Skip to content

Commit

Permalink
Merge pull request #7 from reservoirpy/prebuild_vignette
Browse files Browse the repository at this point in the history
Prebuild vignette
  • Loading branch information
thomasferte authored Mar 13, 2023
2 parents e73ac4a + 19e5a39 commit 7fedba9
Show file tree
Hide file tree
Showing 26 changed files with 1,012 additions and 149 deletions.
2 changes: 1 addition & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
^\.Rproj\.user$
^\.github$
^LICENSE\.md$
^cran-comments\.md$
^cran-comments\.md$
30 changes: 14 additions & 16 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
Package: reservoir
Package: reservoirnet
Type: Package
Title: Simple and flexible code for Reservoir Computing architectures like Echo State Networks
Version: 0.1.2
Date: 2022-05-09
Title: Reservoir Computing and Echo State Networks
Version: 0.2.0
Date: 2023-03-13
Authors@R: c(person("Thomas", "Ferte", role = c("aut", "cre", "trl"), email = "[email protected]"),
person("Kalidou", "Ba", role = c("aut", "trl"), email = "[email protected]"),
person("Nathan", "Trouvain", role = c("aut"), email = "[email protected]"),
person("Rodolphe", "Thiebaut", role = c("aut"), email = "[email protected]"),
person("Xavier", "Hinaut", role = c("aut"), email = "[email protected]"),
person("Boris", "Hejblum", role = c("aut", "trl"), email = "[email protected]"))
Maintainer: <[email protected]>
SystemRequirements: Python (>= 3.7)
Description: ReservoirR is a simple user-friendly library based on Python scientific
modules. It provides a flexible interface to implement efficient Reservoir
Computing (RC) architectures with a particular focus on Echo State Networks (ESN).
Advanced features of ReservoirR allow to improve computation time efficiency on
a simple laptop compared to basic Python implementation, with datasets of any size.
Some of its features are: offline and online training, parallel implementation,
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 with the help of the hyperopt library. Finally, it includes
several tutorials exploring exotic architectures and examples of scientific papers
reproduction.
explore hyperparameters. Finally, it includes several tutorials exploring
time series forecasting, classification and hyperparameter tuning. This package was
developed in the framework of the University of Bordeaux’s IdEx "Investments
for the Future" program / RRI PHDS.
Config/reticulate:
list(
packages = list(
Expand All @@ -32,9 +30,9 @@ Config/reticulate:
)
License: GPL (>= 3)
Repository: CRAN
URL:
URL: https://github.com/reservoirpy
Depends: R (>= 3.6)
RoxygenNote: 7.2.2
RoxygenNote: 7.2.3
Encoding: UTF-8
Imports:
reticulate,
Expand Down
78 changes: 55 additions & 23 deletions R/reservoir.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
#' @param 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.
#' @param 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.
#' @param activation str 'tanh'. Reservoir units activation function. Should be a activationsfunc function name ('tanh', 'identity', 'sigmoid', 'relu', 'softmax', 'softplus').
#'
#' @param seed set random seed
#'
#'@examples
#' if(interactive()){
#' readout <- createNode("Ridge")
Expand All @@ -58,6 +59,7 @@ createNode <- function(nodeType = c("Ridge"),
rc_connectivity = 0.1,
activation = "tanh",
dtype = "float64",
seed = NULL,
...) {

stopifnot(!is.null(nodeType))
Expand All @@ -71,25 +73,54 @@ createNode <- function(nodeType = c("Ridge"),
else if(nodeType=="Reservoir"){
if(!is.null(units))
#units <- noquote(paste0(as.integer(units),'L'))
node <- reservoirpy$nodes$Reservoir(units = as.integer(units),
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation)

if(is.null(seed)){
node <- reservoirpy$nodes$Reservoir(units = as.integer(units),
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation)
} else {
node <- reservoirpy$nodes$Reservoir(units = as.integer(units),
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation,
seed = as.integer(seed))
}
else
node <- reservoirpy$nodes$Reservoir(units = units,
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation)
if(is.null(seed)){
node <- reservoirpy$nodes$Reservoir(units = units,
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation)
} else {
node <- reservoirpy$nodes$Reservoir(units = units,
lr = lr,
sr = sr,
name = name,
input_bias = inputBias,
input_scaling = input_scaling,
rc_connectivity = rc_connectivity,
input_connectivity = input_connectivity,
activation = activation,
seed = as.integer(seed))
}


}
else if(nodeType=="Input"){
node <- reservoirpy$nodes$Input(input_dim = inputDim,
Expand Down Expand Up @@ -311,13 +342,14 @@ generate_data <- function(dataset = c("japanese_vowels","mackey_glass","both"),
#'
#' @examples
#' if(interactive()){
#' source <- reservoir::createNode("Input")
#' reservoir <- reservoir::createNode("Reservoir", units = 500, lr=0.1, sr=0.9)
#' source <- reservoirnet::createNode("Input")
#' reservoir <- reservoirnet::createNode("Reservoir", units = 500, lr=0.1, sr=0.9)
#' source %>>% reservoir
#'
#' readout <- reservoir::createNode("Ridge")
#' readout <- reservoirnet::createNode("Ridge")
#' list(source %>>% reservoir, source) %>>% readout
#' }
`%>>%` <- function(node1, node2){
rp$rshift$operatorRShift(node1, node2)
reservoirnet::link(node1, node2)
# rp$rshift$operatorRShift(node1, node2)
}
4 changes: 2 additions & 2 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
err_reservoirpy <- function(e) {
message("Error importing reservoirpy")
message("Check if reservoirpy is installed")
message("Install by reservoir::install_reservoirpy() and reload library")
message("Install by reservoirnet::install_reservoirpy() and reload library")
}

err_np <- function(e) {
message("Error importing numpy")
message("Check if numpy is installed")
message("Install by reservoir::install_numpy() and reload library")
message("Install by reservoirnet::install_numpy() and reload library")
}

err_rshift <- function(e) {
Expand Down
21 changes: 19 additions & 2 deletions cran-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,24 @@ Environment :
- github action : ubuntu v22.04
- github action : windows server 2022 v10.0
- github action : macos v12.6.3
- check_rhub : Windows Server 2022, R-devel, 64 bit
- check_win_devel : Windows Server 2022 x64 (build 20348)

0 errors | 0 warnings | 0 note
* checking CRAN incoming feasibility ... NOTE
Maintainer: 'Thomas Ferte <[email protected]>'

New submission

Possibly misspelled words in DESCRIPTION:
ESN (16:15)
IdEx (23:75)
PHDS (24:44)
RRI (24:40)
reservoirPy (13:72)

* checking for detritus in the temp directory ... NOTE
Found the following files/directories:
'lastMiKTeXException'

We believe the note is ok. The words are well spelled. The detritus temp directory does not seem to be a problem (https://stackoverflow.com/questions/62456137/r-cran-check-detritus-in-temp-directory).

* This is a new release.
6 changes: 3 additions & 3 deletions man/chevron.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/createNode.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
library(testthat)
library(reservoir)
library(reservoirnet)

test_check("reservoir")
test_check("reservoirnet")
26 changes: 13 additions & 13 deletions tests/testthat/tests.R
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
test_that("reservoir", {
test_that("reservoirnet", {
testthat::skip_on_cran()

print(reticulate::py_config())

timesteps <- 2500
X <- reservoir::generate_data(dataset = "mackey_glass",n_timesteps = timesteps)$mackey_glass
X <- reservoirnet::generate_data(dataset = "mackey_glass",n_timesteps = timesteps)$mackey_glass

X <- 2 * (X - min(X)) / (max(X) - min(X)) - 1
source <- reservoir::createNode("Input")
readout <- reservoir::createNode("Ridge")
reservoir <- reservoir::createNode("Reservoir", units = 100, lr=0.2, sr=0.8)
source <- reservoirnet::createNode("Input")
readout <- reservoirnet::createNode("Ridge")
reservoir <- reservoirnet::createNode("Reservoir", units = 100, lr=0.2, sr=0.8)

model <- reservoir::link(reservoir, readout)
model <- reservoirnet::link(reservoir, readout)

Xtrain <- as.matrix(X[1:2001])
Ytrain <- as.matrix(X[10:2010])

model <- reservoir::reservoirR_fit(model, X=Xtrain, Y=Ytrain)
model <- reservoirnet::reservoirR_fit(model, X=Xtrain, Y=Ytrain)

# Classification
japanese_vowels <- reservoir::generate_data(
japanese_vowels <- reservoirnet::generate_data(
dataset = "japanese_vowels",
repeat_targets=TRUE)$japanese_vowels

source <- reservoir::createNode("Input")
readout <- reservoir::createNode("Ridge",ridge=1e-6)
reservoir <- reservoir::createNode("Reservoir",
source <- reservoirnet::createNode("Input")
readout <- reservoirnet::createNode("Ridge",ridge=1e-6)
reservoir <- reservoirnet::createNode("Reservoir",
units = 500,
lr=0.1, sr=0.9)


# Example: [source >> reservoir, source] >> readout
model <- list(source %>>% reservoir, source) %>>% readout

model_fit <- reservoir::reservoirR_fit(node = model,
model_fit <- reservoirnet::reservoirR_fit(node = model,
X = japanese_vowels$X_train,
Y = japanese_vowels$Y_train,
stateful=FALSE,
warmup = 2)

Y_pred <- reservoir::predict_seq(node = model_fit$fit, X = japanese_vowels$X_test,stateful = FALSE)
Y_pred <- reservoirnet::predict_seq(node = model_fit$fit, X = japanese_vowels$X_test,stateful = FALSE)
# formal test
testthat::expect(class(model)[1] == "reservoirpy.model.Model",
failure_message = "Output of fit function is not a reservoirpy.model.Model object")
Expand Down
Loading

0 comments on commit 7fedba9

Please sign in to comment.