Title: | Reservoir Computing and Echo State Networks |
---|---|
Description: | A simple user-friendly library based on the 'python' module 'reservoirpy'. It provides a flexible interface to implement efficient Reservoir Computing (RC) architectures with a particular focus on Echo State Networks (ESN). Some of its features are: offline and online training, parallel implementation, sparse matrix computation, fast spectral initialization, advanced learning rules (e.g. Intrinsic Plasticity) etc. It also makes possible to easily create complex architectures with multiple reservoirs (e.g. deep reservoirs), readouts, and complex feedback loops. Moreover, graphical tools are included to easily explore hyperparameters. Finally, it includes several tutorials exploring time series forecasting, classification and hyperparameter tuning. For more information about 'reservoirpy', please see Trouvain et al. (2020) <doi:10.1007/978-3-030-61616-8_40>. This package was developed in the framework of the University of Bordeaux’s IdEx "Investments for the Future" program / RRI PHDS. |
Authors: | Thomas Ferte [aut, cre, trl], Kalidou Ba [aut, trl], Nathan Trouvain [aut], Rodolphe Thiebaut [aut], Xavier Hinaut [aut], Boris Hejblum [aut, trl] |
Maintainer: | Thomas Ferte <[email protected]> |
License: | GPL (>= 3) |
Version: | 0.2.0 |
Built: | 2025-01-24 03:42:32 UTC |
Source: | https://github.com/cran/reservoirnet |
>>
A port of the >>
"chevron" operator from reservoirpy.
node1 %>>% node2
node1 %>>% node2
node1 |
a |
node2 |
a |
A node or a list of nodes.
if(interactive()){ source <- reservoirnet::createNode("Input") reservoir <- reservoirnet::createNode("Reservoir", units = 100, lr=0.1, sr=0.9) source %>>% reservoir readout <- reservoirnet::createNode("Ridge") list(source %>>% reservoir, source) %>>% readout }
if(interactive()){ source <- reservoirnet::createNode("Input") reservoir <- reservoirnet::createNode("Reservoir", units = 100, lr=0.1, sr=0.9) source %>>% reservoir readout <- reservoirnet::createNode("Ridge") list(source %>>% reservoir, source) %>>% readout }
Function to create some node
createNode( nodeType = c("Ridge"), units = NULL, lr = 1, sr = NULL, otputDim = NULL, inputDim = NULL, name = NULL, ridge = 0, inputBias = TRUE, input_scaling = TRUE, input_connectivity = 0.1, rc_connectivity = 0.1, activation = "tanh", dtype = "float64", seed = NULL, ... )
createNode( nodeType = c("Ridge"), units = NULL, lr = 1, sr = NULL, otputDim = NULL, inputDim = NULL, name = NULL, ridge = 0, inputBias = TRUE, input_scaling = TRUE, input_connectivity = 0.1, rc_connectivity = 0.1, activation = "tanh", dtype = "float64", seed = NULL, ... )
nodeType |
Type of node. Default is |
units |
(int) optional
Number of reservoir units. If None, the number of units will be infered from
the |
lr |
(float) default to 1.0
Neurons leak rate. Must be in :math: |
sr |
(float) optional Spectral radius of recurrent weight matrix. |
otputDim |
Output dimension of the Node. Dimension of its state. |
inputDim |
Input dimension of the Node. |
name |
Name of the Node. It must be a unique identifier. |
ridge |
float, default to |
inputBias |
bool, default to |
input_scaling |
float or array-like of shapes (features), default to |
input_connectivity |
float, default to 0.1. Connectivity of input neurons, i.e. ratio of input neurons connected to reservoir neurons. Must be between 0 and 1. |
rc_connectivity |
float, default to 0.1. Connectivity of recurrent weight matrix, i.e. ratio of reservoir neurons connected to other reservoir neurons, including themselves. Must be between 0 and 1. |
activation |
str 'tanh'. Reservoir units activation function. Should be a activationsfunc function name ('tanh', 'identity', 'sigmoid', 'relu', 'softmax', 'softplus'). |
dtype |
Numerical type for node parameters |
seed |
set random seed |
... |
Others params |
A node generated by reservoirpy python module.
if(interactive()){ readout <- reservoirnet::createNode("Ridge") }
if(interactive()){ readout <- reservoirnet::createNode("Ridge") }
A dataset containing the data from datagouv.fr concerning covid-19 infections in Aquitaine. Data related to hospitalizations can be found at Santé publique France - Data downloaded at https://www.data.gouv.fr/fr/datasets/r/08c18e08-6780-452d-9b8c-ae244ad529b3, update from 26/01/2023. Data related to RT-PCR can be found at Santé publique France - Data downloaded at https://www.data.gouv.fr/fr/datasets/r/10639654-3864-48ac-b024-d772c218c4c1, update from 26/01/2023.
data(dfCovid)
data(dfCovid)
A data frame with 962 rows and 4 variables
date. The date
hosp. Number of person hospitalized with SARS-CoV-2 in Aquitaine.
Positive. Number of person with a positive RT-PCR in Aquitaine.
Tested. Number of person with a RT-PCR in Aquitaine.
Japanese vowels
or the Mackey-Glass
Mackey-Glass time series [8]_ [9]_
, computed from the Mackey-Glass
delayed differential equation:
generate_data( dataset = c("japanese_vowels", "mackey_glass", "both"), one_hot_encode = TRUE, repeat_targets = FALSE, reload = FALSE, n_timesteps, tau = 17, a = 0.2, b = 0.1, n = 10, x0 = 1.2, h = 1 )
generate_data( dataset = c("japanese_vowels", "mackey_glass", "both"), one_hot_encode = TRUE, repeat_targets = FALSE, reload = FALSE, n_timesteps, tau = 17, a = 0.2, b = 0.1, n = 10, x0 = 1.2, h = 1 )
dataset |
(String) take value in array |
one_hot_encode |
(bool), default to True. If True, returns class label as a one-hot encoded vector. |
repeat_targets |
(bool), default to False. If True, repeat the target label or vector along the time axis of the corresponding sample. |
reload |
(bool), default to False If True, re-download data from remote repository. Else, if a cached version of the dataset exists, use the cached dataset. |
n_timesteps |
(int) Number of time steps to compute. |
tau |
(int), default to 17 Time delay :math:'\tau' of Mackey-Glass equation. By defaults, equals to 17. Other values can change the choatic behaviour of the timeseries. |
a |
(float) default to 0.2 :math:'a' parameter of the equation. |
b |
(float) default to 0.1 :math:'b' parameter of the equation. |
n |
(int) default to 10 :math:'n' parameter of the equation. |
x0 |
(float), optional, default to 1.2 Initial condition of the timeseries. |
h |
(float), default to 1.0 Time delta between two discrete timesteps. |
array of shape (n_timesteps, 1) Mackey-Glass timeseries.
if(interactive()){ japanese_vowels <- generate_data(dataset="japanese_vowels") timeSerie <- generate_data(dataset = "mackey_glass",n_timesteps = 2500) res =generate_data(dataset <- "both",n_timesteps = 2500) }
if(interactive()){ japanese_vowels <- generate_data(dataset="japanese_vowels") timeSerie <- generate_data(dataset = "mackey_glass",n_timesteps = 2500) res =generate_data(dataset <- "both",n_timesteps = 2500) }
Install reservoirpy
install_reservoirpy(envname = "r-reticulate", method = "auto")
install_reservoirpy(envname = "r-reticulate", method = "auto")
envname |
|
method |
|
A NULL object after installing reservoirpy python module.
## Not run: reservoirnet::install_reservoirpy() ## End(Not run)
## Not run: reservoirnet::install_reservoirpy() ## End(Not run)
~.Node
instances to form a :py:class:~.Model
instance. node1
output will be used as input for node2
in the
created model. This is similar to a function composition operation:Link two :py:class:~.Node
instances to form a :py:class:~.Model
instance. node1
output will be used as input for node2
in the
created model. This is similar to a function composition operation:
link(node1, node2, name = NULL)
link(node1, node2, name = NULL)
node1 |
(Node) or (list_of_Node) Nodes or lists of nodes to link. |
node2 |
(Node) or (list_of_Node) Nodes or lists of nodes to link. |
name |
(str) optional Name for the chaining Model. |
Can update the state of the node several times
A reservoir model linking node1 and node2.
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) readout <- reservoirnet::createNode(nodeType = "Ridge", ridge = 0.1) model <- reservoirnet::link(reservoir, readout) }
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) readout <- reservoirnet::createNode(nodeType = "Ridge", ridge = 0.1) model <- reservoirnet::link(reservoir, readout) }
Plot 2x2 combinations of the hyperparameters.
plot_2x2_perf( dfPerf, perf_lab = "Median relative error", legend_position = "bottom", trans = "log10" )
plot_2x2_perf( dfPerf, perf_lab = "Median relative error", legend_position = "bottom", trans = "log10" )
dfPerf |
The performance dataframe which should have the columns : perf, ridge, input_scaling, leaking_rate, spectral_radius. Where perf is the performance metric |
perf_lab |
The label of the performance metric. |
legend_position |
Position of legend passed to ggarrange |
trans |
The transformation (default is "log10") |
A mutliple 2x2 plots.
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_2x2_perf(dfPerf = dfPerf)
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_2x2_perf(dfPerf = dfPerf)
get marginal performance from dfPerf
plot_marginal_perf(dfPerf, color_cut = 10, perf_lab = "Median relative error")
plot_marginal_perf(dfPerf, color_cut = 10, perf_lab = "Median relative error")
dfPerf |
The performance dataframe which should have the columns : perf, ridge, input_scaling, leaking_rate, spectral_radius. Where perf is the performance metric |
color_cut |
The cutting point to highlight best values (default = 10) |
perf_lab |
The label of the performance metric. |
A plot with 4 facets
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_marginal_perf(dfPerf = dfPerf, color_cut = 2)
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_marginal_perf(dfPerf = dfPerf, color_cut = 2)
Unit plot for 2x2 function
plot_perf_22(x, y, dfPerf, perf_lab, trans = "log10")
plot_perf_22(x, y, dfPerf, perf_lab, trans = "log10")
x |
The x feature |
y |
The y feature |
dfPerf |
The performance dataframe which should have the columns : perf, ridge, input_scaling, leaking_rate, spectral_radius. Where perf is the performance metric |
perf_lab |
The label of the performance metric. |
trans |
The transformation (default is "log10") |
A 2x2 plot
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_perf_22( dfPerf = dfPerf, x = "ridge", y = "input_scaling", perf_lab = "MSE" )
dfPerf <- data.frame( perf = runif(n = 10), ridge = runif(n = 10), input_scaling = runif(n = 10), leaking_rate = runif(n = 10) ) reservoirnet::plot_perf_22( dfPerf = dfPerf, x = "ridge", y = "input_scaling", perf_lab = "MSE" )
plot.reservoir_predict_seq
## S3 method for class 'reservoir_predict_seq' plot(x, ..., vec_nodes = c(1:20), vec_time = NULL)
## S3 method for class 'reservoir_predict_seq' plot(x, ..., vec_nodes = c(1:20), vec_time = NULL)
x |
A reservoir_predict_seq object |
... |
deprecated |
vec_nodes |
Number of nodes to plot |
vec_time |
Time to plot |
A ggplot
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
Run the node-forward function on a sequence of data
predict_seq(node, X, formState = NULL, stateful = TRUE, reset = FALSE)
predict_seq(node, X, formState = NULL, stateful = TRUE, reset = FALSE)
node |
node |
X |
array-like of shape |
formState |
array of shape |
stateful |
|
reset |
|
Can update the state of the node several times
An object of class reservoir_predict_seq. This object is a numeric vector containing the matrix of the prediction of the reservoir. It is either the forecast of the ridge layer or the node state of the reservoir if no ridge layer is given.
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
print S3 method for summary.reservoirR_fit object
## S3 method for class 'summary.reservoirR_fit' print(x, ...)
## S3 method for class 'summary.reservoirR_fit' print(x, ...)
x |
an object of class |
... |
further arguments. |
A NULL object which shows the model setting to perform the reservoir fit.
if(reticulate::py_module_available("reservoirpy")){ }
if(reticulate::py_module_available("reservoirpy")){ }
Generate a hyperparameter simulation table using functions as input.
random_search_hyperparam( n = 100, ls_fct = list(ridge = function(n) 1e-05, input_scaling = function(n) 1, spectral_radius = function(n) rloguniform(n = n, min = 0.01, max = 10), leaking_rate = function(n) rloguniform(n = n, min = 0.001, max = 1)) )
random_search_hyperparam( n = 100, ls_fct = list(ridge = function(n) 1e-05, input_scaling = function(n) 1, spectral_radius = function(n) rloguniform(n = n, min = 0.01, max = 10), leaking_rate = function(n) rloguniform(n = n, min = 0.001, max = 1)) )
n |
Number of search |
ls_fct |
A list of functions |
A dataframe of size n x 4. Each row is a different set of hyperparameters.
random_search_hyperparam( n = 100, ls_fct = list( ridge = function(n) 1e-5, input_scaling = function(n) 1, spectral_radius = function(n) rloguniform(n = n, min = 1e-2, max = 10), leaking_rate = function(n) rloguniform(n = n, min = 1e-3, max = 1) ) )
random_search_hyperparam( n = 100, ls_fct = list( ridge = function(n) 1e-5, input_scaling = function(n) 1, spectral_radius = function(n) rloguniform(n = n, min = 1e-2, max = 10), leaking_rate = function(n) rloguniform(n = n, min = 1e-3, max = 1) ) )
Offline fitting method of a Node
reservoirR_fit(node, X, Y, warmup = 0, stateful = FALSE, reset = FALSE)
reservoirR_fit(node, X, Y, warmup = 0, stateful = FALSE, reset = FALSE)
node |
node |
X |
|
Y |
array-like of shape |
warmup |
: |
stateful |
is boolen |
reset |
is boolean. Should the node status be reset before fitting. |
A fitted reservoir of class reservoiR_fit containing the fitted model.
if(reticulate::py_module_available("reservoirpy")){ }
if(reticulate::py_module_available("reservoirpy")){ }
Simulate a log-uniform distribution
rloguniform(n, min = 10^-1, max = 10^2)
rloguniform(n, min = 10^-1, max = 10^2)
n |
number of sample |
min |
minimum of the distribution |
max |
maximum of the distribution |
A vector of simulated values
rloguniform(n = 1)
rloguniform(n = 1)
summary.reservoir_predict_seq
## S3 method for class 'reservoir_predict_seq' summary(object, ...)
## S3 method for class 'reservoir_predict_seq' summary(object, ...)
object |
A reservoir_predict_seq object |
... |
Additional argument (unused) |
A dataframe with node activation
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
if(reticulate::py_module_available("reservoirpy")){ reservoir <- reservoirnet::createNode(nodeType = "Reservoir", seed = 1, units = 100, lr = 0.7, sr = 1, input_scaling = 1) X <- matrix(data = rnorm(100), ncol = 4) reservoir_state_stand <- reservoirnet::predict_seq(node = reservoir, X = X) plot(reservoir_state_stand) summary(reservoir_state_stand) }
summary S3 method for reservoirR_fit object
## S3 method for class 'reservoirR_fit' summary(object, ...)
## S3 method for class 'reservoirR_fit' summary(object, ...)
object |
an object of class |
... |
further arguments. |
a list
object
if(reticulate::py_module_available("reservoirpy")){ }
if(reticulate::py_module_available("reservoirpy")){ }