garcianacho commited on
Commit
e2e6894
·
1 Parent(s): 70e66a8

Upload app.R

Browse files
Files changed (1) hide show
  1. app.R +1326 -43
app.R CHANGED
@@ -1,51 +1,1334 @@
 
 
 
 
 
1
  library(shiny)
2
- library(bslib)
3
- library(dplyr)
4
  library(ggplot2)
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- df <- readr::read_csv("penguins.csv")
7
- # Find subset of columns that are suitable for scatter plot
8
- df_num <- df |> select(where(is.numeric), -Year)
9
-
10
- ui <- page_fillable(theme = bs_theme(bootswatch = "minty"),
11
- layout_sidebar(fillable = TRUE,
12
- sidebar(
13
- varSelectInput("xvar", "X variable", df_num, selected = "Bill Length (mm)"),
14
- varSelectInput("yvar", "Y variable", df_num, selected = "Bill Depth (mm)"),
15
- checkboxGroupInput("species", "Filter by species",
16
- choices = unique(df$Species), selected = unique(df$Species)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  ),
18
- hr(), # Add a horizontal rule
19
- checkboxInput("by_species", "Show species", TRUE),
20
- checkboxInput("show_margins", "Show marginal plots", TRUE),
21
- checkboxInput("smooth", "Add smoother"),
22
- ),
23
- plotOutput("scatter")
24
- )
25
- )
26
-
27
- server <- function(input, output, session) {
28
- subsetted <- reactive({
29
- req(input$species)
30
- df |> filter(Species %in% input$species)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  })
32
 
33
- output$scatter <- renderPlot({
34
- p <- ggplot(subsetted(), aes(!!input$xvar, !!input$yvar)) + list(
35
- theme(legend.position = "bottom"),
36
- if (input$by_species) aes(color=Species),
37
- geom_point(),
38
- if (input$smooth) geom_smooth()
39
- )
40
-
41
- if (input$show_margins) {
42
- margin_type <- if (input$by_species) "density" else "histogram"
43
- p <- p |> ggExtra::ggMarginal(type = margin_type, margins = "both",
44
- size = 8, groupColour = input$by_species, groupFill = input$by_species)
45
- }
46
-
47
- p
48
- }, res = 100)
49
  }
50
 
51
- shinyApp(ui, server)
 
 
 
1
+ #Implementation of a RNN for forex analysis
2
+ #Nacho Garcia 2018
3
+ #Based on the rnn library (https://github.com/bquast/rnn)
4
+
5
+
6
  library(shiny)
 
 
7
  library(ggplot2)
8
+ library(httr)
9
+ library(sigmoid)
10
+
11
+ css <- HTML("
12
+ .row .nudge-right {
13
+ padding-right:0;
14
+ }
15
+
16
+ .row .nudge-left {
17
+ padding-left:0;
18
+ }
19
+ ")
20
 
21
+
22
+
23
+ # Define UI for application that draws a histogram
24
+ ui <- fluidPage(
25
+
26
+ # Application title
27
+ titlePanel("AI Predicting Currency Exchange Rate"),
28
+
29
+ # 1. Open AUD/USD
30
+ # 5. Open EUR/USD
31
+ # 9. Open GBP/USD
32
+ # 13.Open NZD/USD
33
+ # 17.Open USD/CAD
34
+ # 21.Open USD/CHF
35
+ # 24.Open USD/JPY
36
+
37
+ # Sidebars
38
+ sidebarLayout(
39
+ sidebarPanel(
40
+ width = 3,
41
+ selectInput("predX", "Pair to predict:",
42
+ choices = c("AUD/USD" = 1,
43
+ "EUR/USD" = 5,
44
+ "GBP/USD" = 9,
45
+ "NZD/USD"=13,
46
+ "USD/CAD"=17,
47
+ "USD/CHF"=21,
48
+ "USD/JPY"=24), selected = 1),
49
+
50
+ sliderInput("epoch", "Iterations:", 100,5000,1000),
51
+ sliderInput("L", "Events Used for Training:", 500,3000,2000),
52
+ sliderInput("nn", "Neurons in the RNN:", 4,128,12),
53
+ sliderInput("lr", "Learning Rate:", 0.00001,0.01,0.0001),
54
+ h6(""),
55
+ actionButton("do", "Predict", align = "center"),
56
+ h6("By G2C", align = "left")
57
  ),
58
+
59
+ # Show a plot of the generated distribution
60
+ mainPanel(tabsetPanel(id='conditioned',
61
+ tabPanel("Info", htmlOutput("help")),
62
+ tabPanel("Plots", plotOutput("Plot"), plotOutput("Plot2") ),
63
+ tabPanel("Values", tableOutput("summary"))
64
+
65
+
66
+
67
+ ))
68
+
69
+
70
+
71
+
72
+ )
73
+ )
74
+
75
+
76
+ # Define server logic required to draw a histogram
77
+ server <- function(input, output) {
78
+
79
+
80
+
81
+
82
+ observeEvent(input$do, {
83
+
84
+ Pred<-as.numeric(input$predX)
85
+ epochD<-input$epoch
86
+ L<-input$L
87
+ lr<-input$lr
88
+ nn<-input$nn
89
+
90
+ GAP<-1
91
+
92
+
93
+ #Pred<-5
94
+ # epochD<-300
95
+ # L<-3000
96
+ # lr<-0.0001
97
+ # nn<-12
98
+ #
99
+
100
+
101
+
102
+ withProgress(message = 'Predicting', value = 0, {
103
+ incProgress(1, detail = paste("Loading Pairs"))
104
+
105
+
106
+
107
+ response <- GET(url="https://www.dropbox.com/s/v3ztdtxcbpdx9mn/dfBrute.RData?dl=1")
108
+ load(rawConnection(response$content))
109
+ rm(response)
110
+
111
+ Values<-dfBrute[[Pred]]
112
+
113
+ for (h in 1:length(dfBrute)) {
114
+ dfBrute[[h]]$Open<-(dfBrute[[h]]$Open-min(dfBrute[[h]]$Open)) / (max(dfBrute[[h]]$Open)-min(dfBrute[[h]]$Open))
115
+ dfBrute[[h]]$High<-(dfBrute[[h]]$High-min(dfBrute[[h]]$High)) / (max(dfBrute[[h]]$High)-min(dfBrute[[h]]$High))
116
+ dfBrute[[h]]$Low<-(dfBrute[[h]]$Low-min(dfBrute[[h]]$Low)) / (max(dfBrute[[h]]$Low)-min(dfBrute[[h]]$Low))
117
+ dfBrute[[h]]$Volume<-(dfBrute[[h]]$Volume-min(dfBrute[[h]]$Volume)) / (max(dfBrute[[h]]$Volume)-min(dfBrute[[h]]$Volume))
118
+ }
119
+
120
+
121
+
122
+ df<-array(data = NA, dim = c(1,nrow(dfBrute[[1]]),28))
123
+ dummy<-0
124
+ for (i in 1:length(dfBrute)) {
125
+
126
+ df[1,,i+dummy]<-dfBrute[[i]]$Open
127
+ df[1,,i+1+dummy]<-dfBrute[[i]]$High
128
+ df[1,,i+2+dummy]<-dfBrute[[i]]$Low
129
+ df[1,,i+3+dummy]<-dfBrute[[i]]$Volume
130
+ dummy<-dummy+3
131
+
132
+ }
133
+
134
+ })
135
+
136
+
137
+ #Training data
138
+ Xt <- df[,1:L,]
139
+ X.train <- array(Xt,dim=c(1,L,28))
140
+
141
+ Yt <- df[,1:L+GAP,Pred]
142
+ y.train <- matrix(Yt, ncol=L)
143
+
144
+ ####RNN functions from rnn library
145
+
146
+ init_r = function(model){
147
+ if(model$network_type == "rnn"){
148
+ init_rnn(model)
149
+ } else if (model$network_type == "lstm"){
150
+ init_lstm(model)
151
+ }else if (model$network_type == "gru"){
152
+ init_gru(model)
153
+ }
154
+ }
155
+
156
+ #' @name init_rnn
157
+ #' @title init_rnn
158
+ #' @description Initialize the weight parameter for a rnn
159
+ #' @param model the output model object
160
+ #' @return the updated model
161
+
162
+ init_rnn = function(model){
163
+
164
+ # Storing layers states, filled with 0 for the moment
165
+ model$store <- list()
166
+ for(i in seq(length(model$synapse_dim) - 1)){
167
+ model$store[[i]] <- array(0,dim = c(dim(model$last_layer_error)[1:2],model$synapse_dim[i+1]))
168
+ }
169
+
170
+ model$time_synapse = list()
171
+ model$recurrent_synapse = list()
172
+ model$bias_synapse = list()
173
+
174
+ #initialize neural network weights, stored in several lists
175
+ for(i in seq(length(model$synapse_dim) - 1)){
176
+ model$time_synapse[[i]] <- matrix(runif(n = model$synapse_dim[i]*model$synapse_dim[i+1], min=-1, max=1), nrow=model$synapse_dim[i])
177
+ }
178
+ for(i in seq(length(model$hidden_dim))){
179
+ model$recurrent_synapse[[i]] <- matrix(runif(n = model$hidden_dim[i]*model$hidden_dim[i], min=-1, max=1), nrow=model$hidden_dim[i])
180
+ }
181
+ for(i in seq(length(model$synapse_dim) - 1)){
182
+ model$bias_synapse[[i]] <- runif(model$synapse_dim[i+1],min=-0.1,max=0.1)
183
+ }
184
+
185
+ # add the update to the model list
186
+ model$time_synapse_update = lapply(model$time_synapse,function(x){x*0})
187
+ model$bias_synapse_update = lapply(model$bias_synapse,function(x){x*0})
188
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse,function(x){x*0})
189
+
190
+ return(model)
191
+ }
192
+
193
+ #' @name init_lstm
194
+ #' @title init_lstm
195
+ #' @description Initialize the weight parameter for a lstm
196
+ #' @param model the output model object
197
+ #' @return the updated model
198
+
199
+ init_lstm = function(model){
200
+ # if(length(model$hidden_dim) != 1){stop("only one layer LSTM supported yet")}
201
+
202
+ # Storing layers states, filled with 0 for the moment
203
+ model$store <- list()
204
+ model$time_synapse = list()
205
+ model$recurrent_synapse = list()
206
+ model$bias_synapse = list()
207
+ for(i in seq(length(model$hidden_dim))){
208
+ # hidden output / cells / forget / input / gate / output
209
+ model$store[[i]] = array(0,dim = c(dim(model$last_layer_error)[1:2],model$hidden_dim[1],6)) # 4D arrays !!! with dim()[4] = 6
210
+ model$time_synapse[[i]] = array(runif(n = model$synapse_dim[i] * model$synapse_dim[i+1] * 4, min=-1, max=1),dim = c(model$synapse_dim[i], model$synapse_dim[i+1], 4))# 3D arrays with dim()[3] = 4
211
+ model$recurrent_synapse[[i]] = array(runif(n = model$synapse_dim[i+1] * model$synapse_dim[i+1] * 4, min=-1, max=1),dim = c(model$synapse_dim[i+1], model$synapse_dim[i+1], 4))# 3D arrays with dim()[3] = 4
212
+ model$bias_synapse[[i]] = array(runif(n = model$synapse_dim[i+1] * 4, min=-1, max=1),dim = c(model$synapse_dim[i+1], 4))#2D arrays with dim()[2] = 4
213
+ }
214
+
215
+ model$store[[length(model$store) + 1]] = array(0,dim = c(dim(model$last_layer_error)[1:2],model$output_dim)) # final output layer
216
+ model$time_synapse[[length(model$time_synapse) + 1]] = array(runif(n = model$hidden_dim[length(model$hidden_dim)] * model$output_dim, min=-1, max=1),dim = c(model$hidden_dim[length(model$hidden_dim)], model$output_dim)) # 4D arrays !!!
217
+ model$bias_synapse[[length(model$bias_synapse) + 1]] = runif(model$output_dim,min=-0.1,max=0.1)
218
+
219
+ # add the update to the model list
220
+ model$time_synapse_update = lapply(model$time_synapse,function(x){x*0})
221
+ model$bias_synapse_update = lapply(model$bias_synapse,function(x){x*0})
222
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse,function(x){x*0})
223
+
224
+ return(model)
225
+ }
226
+
227
+ #' @name init_gru
228
+ #' @title init_gru
229
+ #' @description Initialize the weight parameter for a gru
230
+ #' @param model the output model object
231
+ #' @return the updated model
232
+
233
+ init_gru = function(model){
234
+
235
+ # Storing layers states, filled with 0 for the moment
236
+ model$store <- list()
237
+ model$time_synapse = list()
238
+ model$recurrent_synapse = list()
239
+ model$bias_synapse = list()
240
+ for(i in seq(length(model$hidden_dim))){
241
+ # hidden output / z / r / h
242
+ model$store[[i]] = array(0,dim = c(dim(model$last_layer_error)[1:2],model$hidden_dim[1],4)) # 4D arrays !!! with dim()[4] = 4
243
+ model$time_synapse[[i]] = array(runif(n = model$synapse_dim[i] * model$synapse_dim[i+1] * 3, min=-1, max=1),dim = c(model$synapse_dim[i], model$synapse_dim[i+1], 3))# 3D arrays with dim()[3] = 3
244
+ model$recurrent_synapse[[i]] = array(runif(n = model$synapse_dim[i+1] * model$synapse_dim[i+1] * 3, min=-1, max=1),dim = c(model$synapse_dim[i+1], model$synapse_dim[i+1], 3))# 3D arrays with dim()[3] = 3
245
+ model$bias_synapse[[i]] = array(runif(n = model$synapse_dim[i+1] * 3, min=-1, max=1),dim = c(model$synapse_dim[i+1], 3))#2D arrays with dim()[2] = 3
246
+ }
247
+
248
+ model$store[[length(model$store) + 1]] = array(0,dim = c(dim(model$last_layer_error)[1:2],model$output_dim)) # final output layer
249
+ model$time_synapse[[length(model$time_synapse) + 1]] = array(runif(n = model$hidden_dim[length(model$hidden_dim)] * model$output_dim, min=-1, max=1),dim = c(model$hidden_dim[length(model$hidden_dim)], model$output_dim)) # 4D arrays !!!
250
+ model$bias_synapse[[length(model$bias_synapse) + 1]] = runif(model$output_dim,min=-0.1,max=0.1)
251
+
252
+ # add the update to the model list
253
+ model$time_synapse_update = lapply(model$time_synapse,function(x){x*0})
254
+ model$bias_synapse_update = lapply(model$bias_synapse,function(x){x*0})
255
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse,function(x){x*0})
256
+
257
+ return(model)
258
+ }
259
+
260
+ #' @name backprop_r
261
+ #' @title backprop_r
262
+ #' @description backpropagate the error in a model object
263
+ #' @param model the output model object
264
+ #' @param a the input of this learning batch
265
+ #' @param c the output of this learning batch
266
+ #' @param j the indexes of the sample in the current batch
267
+ #' @param ... argument to be passed to method
268
+ #' @return the updated model
269
+
270
+ backprop_r = function(model,a,c,j,...){
271
+ if(model$network_type == "rnn"){
272
+ backprop_rnn(model,a,c,j,...)
273
+ } else if (model$network_type == "lstm"){
274
+ backprop_lstm(model,a,c,j,...)
275
+ } else if (model$network_type == "gru"){
276
+ backprop_gru(model,a,c,j,...)
277
+ }else{
278
+ stop("network_type_unknown for the backprop")
279
+ }
280
+ }
281
+
282
+ #' @name backprop_rnn
283
+ #' @title backprop_rnn
284
+ #' @description backpropagate the error in a model object of type rnn
285
+ #' @param model the output model object
286
+ #' @param a the input of this learning batch
287
+ #' @param c the output of this learning batch
288
+ #' @param j the indexes of the sample in the current batch
289
+ #' @param ... argument to be passed to method
290
+ #' @return the updated model
291
+
292
+ backprop_rnn = function(model,a,c,j,...){
293
+
294
+ # store errors
295
+ model$last_layer_error[j,,] = c - model$store[[length(model$store)]][j,,,drop=F]
296
+ model$last_layer_delta[j,,] = model$last_layer_error[j,,,drop = F] * sigmoid_output_to_derivative(model$store[[length(model$store)]][j,,,drop=F])
297
+
298
+ if(model$seq_to_seq_unsync){
299
+ model$last_layer_error[j,1:(model$time_dim_input - 1),] = 0
300
+ model$last_layer_delta[j,1:(model$time_dim_input - 1),] = 0
301
+ }
302
+
303
+
304
+ model$error[j,model$current_epoch] <- apply(model$last_layer_error[j,,,drop=F],1,function(x){sum(abs(x))})
305
+
306
+ # init futur layer delta, here because there is no layer delta at time_dim+1
307
+ future_layer_delta = list()
308
+ for(i in seq(length(model$hidden_dim))){
309
+ future_layer_delta[[i]] <- matrix(0,nrow=length(j), ncol = model$hidden_dim[i])
310
+ }
311
+
312
+ # Weight iteration,
313
+ for (position in model$time_dim:1) {
314
+
315
+ # input states
316
+ x = array(a[,position,],dim=c(length(j),model$input_dim))
317
+ # error at output layer
318
+ layer_up_delta = array(model$last_layer_delta[j,position,],dim=c(length(j),model$output_dim))
319
+
320
+ for(i in (length(model$store)):1){
321
+ if(i != 1){ # need update for time and recurrent synapse
322
+ layer_current = array(model$store[[i-1]][j,position,],dim=c(length(j),model$hidden_dim[i-1]))
323
+ if(position != 1){
324
+ prev_layer_current = array(model$store[[i-1]][j,position - 1,],dim=c(length(j),model$hidden_dim[i-1]))
325
+ }else{
326
+ prev_layer_current = array(0,dim=c(length(j),model$hidden_dim[i-1]))
327
+ }
328
+ # error at hidden layers
329
+ layer_current_delta = (future_layer_delta[[i-1]] %*% t(model$recurrent_synapse[[i-1]]) + layer_up_delta %*% t(model$time_synapse[[i]])) *
330
+ sigmoid_output_to_derivative(layer_current)
331
+ model$time_synapse_update[[i]] = model$time_synapse_update[[i]] + t(layer_current) %*% layer_up_delta
332
+ model$bias_synapse_update[[i]] = model$bias_synapse_update[[i]] + colMeans(layer_up_delta)
333
+ model$recurrent_synapse_update[[i-1]] = model$recurrent_synapse_update[[i-1]] + t(prev_layer_current) %*% layer_current_delta
334
+ layer_up_delta = layer_current_delta
335
+ future_layer_delta[[i-1]] = layer_current_delta
336
+ }else{ # need only update for time synapse
337
+ model$time_synapse_update[[i]] = model$time_synapse_update[[i]] + t(x) %*% layer_up_delta
338
+ }
339
+ }
340
+ } # end position back prop loop
341
+ return(model)
342
+ }
343
+
344
+ #' @name backprop_lstm
345
+ #' @title backprop_lstm
346
+ #' @description backpropagate the error in a model object of type rlstm
347
+ #' @importFrom sigmoid tanh_output_to_derivative
348
+ #' @param model the output model object
349
+ #' @param a the input of this learning batch
350
+ #' @param c the output of this learning batch
351
+ #' @param j the indexes of the sample in the current batch
352
+ #' @param ... argument to be passed to method
353
+ #' @return the updated model
354
+
355
+ backprop_lstm = function(model,a,c,j,...){
356
+
357
+ # store errors
358
+ model$last_layer_error[j,,] = c - model$store[[length(model$store)]][j,,,drop=F]
359
+ model$last_layer_delta[j,,] = model$last_layer_error[j,,,drop = F] * sigmoid_output_to_derivative(model$store[[length(model$store)]][j,,,drop=F])
360
+
361
+ if(model$seq_to_seq_unsync){
362
+ model$last_layer_error[j,1:(model$time_dim_input - 1),] = 0
363
+ model$last_layer_delta[j,1:(model$time_dim_input - 1),] = 0
364
+ }
365
+ model$error[j,model$current_epoch] <- apply(model$last_layer_error[j,,,drop=F],1,function(x){sum(abs(x))})
366
+
367
+ future_layer_cell_delta = list()
368
+ future_layer_hidden_delta = list()
369
+ for(i in seq(length(model$hidden_dim))){
370
+ future_layer_cell_delta[[i]] = matrix(0, nrow = length(j), ncol = model$hidden_dim[i]) # 4 to actualize
371
+ future_layer_hidden_delta[[i]] = matrix(0, nrow = length(j), ncol = model$hidden_dim[i]) # 2, to actualize
372
+ }
373
+
374
+
375
+ for (position in model$time_dim:1) {
376
+ # error at output layer
377
+ layer_up_delta = array(model$last_layer_delta[j,position,],dim=c(length(j),model$output_dim))
378
+
379
+ # first the last layer to update the layer_up_delta
380
+ i = length(model$hidden_dim)
381
+ layer_hidden = array(model$store[[i]][j,position,,1],dim=c(length(j),model$hidden_dim[i]))
382
+ # output layer update
383
+ model$time_synapse_update[[i+1]] = model$time_synapse_update[[i+1]] + (t(layer_hidden) %*% layer_up_delta)
384
+ model$bias_synapse_update[[i+1]] = model$bias_synapse_update[[i+1]] + colMeans(layer_up_delta)
385
+ # lstm hidden delta
386
+ layer_up_delta = (layer_up_delta %*% t(model$time_synapse_update[[i+1]])) * sigmoid_output_to_derivative(layer_hidden) + future_layer_hidden_delta[[i]] # 1 and 3
387
+
388
+ for(i in length(model$hidden_dim):1){
389
+ # x: input of the layer
390
+ if(i == 1){
391
+ x = array(a[,position,],dim=c(length(j),model$input_dim))
392
+ }else{
393
+ x = array(model$store[[i - 1]][j,position,,1],dim=c(length(j),model$synapse_dim[i]))
394
+ }
395
+ layer_hidden = array(model$store[[i]][j,position,,1],dim=c(length(j),model$hidden_dim[i]))
396
+ layer_cell = array(model$store[[i]][j,position,,2],dim=c(length(j), model$hidden_dim[i]))
397
+ if(position != 1){
398
+ prev_layer_hidden =array(model$store[[i]][j,position-1,,1],dim=c(length(j),model$hidden_dim[i]))
399
+ preview_layer_cell = array(model$store[[i]][j,position-1,,2],dim=c(length(j), model$hidden_dim[i]))
400
+ }else{
401
+ prev_layer_hidden =array(0,dim=c(length(j),model$hidden_dim[i]))
402
+ preview_layer_cell = array(0,dim=c(length(j), model$hidden_dim[i]))
403
+ }
404
+
405
+ layer_f = array(model$store[[i]][j,position,,3],dim=c(length(j), model$hidden_dim[i]))
406
+ layer_i = array(model$store[[i]][j,position,,4],dim=c(length(j), model$hidden_dim[i]))
407
+ layer_c = array(model$store[[i]][j,position,,5],dim=c(length(j), model$hidden_dim[i]))
408
+ layer_o = array(model$store[[i]][j,position,,6],dim=c(length(j), model$hidden_dim[i]))
409
+
410
+ # lstm cell delta
411
+ # layer_cell_delta = (layer_hidden_delta * layer_o) + future_layer_cell_delta # 5 then 8 (skip 7 as no tanh)
412
+ # layer_o_delta_post_activation = layer_hidden_delta * layer_cell # 6 (skip 7 as no tanh)
413
+ layer_cell_delta = (layer_up_delta * layer_o)* tanh_output_to_derivative(layer_cell) + future_layer_cell_delta[[i]] # 5, 7 then 8
414
+ layer_o_delta_post_activation = layer_up_delta * tanh(layer_cell) # 6
415
+
416
+ layer_c_delta_post_activation = layer_cell_delta * layer_i # 9
417
+ layer_i_delta_post_activation = layer_cell_delta * layer_c # 10
418
+
419
+ layer_f_delta_post_activation = layer_cell_delta * preview_layer_cell # 12
420
+ future_layer_cell_delta[[i]] = layer_cell_delta * layer_f # 11
421
+
422
+ layer_o_delta_pre_activation = layer_o_delta_post_activation * sigmoid_output_to_derivative(layer_o) # 13
423
+ layer_c_delta_pre_activation = layer_c_delta_post_activation * tanh_output_to_derivative(layer_c) # 14
424
+ layer_i_delta_pre_activation = layer_i_delta_post_activation * sigmoid_output_to_derivative(layer_i) # 15
425
+ layer_f_delta_pre_activation = layer_f_delta_post_activation * sigmoid_output_to_derivative(layer_f) # 16
426
+ #
427
+
428
+
429
+ # let's update all our weights so we can try again
430
+ model$recurrent_synapse_update[[i]][,,1] = model$recurrent_synapse_update[[i]][,,1] + t(prev_layer_hidden) %*% layer_f_delta_post_activation
431
+ model$recurrent_synapse_update[[i]][,,2] = model$recurrent_synapse_update[[i]][,,2] + t(prev_layer_hidden) %*% layer_i_delta_post_activation
432
+ model$recurrent_synapse_update[[i]][,,3] = model$recurrent_synapse_update[[i]][,,3] + t(prev_layer_hidden) %*% layer_c_delta_post_activation
433
+ model$recurrent_synapse_update[[i]][,,4] = model$recurrent_synapse_update[[i]][,,4] + t(prev_layer_hidden) %*% layer_o_delta_post_activation
434
+ model$time_synapse_update[[i]][,,1] = model$time_synapse_update[[i]][,,1] + t(x) %*% layer_f_delta_post_activation
435
+ model$time_synapse_update[[i]][,,2] = model$time_synapse_update[[i]][,,2] + t(x) %*% layer_i_delta_post_activation
436
+ model$time_synapse_update[[i]][,,3] = model$time_synapse_update[[i]][,,3] + t(x) %*% layer_c_delta_post_activation
437
+ model$time_synapse_update[[i]][,,4] = model$time_synapse_update[[i]][,,4] + t(x) %*% layer_o_delta_post_activation
438
+ model$bias_synapse_update[[i]][,1] = model$bias_synapse_update[[i]][,1] + colMeans(layer_f_delta_post_activation)
439
+ model$bias_synapse_update[[i]][,2] = model$bias_synapse_update[[i]][,2] + colMeans(layer_i_delta_post_activation)
440
+ model$bias_synapse_update[[i]][,3] = model$bias_synapse_update[[i]][,3] + colMeans(layer_c_delta_post_activation)
441
+ model$bias_synapse_update[[i]][,4] = model$bias_synapse_update[[i]][,4] + colMeans(layer_o_delta_post_activation)
442
+
443
+ layer_f_delta_pre_weight = layer_f_delta_pre_activation %*% t(array(model$recurrent_synapse[[i]][,,1],dim=c(dim(model$recurrent_synapse[[i]])[1:2]))) # 20
444
+ layer_i_delta_pre_weight = layer_i_delta_pre_activation %*% t(array(model$recurrent_synapse[[i]][,,2],dim=c(dim(model$recurrent_synapse[[i]])[1:2]))) # 19
445
+ layer_c_delta_pre_weight = layer_c_delta_pre_activation %*% t(array(model$recurrent_synapse[[i]][,,3],dim=c(dim(model$recurrent_synapse[[i]])[1:2]))) # 18
446
+ layer_o_delta_pre_weight = layer_o_delta_pre_activation %*% t(array(model$recurrent_synapse[[i]][,,4],dim=c(dim(model$recurrent_synapse[[i]])[1:2]))) # 17
447
+ future_layer_hidden_delta[[i]] = layer_o_delta_pre_weight + layer_c_delta_pre_weight + layer_i_delta_pre_weight + layer_f_delta_pre_weight # 21
448
+
449
+ layer_f_delta_pre_weight = layer_f_delta_pre_activation %*% t(array(model$time_synapse[[i]][,,1],dim=c(dim(model$time_synapse[[i]])[1:2]))) # 20
450
+ layer_i_delta_pre_weight = layer_i_delta_pre_activation %*% t(array(model$time_synapse[[i]][,,2],dim=c(dim(model$time_synapse[[i]])[1:2]))) # 19
451
+ layer_c_delta_pre_weight = layer_c_delta_pre_activation %*% t(array(model$time_synapse[[i]][,,3],dim=c(dim(model$time_synapse[[i]])[1:2]))) # 18
452
+ layer_o_delta_pre_weight = layer_o_delta_pre_activation %*% t(array(model$time_synapse[[i]][,,4],dim=c(dim(model$time_synapse[[i]])[1:2]))) # 17
453
+ layer_up_delta = layer_o_delta_pre_weight + layer_c_delta_pre_weight + layer_i_delta_pre_weight + layer_f_delta_pre_weight # 21
454
+ }
455
+ }
456
+
457
+ # future_layers_delta = list()
458
+ # for(i in seq(length(model$hidden_dim))){
459
+ # future_layers_delta[[i]] = array(0,dim=c(length(j),model$hidden_dim[i],4))
460
+ # }
461
+ #
462
+ # for (position in model$time_dim:1) {
463
+ #
464
+ # # input states
465
+ # x = array(a[,position,],dim=c(length(j),model$input_dim))
466
+ # # error at output layer
467
+ # layer_up_delta = array(model$last_layer_delta[j,position,],dim=c(length(j),model$output_dim))
468
+ #
469
+ # for(i in (length(model$store)):1){
470
+ # if(i != 1){ # need update for time and recurrent synapse
471
+ # layer_current = array(model$store[[i-1]][j,position,],dim=c(length(j),model$hidden_dim[i-1]))
472
+ # if(position != 1){
473
+ # prev_layer_current = array(model$store[[i-1]][j,position - 1,],dim=c(length(j),model$hidden_dim[i-1]))
474
+ # }else{
475
+ # prev_layer_current = array(0,dim=c(length(j),model$hidden_dim[i-1]))
476
+ # }
477
+ # }
478
+ # if(i == length(model$store)){
479
+ # # error at hidden layer
480
+ # future_layers_delta[[i-1]][,,1] = (future_layers_delta[[i-1]][,,1] %*% t(model$recurrent_synapse[[i-1]][,,1]) + layer_up_delta %*% t(model$time_synapse_ouput)) *
481
+ # sigmoid_output_to_derivative(layer_current)
482
+ # future_layers_delta[[i-1]][,,2] = (future_layers_delta[[i-1]][,,2] %*% t(model$recurrent_synapse[[i-1]][,,2]) + layer_up_delta %*% t(model$time_synapse_ouput)) *
483
+ # sigmoid_output_to_derivative(layer_current)
484
+ # future_layers_delta[[i-1]][,,3] = (future_layers_delta[[i-1]][,,3] %*% t(model$recurrent_synapse[[i-1]][,,3]) + layer_up_delta %*% t(model$time_synapse_ouput)) *
485
+ # sigmoid_output_to_derivative(layer_current)
486
+ # future_layers_delta[[i-1]][,,4] = (future_layers_delta[[i-1]][,,4] %*% t(model$recurrent_synapse[[i-1]][,,4]) + layer_up_delta %*% t(model$time_synapse_ouput)) *
487
+ # sigmoid_output_to_derivative(layer_current)
488
+ #
489
+ # # let's update all our weights so we can try again
490
+ # model$time_synapse_ouput_update = model$time_synapse_ouput_update + t(layer_current) %*% layer_up_delta
491
+ # model$recurrent_synapse_update[[i-1]][,,1] = model$recurrent_synapse_update[[i-1]][,,1] + t(prev_layer_current) %*% future_layers_delta[[i-1]][,,1]
492
+ # model$recurrent_synapse_update[[i-1]][,,2] = model$recurrent_synapse_update[[i-1]][,,2] + t(prev_layer_current) %*% future_layers_delta[[i-1]][,,2]
493
+ # model$recurrent_synapse_update[[i-1]][,,3] = model$recurrent_synapse_update[[i-1]][,,3] + t(prev_layer_current) %*% future_layers_delta[[i-1]][,,3]
494
+ # model$recurrent_synapse_update[[i-1]][,,4] = model$recurrent_synapse_update[[i-1]][,,4] + t(prev_layer_current) %*% future_layers_delta[[i-1]][,,4]
495
+ #
496
+ # model$bias_synapse_ouput_update = model$bias_synapse_ouput_update + colMeans(layer_up_delta)
497
+ #
498
+ # model$bias_synapse_update[[i-1]] = model$bias_synapse_update[[i-1]] + apply(future_layers_delta[[i-1]],2:3,mean)
499
+ #
500
+ # } else if(i == 1){
501
+ # model$time_synapse_update[[i]][,,1] = model$time_synapse_update[[i]][,,1] + t(x) %*% future_layers_delta[[i]][,,1]
502
+ # model$time_synapse_update[[i]][,,2] = model$time_synapse_update[[i]][,,2] + t(x) %*% future_layers_delta[[i]][,,2]
503
+ # model$time_synapse_update[[i]][,,3] = model$time_synapse_update[[i]][,,3] + t(x) %*% future_layers_delta[[i]][,,3]
504
+ # model$time_synapse_update[[i]][,,4] = model$time_synapse_update[[i]][,,4] + t(x) %*% future_layers_delta[[i]][,,4]
505
+ # }
506
+ # }
507
+ # }
508
+ return(model)
509
+ }
510
+
511
+ #' @name backprop_gru
512
+ #' @title backprop_gru
513
+ #' @description backpropagate the error in a model object of type gru
514
+ #' @importFrom sigmoid tanh_output_to_derivative
515
+ #' @param model the output model object
516
+ #' @param a the input of this learning batch
517
+ #' @param c the output of this learning batch
518
+ #' @param j the indexes of the sample in the current batch
519
+ #' @param ... argument to be passed to method
520
+ #' @return the updated model
521
+
522
+ backprop_gru = function(model,a,c,j,...){
523
+
524
+ # store errors
525
+ model$last_layer_error[j,,] = c - model$store[[length(model$store)]][j,,,drop=F]
526
+ model$last_layer_delta[j,,] = model$last_layer_error[j,,,drop = F] * sigmoid_output_to_derivative(model$store[[length(model$store)]][j,,,drop=F])
527
+
528
+ # many_to_one
529
+ if(model$seq_to_seq_unsync){
530
+ model$last_layer_error[j,1:(model$time_dim_input - 1),] = 0
531
+ model$last_layer_delta[j,1:(model$time_dim_input - 1),] = 0
532
+ }
533
+ model$error[j,model$current_epoch] <- apply(model$last_layer_error[j,,,drop=F],1,function(x){sum(abs(x))})
534
+
535
+ future_layer_hidden_delta = list()
536
+ for(i in seq(length(model$hidden_dim))){
537
+ future_layer_hidden_delta[[i]] = matrix(0, nrow = length(j), ncol = model$hidden_dim[i]) # 2, to actualize
538
+ }
539
+
540
+
541
+ for (position in model$time_dim:1) {
542
+ # error at output layer
543
+ layer_up_delta = array(model$last_layer_delta[j,position,],dim=c(length(j),model$output_dim))
544
+
545
+ # first the last layer to update the layer_up_delta
546
+ i = length(model$hidden_dim)
547
+ layer_hidden = array(model$store[[i]][j,position,,1],dim=c(length(j),model$hidden_dim[i]))
548
+ # output layer update
549
+ model$time_synapse_update[[i+1]] = model$time_synapse_update[[i+1]] + (t(layer_hidden) %*% layer_up_delta)
550
+ model$bias_synapse_update[[i+1]] = model$bias_synapse_update[[i+1]] + colMeans(layer_up_delta)
551
+ # lstm hidden delta
552
+ layer_up_delta = (layer_up_delta %*% t(model$time_synapse_update[[i+1]])) * sigmoid_output_to_derivative(layer_hidden) + future_layer_hidden_delta[[i]] # 1 and 3
553
+
554
+ for(i in length(model$hidden_dim):1){
555
+ # x: input of the layer
556
+ if(i == 1){
557
+ x = array(a[,position,],dim=c(length(j),model$input_dim))
558
+ }else{
559
+ x = array(model$store[[i - 1]][j,position,,1],dim=c(length(j),model$synapse_dim[i]))
560
+ }
561
+ layer_hidden = array(model$store[[i]][j,position,,1],dim=c(length(j),model$hidden_dim[i]))
562
+ if(position != 1){
563
+ prev_layer_hidden =array(model$store[[i]][j,position-1,,1],dim=c(length(j),model$hidden_dim[i]))
564
+ }else{
565
+ prev_layer_hidden =array(0,dim=c(length(j),model$hidden_dim[i]))
566
+ }
567
+
568
+ layer_z = array(model$store[[i]][j,position,,2],dim=c(length(j), model$hidden_dim[i]))
569
+ layer_r = array(model$store[[i]][j,position,,3],dim=c(length(j), model$hidden_dim[i]))
570
+ layer_h = array(model$store[[i]][j,position,,4],dim=c(length(j), model$hidden_dim[i]))
571
+
572
+ layer_hidden_delta = layer_up_delta + future_layer_hidden_delta[[i]] #3
573
+ layer_h_delta_post_activation = layer_hidden_delta * layer_z # 6
574
+ layer_h_delta_pre_activation = layer_h_delta_post_activation * tanh_output_to_derivative(layer_h) # 6 bis
575
+ layer_z_delta_post_split = layer_hidden_delta * layer_h # 7
576
+
577
+ layer_z_delta_post_1_minus = layer_hidden_delta * prev_layer_hidden # 9
578
+ layer_hidden_delta = layer_hidden_delta * (1 - layer_z) # 8
579
+
580
+ layer_z_delta_post_activation = (1 - layer_z_delta_post_1_minus) # 10
581
+ layer_z_delta_pre_activation = layer_z_delta_post_activation* sigmoid_output_to_derivative(layer_z) # 10 bis
582
+ layer_z_delta_pre_weight_h = (layer_z_delta_pre_activation %*% t(model$recurrent_synapse[[i]][,,1]) ) # 14
583
+ layer_z_delta_pre_weight_x = (layer_z_delta_pre_activation %*% array(t(model$time_synapse[[i]][,,1]),dim = dim(model$time_synapse[[i]])[2:1])) # 14
584
+ # let's update all our weights so we can try again
585
+ model$recurrent_synapse_update[[i]][,,1] = model$recurrent_synapse_update[[i]][,,1] + t(prev_layer_hidden) %*% layer_z_delta_post_activation
586
+ model$time_synapse_update[[i]][,,1] = model$time_synapse_update[[i]][,,1] + t(x) %*% layer_z_delta_post_activation
587
+ model$bias_synapse_update[[i]][,1] = model$bias_synapse_update[[i]][,1] + colMeans(layer_z_delta_post_activation)
588
+
589
+ layer_h_delta_pre_weight_h = (layer_h_delta_pre_activation %*% t(model$recurrent_synapse[[i]][,,3]))# 13
590
+ layer_h_delta_pre_weight_x = ( layer_h_delta_pre_activation %*% array(t(model$time_synapse[[i]][,,3]),dim = dim(model$time_synapse[[i]])[2:1])) # 13
591
+ # let's update all our weights so we can try again
592
+ model$recurrent_synapse_update[[i]][,,3] = model$recurrent_synapse_update[[i]][,,3] + t(prev_layer_hidden * layer_r) %*% layer_h_delta_post_activation
593
+ model$time_synapse_update[[i]][,,3] = model$time_synapse_update[[i]][,,3] + t(x) %*% layer_h_delta_post_activation
594
+ model$bias_synapse_update[[i]][,3] = model$bias_synapse_update[[i]][,3] + colMeans(layer_h_delta_post_activation)
595
+
596
+ layer_r_delta_post_activation = prev_layer_hidden * layer_h_delta_pre_weight_h # 15
597
+ layer_r_delta_pre_activation = layer_r_delta_post_activation * sigmoid_output_to_derivative(layer_r) # 15 bis
598
+ layer_hidden_delta = layer_hidden_delta + layer_r * layer_h_delta_pre_weight_h # 12
599
+
600
+ layer_r_delta_pre_weight_h = (layer_r_delta_pre_activation %*% t(model$recurrent_synapse[[i]][,,2])) # 17
601
+ layer_r_delta_pre_weight_x = (layer_r_delta_post_activation %*% array(t(model$time_synapse[[i]][,,2]),dim = dim(model$time_synapse[[i]])[2:1])) # 17
602
+ # let's update all our weights so we can try again
603
+ model$recurrent_synapse_update[[i]][,,2] = model$recurrent_synapse_update[[i]][,,2] + t(prev_layer_hidden) %*% layer_r_delta_post_activation
604
+ model$time_synapse_update[[i]][,,2] = model$time_synapse_update[[i]][,,2] + t(x) %*% layer_r_delta_post_activation
605
+ model$bias_synapse_update[[i]][,2] = model$bias_synapse_update[[i]][,2] + colMeans(layer_r_delta_post_activation)
606
+
607
+ layer_r_and_z_delta_pre_weight_h = layer_r_delta_pre_weight_h + layer_z_delta_pre_weight_h # 19
608
+ layer_r_and_z_delta_pre_weight_x = layer_r_delta_pre_weight_x + layer_z_delta_pre_weight_x # 19
609
+
610
+ future_layer_hidden_delta[[i]] = layer_hidden_delta + layer_r_and_z_delta_pre_weight_h # 23
611
+
612
+ layer_up_delta = layer_r_and_z_delta_pre_weight_x + layer_h_delta_pre_weight_x # 22
613
+ }
614
+ }
615
+ return(model)
616
+ }
617
+
618
+
619
+ update_r = function(model){
620
+ if(model$update_rule == "sgd"){
621
+ update_sgd(model)
622
+ }else if(model$update_rule == "adagrad"){
623
+ update_adagrad(model)
624
+ }else{
625
+ stop("update_rule unknown")
626
+ }
627
+ }
628
+
629
+
630
+ #' @name update_sgd
631
+ #' @title update_sgd
632
+ #' @description Apply the update with stochastic gradient descent
633
+ #' @param model the output model object
634
+ #' @return the updated model
635
+
636
+ update_sgd = function(model){
637
+
638
+ if(!is.null(model$clipping)){ # should we clippe the update or the weight, the update will make more sens as the weight lead to killed units
639
+ clipping = function(x){
640
+ x[is.nan(x)] = runif(sum(is.nan(x)),-1,1)
641
+ x[x > model$clipping] = model$clipping
642
+ x[x < -model$clipping] = - model$clipping
643
+ return(x)
644
+ }
645
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,clipping)
646
+ model$time_synapse_update = lapply(model$time_synapse_update,clipping)
647
+ model$bias_synapse_update = lapply(model$bias_synapse_update, clipping)
648
+ }
649
+
650
+ for(i in seq(length(model$time_synapse))){
651
+ model$time_synapse[[i]] <- model$time_synapse[[i]] + model$time_synapse_update[[i]]
652
+ model$bias_synapse[[i]] <- model$bias_synapse[[i]] + model$bias_synapse_update[[i]]
653
+ }
654
+ for(i in seq(length(model$recurrent_synapse))){
655
+ model$recurrent_synapse[[i]] <- model$recurrent_synapse[[i]] + model$recurrent_synapse_update[[i]]
656
+ }
657
+
658
+ # Initializing the update with the momentum
659
+ model$time_synapse_update = lapply(model$time_synapse_update,function(x){x* model$momentum})
660
+ model$bias_synapse_update = lapply(model$bias_synapse_update,function(x){x* model$momentum})
661
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,function(x){x* model$momentum})
662
+
663
+ return(model)
664
+ }
665
+
666
+
667
+ #' @name update_adagrad
668
+ #' @title update_adagrad
669
+ #' @description Apply the update with adagrad, not working yet
670
+ #' @param model the output model object
671
+ #' @return the updated model
672
+
673
+ update_adagrad = function(model){
674
+ ## not working yet, inspiration here:
675
+ ## https://www.quora.com/What-are-differences-between-update-rules-like-AdaDelta-RMSProp-AdaGrad-and-AdaM
676
+ if(!is.null(model$clipping)){ # should we clippe the update or the weight, the update will make more sens as the weight lead to killed units
677
+ clipping = function(x){
678
+ x[is.nan(x)] = runif(sum(is.nan(x)),-1,1)
679
+ x[x > model$clipping] = model$clipping
680
+ x[x < -model$clipping] = - model$clipping
681
+ return(x)
682
+ }
683
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,clipping)
684
+ model$time_synapse_update = lapply(model$time_synapse_update,clipping)
685
+ model$bias_synapse_update = lapply(model$bias_synapse_update, clipping)
686
+ }
687
+
688
+ if(is.null(model$recurrent_synapse_update_old)){ # not really the old update but just a store of the old
689
+ model$recurrent_synapse_update_old = lapply(model$recurrent_synapse_update,function(x){x*0})
690
+ model$time_synapse_update_old = lapply(model$time_synapse_update,function(x){x*0})
691
+ # model$bias_synapse_update_old = lapply(model$bias_synapse_update,function(x){x*0}) # the bias stay the same, we only apply it on the weight
692
+ }
693
+
694
+ for(i in seq(length(model$time_synapse))){
695
+ model$time_synapse_update_old[[i]] <- model$time_synapse_update_old[[i]] + model$time_synapse_update[[i]]
696
+ # model$bias_synapse_old[[i]] <- model$bias_synapse[[i]] + model$bias_synapse_update[[i]]
697
+ }
698
+ for(i in seq(length(model$recurrent_synapse))){
699
+ model$recurrent_synapse_update_old[[i]] <- model$recurrent_synapse_update_old[[i]] + model$recurrent_synapse_update[[i]]
700
+ }
701
+
702
+ for(i in seq(length(model$time_synapse))){
703
+ model$time_synapse[[i]] <- model$time_synapse[[i]] + model$learningrate * model$time_synapse_update[[i]] / (model$time_synapse_update_old[[i]] + 0.000000001)
704
+ model$bias_synapse[[i]] <- model$bias_synapse[[i]] + model$bias_synapse_update[[i]]
705
+ }
706
+ for(i in seq(length(model$recurrent_synapse))){
707
+ model$recurrent_synapse[[i]] <- model$recurrent_synapse[[i]] + model$learningrate * model$recurrent_synapse_update[[i]] / (model$recurrent_synapse_update_old[[i]] + 0.000000001)
708
+ }
709
+
710
+ return(model)
711
+ }
712
+
713
+ #' @name epoch_print
714
+ #' @export
715
+ #' @title epoch printing for trainr
716
+ #' @description Print the error adn learning rate at each epoch of the trainr learning, called in epoch_function
717
+ #' @param model the output model object
718
+ #' @return nothing
719
+
720
+ epoch_print = function(model){
721
+ message(paste0("Trained epoch: ",model$current_epoch," - Learning rate: ",model$learningrate))
722
+ message(paste0("Epoch error: ",colMeans(model$error)[model$current_epoch]))
723
+ return(model)
724
+ }
725
+
726
+ #' @name epoch_annealing
727
+ #' @export
728
+ #' @title epoch annealing
729
+ #' @description Apply the learning rate decay to the learning rate, called in epoch_model_function
730
+ #' @param model the output model object
731
+ #' @return the updated model
732
+
733
+ epoch_annealing = function(model){
734
+ model$learningrate = model$learningrate * model$learningrate_decay
735
+ return(model)
736
+ }
737
+
738
+ #' @name loss_L1
739
+ #' @export
740
+ #' @title L1 loss
741
+ #' @description Apply the learning rate to the weight update, vocabulary to verify !!
742
+ #' @param model the output model object
743
+ #' @return the updated model
744
+
745
+ loss_L1 = function(model){
746
+ if(model$network_type == "rnn"){
747
+ model$time_synapse_update = lapply(model$time_synapse_update,function(x){x* model$learningrate})
748
+ model$bias_synapse_update = lapply(model$bias_synapse_update,function(x){x* model$learningrate})
749
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,function(x){x* model$learningrate})
750
+ } else if(model$network_type == "lstm"){
751
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,function(x){x * model$learningrate})
752
+ model$time_synapse_update = lapply(model$time_synapse_update,function(x){x * model$learningrate})
753
+ model$bias_synapse_update = lapply(model$bias_synapse_update, function(x){x * model$learningrate})
754
+ } else if(model$network_type == "gru"){
755
+ model$recurrent_synapse_update = lapply(model$recurrent_synapse_update,function(x){x * model$learningrate})
756
+ model$time_synapse_update = lapply(model$time_synapse_update,function(x){x * model$learningrate})
757
+ model$bias_synapse_update = lapply(model$bias_synapse_update, function(x){x * model$learningrate})
758
+ }
759
+ return(model)
760
+ }
761
+
762
+
763
+ #' @name predictr
764
+ #' @export
765
+ #' @importFrom stats runif
766
+ #' @importFrom sigmoid sigmoid
767
+ #' @title Recurrent Neural Network
768
+ #' @description predict the output of a RNN model
769
+ #' @param model output of the trainr function
770
+ #' @param X array of input values, dim 1: samples, dim 2: time, dim 3: variables (could be 1 or more, if a matrix, will be coerce to array)
771
+ #' @param hidden should the function output the hidden units states
772
+ #' @param real_output option used when the function in called inside trainr, do not drop factor for 2 dimension array output and other actions. Let it to TRUE, the default, to let the function take care of the data.
773
+ #' @param ... arguments to pass on to sigmoid function
774
+ #' @return array or matrix of predicted values
775
+ #' @examples
776
+ #' \dontrun{
777
+ #' # create training numbers
778
+ #' X1 = sample(0:127, 10000, replace=TRUE)
779
+ #' X2 = sample(0:127, 10000, replace=TRUE)
780
+ #'
781
+ #' # create training response numbers
782
+ #' Y <- X1 + X2
783
+ #'
784
+ #' # convert to binary
785
+ #' X1 <- int2bin(X1)
786
+ #' X2 <- int2bin(X2)
787
+ #' Y <- int2bin(Y)
788
+ #'
789
+ #' # Create 3d array: dim 1: samples; dim 2: time; dim 3: variables.
790
+ #' X <- array( c(X1,X2), dim=c(dim(X1),2) )
791
+ #'
792
+ #' # train the model
793
+ #' model <- trainr(Y=Y[,dim(Y)[2]:1],
794
+ #' X=X[,dim(X)[2]:1,],
795
+ #' learningrate = 1,
796
+ #' hidden_dim = 16 )
797
+ #'
798
+ #' # create test inputs
799
+ #' A1 = int2bin( sample(0:127, 7000, replace=TRUE) )
800
+ #' A2 = int2bin( sample(0:127, 7000, replace=TRUE) )
801
+ #'
802
+ #' # create 3d array: dim 1: samples; dim 2: time; dim 3: variables
803
+ #' A <- array( c(A1,A2), dim=c(dim(A1),2) )
804
+ #'
805
+ #' # predict
806
+ #' B <- predictr(model,
807
+ #' A[,dim(A)[2]:1,] )
808
+ #' B = B[,dim(B)[2]:1]
809
+ #' # convert back to integers
810
+ #' A1 <- bin2int(A1)
811
+ #' A2 <- bin2int(A2)
812
+ #' B <- bin2int(B)
813
+ #'
814
+ #' # inspect the differences
815
+ #' table( B-(A1+A2) )
816
+ #'
817
+ #' # plot the difference
818
+ #' hist( B-(A1+A2) )
819
+ #' }
820
+ #'
821
+ predictr = function(model, X, hidden = FALSE, real_output = T,...){
822
+
823
+ # coerce to array if matrix
824
+ if(length(dim(X)) == 2){
825
+ X <- array(X,dim=c(dim(X),1))
826
+ }
827
+
828
+ if(real_output && model$seq_to_seq_unsync){ ## here we modify the X in case of seq_2_seq & real_output to have the good dimensions
829
+ time_dim_input = dim(X)[2]
830
+ store = array(0, dim = c(dim(X)[1],model$time_dim,dim(X)[3]))
831
+ store[,1:dim(X)[2],] = X
832
+ X = store
833
+ rm(store)
834
+ }
835
+
836
+ if(model$network_type == "rnn"){
837
+ store = predict_rnn(model, X, hidden, real_output,...)
838
+ } else if (model$network_type == "lstm"){
839
+ store = predict_lstm(model, X, hidden, real_output,...)
840
+ } else if (model$network_type == "gru"){
841
+ store = predict_gru(model, X, hidden, real_output,...)
842
+ }else{
843
+ stop("network_type_unknown for the prediction")
844
+ }
845
+
846
+ if(real_output && model$seq_to_seq_unsync){
847
+ if(length(dim(store)) == 2){
848
+ store = store[,model$time_dim_input:model$time_dim,drop=F]
849
+ }else{
850
+ store = store[,model$time_dim_input:model$time_dim,,drop=F]
851
+ }
852
+ }
853
+
854
+ return(store)
855
+ }
856
+
857
+ #' @name predict_rnn
858
+ #' @importFrom stats runif
859
+ #' @importFrom sigmoid sigmoid
860
+ #' @title Recurrent Neural Network
861
+ #' @description predict the output of a RNN model
862
+ #' @param model output of the trainr function
863
+ #' @param X array of input values, dim 1: samples, dim 2: time, dim 3: variables (could be 1 or more, if a matrix, will be coerce to array)
864
+ #' @param hidden should the function output the hidden units states
865
+ #' @param real_output option used when the function in called inside trainr, do not drop factor for 2 dimension array output
866
+ #' @param ... arguments to pass on to sigmoid function
867
+ #' @return array or matrix of predicted values
868
+
869
+ predict_rnn <- function(model, X, hidden = FALSE, real_output = T,...) {
870
+
871
+ store <- list()
872
+ for(i in seq(length(model$synapse_dim) - 1)){
873
+ store[[i]] <- array(0,dim = c(dim(X)[1:2],model$synapse_dim[i+1]))
874
+ }
875
+
876
+ # store the hidden layers values for each time step, needed in parallel of store because we need the t(-1) hidden states. otherwise, we could take the values from the store list
877
+ layers_values = list()
878
+ for(i in seq(length(model$synapse_dim) - 2)){
879
+ layers_values[[i]] <- matrix(0,nrow=dim(X)[1], ncol = model$synapse_dim[i+1])
880
+ }
881
+
882
+ for (position in 1:dim(X)[2]) {
883
+
884
+ # generate input
885
+ x = array(X[,position,],dim=dim(X)[c(1,3)])
886
+
887
+ for(i in seq(length(model$synapse_dim) - 1)){
888
+ if (i == 1) { # first hidden layer, need to take x as input
889
+ store[[i]][,position,] <- (x %*% model$time_synapse[[i]]) + (layers_values[[i]] %*% model$recurrent_synapse[[i]])
890
+ } else if (i != length(model$synapse_dim) - 1 & i != 1){ #hidden layers not linked to input layer, depends of the last time step
891
+ store[[i]][,position,] <- (store[[i-1]][,position,] %*% model$time_synapse[[i]]) + (layers_values[[i]] %*% model$recurrent_synapse[[i]])
892
+ } else { # output layer depend only of the hidden layer of bellow
893
+ store[[i]][,position,] <- store[[i-1]][,position,] %*% model$time_synapse[[i]]
894
+ }
895
+ if(model$use_bias){ # apply the bias if applicable
896
+ store[[i]][,position,] <- store[[i]][,position,] + model$bias_synapse[[i]]
897
+ }
898
+ # apply the activation function
899
+ store[[i]][,position,] <- sigmoid(store[[i]][,position,], method=model$sigmoid)
900
+
901
+ if(i != length(model$synapse_dim) - 1){ # for all hidden layers, we need the previous state, looks like we duplicate the values here, it is also in the store list
902
+ # store hidden layers so we can print it out. Needed for error calculation and weight iteration
903
+ layers_values[[i]] = store[[i]][,position,]
904
+ }
905
+ }
906
+ }
907
+
908
+ # convert output to matrix if 2 dimensional, real_output argument added if used inside trainr
909
+ if(real_output){
910
+ if(dim(store[[length(store)]])[3]==1) {
911
+ store[[length(store)]] <- matrix(store[[length(store)]],
912
+ nrow = dim(store[[length(store)]])[1],
913
+ ncol = dim(store[[length(store)]])[2])
914
+ }
915
+ }
916
+
917
+ # return output
918
+ if(hidden == FALSE){ # return only the last element of the list, i.e. the output
919
+ return(store[[length(store)]])
920
+ }else{ # return everything
921
+ return(store)
922
+ }
923
+ }
924
+
925
+ #' @name predict_lstm
926
+ #' @importFrom stats runif
927
+ #' @importFrom sigmoid sigmoid
928
+ #' @title gru prediction function
929
+ #' @description predict the output of a lstm model
930
+ #' @param model output of the trainr function
931
+ #' @param X array of input values, dim 1: samples, dim 2: time, dim 3: variables (could be 1 or more, if a matrix, will be coerce to array)
932
+ #' @param hidden should the function output the hidden units states
933
+ #' @param real_output option used when the function in called inside trainr, do not drop factor for 2 dimension array output
934
+ #' @param ... arguments to pass on to sigmoid function
935
+ #' @return array or matrix of predicted values
936
+
937
+ predict_lstm <- function(model, X, hidden = FALSE, real_output = T,...) {
938
+
939
+ store <- list()
940
+ prev_layer_values = list()
941
+ c_t = list()
942
+ for(i in seq(length(model$hidden_dim))){
943
+ store[[i]] = array(0,dim = c(dim(X)[1:2],model$hidden_dim[i],6)) # 4d arrays !!!, hidden, cell, f, i, g, o
944
+ prev_layer_values[[i]] = matrix(0,nrow=dim(X)[1], ncol = model$hidden_dim[i]) # we need this object because of t-1 which do not exist in store
945
+ c_t[[i]] = matrix(0,nrow=dim(X)[1], ncol = model$hidden_dim[i]) # we need this object because of t-1 which do not exist in store
946
+ }
947
+ store[[length(store)+1]] <- array(0,dim = c(dim(X)[1:2],model$output_dim))
948
+
949
+ for (position in 1:dim(X)[2]) {
950
+
951
+ # generate input
952
+ x = array(X[,position,],dim=dim(X)[c(1,3)])
953
+
954
+ for(i in seq(length(model$hidden_dim))){
955
+ # hidden layer (input ~+ prev_hidden)
956
+ f_t = (x %*% array(model$time_synapse[[i]][,,1],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (prev_layer_values[[i]] %*% array(model$recurrent_synapse[[i]][,,1],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
957
+ i_t = (x %*% array(model$time_synapse[[i]][,,2],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (prev_layer_values[[i]] %*% array(model$recurrent_synapse[[i]][,,2],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
958
+ c_in_t = (x %*% array(model$time_synapse[[i]][,,3],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (prev_layer_values[[i]] %*% array(model$recurrent_synapse[[i]][,,3],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
959
+ o_t = (x %*% array(model$time_synapse[[i]][,,4],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (prev_layer_values[[i]] %*% array(model$recurrent_synapse[[i]][,,4],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
960
+ if(model$use_bias){
961
+ f_t = f_t + model$bias_synapse[[i]][,1]
962
+ i_t = i_t + model$bias_synapse[[i]][,2]
963
+ c_in_t = c_in_t + model$bias_synapse[[i]][,3]
964
+ o_t = o_t + model$bias_synapse[[i]][,4]
965
+ }
966
+ f_t = sigmoid(f_t)
967
+ i_t = sigmoid(i_t)
968
+ c_in_t = tanh(c_in_t)
969
+ o_t = sigmoid(o_t)
970
+
971
+ c_t[[i]] = f_t * c_t[[i]] + (i_t * c_in_t)
972
+ store[[i]][,position,,1] = o_t * tanh(c_t[[i]])
973
+ store[[i]][,position,,2] = c_t[[i]]
974
+ store[[i]][,position,,3] = f_t
975
+ store[[i]][,position,,4] = i_t
976
+ store[[i]][,position,,5] = c_in_t
977
+ store[[i]][,position,,6] = o_t
978
+
979
+ # replace the x in case of multi layer
980
+ prev_layer_values[[i]] = x = o_t * tanh(c_t[[i]])# the top of this layer at this position is the past of the top layer at the next position
981
+ }
982
+
983
+
984
+ # output layer (new binary representation)
985
+ store[[length(store)]][,position,] = store[[length(store) - 1]][,position,,1] %*% model$time_synapse[[length(model$time_synapse)]]
986
+ if(model$use_bias){
987
+ store[[length(store)]][,position,] = store[[length(store)]][,position,] + model$bias_synapse[[length(model$bias_synapse)]]
988
+ }
989
+ store[[length(store)]][,position,] = sigmoid(store[[length(store)]][,position,])
990
+ } # end time loop
991
+
992
+ # convert output to matrix if 2 dimensional, real_output argument added if used inside trainr
993
+ if(real_output){
994
+ if(dim(store[[length(store)]])[3]==1) {
995
+ store[[length(store)]] <- matrix(store[[length(store)]],
996
+ nrow = dim(store[[length(store)]])[1],
997
+ ncol = dim(store[[length(store)]])[2])
998
+ }
999
+ }
1000
+
1001
+ # return output
1002
+ if(hidden == FALSE){ # return only the last element of the list, i.e. the output
1003
+ return(store[[length(store)]])
1004
+ }else{ # return everything
1005
+ return(store)
1006
+ }
1007
+ }
1008
+
1009
+
1010
+
1011
+ #' @name predict_gru
1012
+ #' @importFrom stats runif
1013
+ #' @importFrom sigmoid sigmoid
1014
+ #' @title gru prediction function
1015
+ #' @description predict the output of a gru model
1016
+ #' @param model output of the trainr function
1017
+ #' @param X array of input values, dim 1: samples, dim 2: time, dim 3: variables (could be 1 or more, if a matrix, will be coerce to array)
1018
+ #' @param hidden should the function output the hidden units states
1019
+ #' @param real_output option used when the function in called inside trainr, do not drop factor for 2 dimension array output
1020
+ #' @param ... arguments to pass on to sigmoid function
1021
+ #' @return array or matrix of predicted values
1022
+
1023
+ predict_gru <- function(model, X, hidden = FALSE, real_output = T,...) {
1024
+
1025
+ store <- list()
1026
+ h_t = list()
1027
+ for(i in seq(length(model$hidden_dim))){
1028
+ store[[i]] = array(0,dim = c(dim(X)[1:2],model$hidden_dim[i],4)) # 4d arrays !!!, hidden, z, r, h
1029
+ h_t[[i]] = matrix(0,nrow=dim(X)[1], ncol = model$hidden_dim[i]) # we need this object because of t-1 which do not exist in store
1030
+ }
1031
+ store[[length(store)+1]] <- array(0,dim = c(dim(X)[1:2],model$output_dim))
1032
+
1033
+ for (position in 1:dim(X)[2]) {
1034
+
1035
+ # generate input
1036
+ x = array(X[,position,],dim=dim(X)[c(1,3)])
1037
+
1038
+ for(i in seq(length(model$hidden_dim))){
1039
+ # hidden layer (input ~+ prev_hidden)
1040
+ z_t = (x %*% array(model$time_synapse[[i]][,,1],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (h_t[[i]] %*% array(model$recurrent_synapse[[i]][,,1],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
1041
+ r_t = (x %*% array(model$time_synapse[[i]][,,2],dim=c(dim(model$time_synapse[[i]])[1:2]))) + (h_t[[i]] %*% array(model$recurrent_synapse[[i]][,,2],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
1042
+ if(model$use_bias){
1043
+ z_t = z_t + model$bias_synapse[[i]][,1]
1044
+ r_t = r_t + model$bias_synapse[[i]][,2]
1045
+ }
1046
+ z_t = sigmoid(z_t)
1047
+ r_t = sigmoid(r_t)
1048
+
1049
+ h_in_t = (x %*% array(model$time_synapse[[i]][,,3],dim=c(dim(model$time_synapse[[i]])[1:2]))) + ((h_t[[i]] * r_t) %*% array(model$recurrent_synapse[[i]][,,3],dim=c(dim(model$recurrent_synapse[[i]])[1:2])))
1050
+ if(model$use_bias){
1051
+ h_in_t = h_in_t + model$bias_synapse[[i]][,3]
1052
+ }
1053
+ h_in_t = tanh(h_in_t)
1054
+
1055
+ h_t[[i]] = (1 - z_t) * h_t[[i]] + (z_t * h_in_t)
1056
+ store[[i]][,position,,1] = h_t[[i]]
1057
+ store[[i]][,position,,2] = z_t
1058
+ store[[i]][,position,,3] = r_t
1059
+ store[[i]][,position,,4] = h_in_t
1060
+
1061
+ # replace the x in case of multi layer
1062
+ x = h_t[[i]] # the top of this layer at this position is the past of the top layer at the next position
1063
+ }
1064
+
1065
+
1066
+ # output layer (new binary representation)
1067
+ store[[length(store)]][,position,] = store[[length(store) - 1]][,position,,1] %*% model$time_synapse[[length(model$time_synapse)]]
1068
+ if(model$use_bias){
1069
+ store[[length(store)]][,position,] = store[[length(store)]][,position,] + model$bias_synapse[[length(model$bias_synapse)]]
1070
+ }
1071
+ store[[length(store)]][,position,] = sigmoid(store[[length(store)]][,position,])
1072
+ } # end time loop
1073
+
1074
+ # convert output to matrix if 2 dimensional, real_output argument added if used inside trainr
1075
+ if(real_output){
1076
+ if(dim(store[[length(store)]])[3]==1) {
1077
+ store[[length(store)]] <- matrix(store[[length(store)]],
1078
+ nrow = dim(store[[length(store)]])[1],
1079
+ ncol = dim(store[[length(store)]])[2])
1080
+ }
1081
+ }
1082
+
1083
+ # return output
1084
+ if(hidden == FALSE){ # return only the last element of the list, i.e. the output
1085
+ return(store[[length(store)]])
1086
+ }else{ # return everything
1087
+ return(store)
1088
+ }
1089
+ }
1090
+
1091
+
1092
+
1093
+ ####
1094
+
1095
+ error<-as.data.frame(c(1:epochD))
1096
+ colnames(error)<-"Iteration"
1097
+
1098
+ rnn<- function (Y, X, model = NULL, learningrate, learningrate_decay = 1,
1099
+ momentum = 0, hidden_dim = c(10), network_type = "rnn", numepochs = 1,
1100
+ sigmoid = c("logistic", "Gompertz", "tanh"), use_bias = F,
1101
+ batch_size = 1, seq_to_seq_unsync = F, update_rule = "sgd",
1102
+ epoch_function = c(epoch_print, epoch_annealing), loss_function = loss_L1,
1103
+ ...)
1104
+
1105
+ {
1106
+ sigmoid <- match.arg(sigmoid)
1107
+ if (length(dim(X)) == 2) {
1108
+ X <- array(X, dim = c(dim(X), 1))
1109
+ }
1110
+ if (length(dim(Y)) == 2) {
1111
+ Y <- array(Y, dim = c(dim(Y), 1))
1112
+ }
1113
+ if (seq_to_seq_unsync) {
1114
+ time_dim_input = dim(X)[2]
1115
+ store = array(0, dim = c(dim(X)[1], dim(X)[2] + dim(Y)[2] -
1116
+ 1, dim(X)[3]))
1117
+ store[, 1:dim(X)[2], ] = X
1118
+ X = store
1119
+ store = array(0, dim = c(dim(X)[1], time_dim_input +
1120
+ dim(Y)[2] - 1, dim(Y)[3]))
1121
+ store[, time_dim_input:dim(store)[2], ] = Y
1122
+ Y = store
1123
+ }
1124
+ if (dim(X)[2] != dim(Y)[2] && !seq_to_seq_unsync) {
1125
+ stop("The time dimension of X is different from the time dimension of Y. seq_to_seq_unsync is set to FALSE")
1126
+ }
1127
+ if (dim(X)[1] != dim(Y)[1]) {
1128
+ stop("The sample dimension of X is different from the sample dimension of Y.")
1129
+ }
1130
+ if (is.null(model)) {
1131
+ model = list(...)
1132
+ model$input_dim = dim(X)[3]
1133
+ model$hidden_dim = hidden_dim
1134
+ model$output_dim = dim(Y)[3]
1135
+ model$synapse_dim = c(model$input_dim, model$hidden_dim,
1136
+ model$output_dim)
1137
+ model$time_dim = dim(X)[2]
1138
+ model$sigmoid = sigmoid
1139
+ model$network_type = network_type
1140
+ model$numepochs = numepochs
1141
+ model$batch_size = batch_size
1142
+ model$learningrate = learningrate
1143
+ model$learningrate_decay = learningrate_decay
1144
+ model$momentum = momentum
1145
+ model$update_rule = update_rule
1146
+ model$use_bias = use_bias
1147
+ model$seq_to_seq_unsync = seq_to_seq_unsync
1148
+ model$epoch_function = epoch_function
1149
+ model$loss_function = loss_function
1150
+ model$last_layer_error = Y * 0
1151
+ model$last_layer_delta = Y * 0
1152
+ if ("epoch_model_function" %in% names(model)) {
1153
+ stop("epoch_model_function is not used anymore, use epoch_function and return the model inside.")
1154
+ }
1155
+ if (seq_to_seq_unsync) {
1156
+ model$time_dim_input = time_dim_input
1157
+ }
1158
+ if (model$update_rule == "adagrad") {
1159
+ message("adagrad update, loss function not used and momentum set to 0")
1160
+ model$momentum = 0
1161
+ }
1162
+ model <- init_r(model)
1163
+ model$error <- array(0, dim = c(dim(Y)[1], model$numepochs))
1164
+ }
1165
+ else {
1166
+ message("retraining, all options except X, Y and the model itself are ignored, error are reseted")
1167
+ if (model$input_dim != dim(X)[3]) {
1168
+ stop("input dim changed")
1169
+ }
1170
+ if (model$time_dim != dim(X)[2]) {
1171
+ stop("time dim changed")
1172
+ }
1173
+ if (model$output_dim != dim(Y)[3]) {
1174
+ stop("output dim changed")
1175
+ }
1176
+ if (seq_to_seq_unsync && model$time_dim_input != time_dim_input) {
1177
+ stop("time input dim changed")
1178
+ }
1179
+ model$error <- array(0, dim = c(dim(Y)[1], model$numepochs))
1180
+ }
1181
+ for (epoch in seq(model$numepochs)) {
1182
+ error$error[epoch]<-colMeans(model$error)[model$current_epoch]
1183
+
1184
+ incProgress(1/model$numepochs, detail = paste("Learning Rate:",
1185
+ lr, "Neurons in Recursive Neural Network:",nn, "Iteration:", model$current_epoch,
1186
+ "Error:", colMeans(model$error)[model$current_epoch] ))
1187
+
1188
+
1189
+ model$current_epoch = epoch
1190
+ index = sample(seq(round(dim(Y)[1]/model$batch_size)),
1191
+ dim(Y)[1], replace = T)
1192
+ lj = list()
1193
+ for (i in seq(round(dim(Y)[1]/model$batch_size))) {
1194
+ lj[[i]] = seq(dim(Y)[1])[index == i]
1195
+ }
1196
+ lj[unlist(lapply(lj, length)) < 1] = NULL
1197
+ for (j in lj) {
1198
+ a = X[j, , , drop = F]
1199
+ c = Y[j, , , drop = F]
1200
+ store = predictr(model, a, hidden = T, real_output = F)
1201
+ if (model$network_type == "rnn") {
1202
+ for (i in seq(length(model$synapse_dim) - 1)) {
1203
+ model$store[[i]][j, , ] = store[[i]]
1204
+ }
1205
+ }
1206
+ else if (model$network_type == "lstm" | model$network_type ==
1207
+ "gru") {
1208
+ for (i in seq(length(model$hidden_dim))) {
1209
+ model$store[[i]][j, , , ] = store[[i]]
1210
+ }
1211
+ model$store[[length(model$hidden_dim) + 1]][j,
1212
+ , ] = store[[length(model$hidden_dim) + 1]]
1213
+ }
1214
+ model = backprop_r(model, a, c, j)
1215
+ if (model$update_rule == "sgd") {
1216
+ model = model$loss_function(model)
1217
+ }
1218
+ model = update_r(model)
1219
+ }
1220
+ for (i in model$epoch_function) {
1221
+ model <- i(model)
1222
+ if (!is.list(model)) {
1223
+ stop("one epoch function didn't return the model.")
1224
+ }
1225
+ }
1226
+
1227
+
1228
+
1229
+ }
1230
+ if (colMeans(model$error)[epoch] <= min(colMeans(model$error)[1:epoch])) {
1231
+ model$store_best <- model$store
1232
+ }
1233
+ attr(model, "error") <- colMeans(model$error)
1234
+
1235
+
1236
+ return(model)
1237
+ }
1238
+
1239
+ withProgress(message = 'Training Model:', value = 0, {
1240
+
1241
+
1242
+
1243
+ model <- rnn(X = X.train,
1244
+ Y = y.train,
1245
+ learningrate = lr,
1246
+
1247
+ sigmoid = c("Gompertz"),
1248
+ numepochs = epochD,
1249
+ hidden_dim = nn)
1250
+
1251
+ })
1252
+
1253
+
1254
+ xtest <- df[,1:ncol(df),]
1255
+ xtest<- array(xtest, dim=c(1,ncol(df),28))
1256
+ predicted<-predictr(model, xtest)
1257
+
1258
+ forplot<-as.data.frame(t(predicted))
1259
+ colnames(forplot)<-"predicted"
1260
+
1261
+ forplot$real<-df[1,1:ncol(df),Pred]
1262
+
1263
+ forplot$time<-c(1:nrow(forplot))
1264
+ forplot$date<-Values$Local.time
1265
+
1266
+ Values$Predicted<-(t(predicted)*(max(Values$Open)-min(Values$Open)))+min(Values$Open)
1267
+
1268
+ error$error<-model$error[1,]
1269
+ output$Plot <- renderPlot({
1270
+
1271
+ P<-ggplot(forplot)+
1272
+ geom_line(aes(y=predicted, x=time ), colour="red")+
1273
+ geom_line(aes(y=real, x=time ), colour="blue")+
1274
+ xlim(L,ncol(forplot))+
1275
+ xlab("Time (10M)")+
1276
+ ylab("Relative Price (0-1)")+
1277
+ theme_minimal(base_size = 20)+
1278
+ ggtitle("Predicted Prices")+
1279
+ ylim(0,1)
1280
+
1281
+
1282
+ print(P)
1283
+
1284
+ })
1285
+
1286
+ output$Plot2 <- renderPlot({
1287
+
1288
+ Q<-ggplot(error)+
1289
+ geom_line(aes(y=error, x=Iteration ), colour="red")+
1290
+
1291
+
1292
+ xlab("Epoch")+
1293
+ ylab("Error")+
1294
+ theme_minimal(base_size = 20)+
1295
+ ggtitle("Error/Iteration")
1296
+
1297
+
1298
+ print(Q)
1299
+
1300
+ })
1301
+
1302
+
1303
+
1304
+ output$summary <- renderTable({
1305
+ Values
1306
+ })
1307
+
1308
+
1309
+ })
1310
+
1311
+ output$help <- renderUI({
1312
+
1313
+ HTML(paste(
1314
+ "","This application explores the possibilities of using a recursive neural network (RNN) to predict pseudo-stochastic time series.",
1315
+ "Forex (Foreign Exchange) is a highly dynamic and stochastic market which can be used to benchmark RNN",
1316
+ "The application loads the price series and volumes from 7 different markets and use the interrelations among them to predict the price of currency 10 minutes after the last observation.",
1317
+ "Since the time-frame is 10 minutes the algorithm must analyze the last 3000 time points and find a pattern to predict the forthcoming values.",
1318
+ "","The application uses four parameters:","",
1319
+ "<b>Iterations:</b> Number of times that the dataset is presented to the algorithm. The higher the better but the slower. How new iterations improve the performance can be observed in the Error/Iteration plot",
1320
+ "","<b>Events Used for Training:</b> The number previous events are used to predict the coming events, the higher the better","",
1321
+ "<b>Neurons in the RNN:</b> RNN are special types of Neural Networks so it is possible to adjust the number of neurons in the deep layer, the effect of this number in the performance depends on the dataset","",
1322
+ "<b>Learning Rate:</b> This represents the size of the steps used to optimize the model. Low values are better but slower","",
1323
+ sep = "</br>"
1324
+
1325
+ ))
1326
+
1327
  })
1328
 
1329
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1330
  }
1331
 
1332
+ # Run the application
1333
+ shinyApp(ui = ui, server = server)
1334
+