In this article, I will explain the way you can code a simple RNN that tracks cumulative sums of a sequence

Create Training and Validation Data

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import numpy as np
import re
from sklearn.model_selection import train_test_split
import tensorflow as tf
input_seed = 1234
time_steps = 24
n_samples = 100000
X = np.random.randint(1,30,n_samples*time_steps).reshape(n_samples, time_steps)
Y = np.apply_along_axis(np.cumsum,1,X)
X = X.reshape(X.shape[0],X.shape[1],1)
Y = X.reshape(Y.shape[0],Y.shape[1],1)
np.random.seed(input_seed)
idx     = np.arange(len(X))
np.random.shuffle(idx)
X, Y    = X[idx,:,:], Y[idx,:,:]
X_train, X_valid, Y_train, Y_valid = train_test_split(X,Y,test_size=0.25, random_state = input_seed)

Set up the RNN Model in TensorFlow

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
tf.reset_default_graph()
hidden_units  = 32
tf_X          = tf.placeholder(tf.float32, shape=[None, time_steps, 1])
tf_Y          = tf.placeholder(tf.float32, shape=[None, time_steps, 1])
rnn_cell      = tf.contrib.rnn.OutputProjectionWrapper(tf.contrib.rnn.BasicRNNCell(
                                                        num_units= hidden_units,
                                                        activation=tf.nn.relu),
                                                    output_size = 1)
outputs, states  =tf.nn.dynamic_rnn(rnn_cell, inputs = tf_X,
                                   dtype=tf.float32)

loss = tf.square(outputs - tf_Y) total_loss = tf.reduce_mean(loss) learning_rate = 0.001 optimizer = tf.train.AdamOptimizer(learning_rate= learning_rate).minimize(loss=total_loss) batch_size =1000 n_batches = int(X_train.shape[0]/batch_size) epochs = 20 i = 0

Train the Model

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  for e in range(epochs):
      idx     = np.arange(len(X_train))
      np.random.shuffle(idx)
      X_train, Y_train    = X_train[idx,:,:], Y_train[idx]
      for i in range(n_batches):
          x  = X_train[(i*batch_size):((i+1)*batch_size),:,:]
          y  = Y_train[(i*batch_size):((i+1)*batch_size),:,:]
          _, curr_loss = sess.run([optimizer, total_loss],
                                 feed_dict={tf_X:x, tf_Y:y})
          #print("Epoch:",str(e), "Batch:",str(i), "loss:",str(curr_loss))
      loss_val = sess.run(total_loss, feed_dict={tf_X:X_valid, tf_Y:Y_valid})
      print("Epoch:",str(e), " Loss:", loss_val)

The output from testing validation data is

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
2019-09-03 08:23:52.818186: I tensorflow/core/common_runtime/process_util.cc:69] Creating new thread pool with default inter op setting: 4. Tune using inter_op_parallelism_threads for best performance.
Epoch: 0  Loss: 18.690283
Epoch: 1  Loss: 5.2597303
Epoch: 2  Loss: 2.7423012
Epoch: 3  Loss: 1.7486552
Epoch: 4  Loss: 1.1167356
Epoch: 5  Loss: 0.70697135
Epoch: 6  Loss: 0.4718891
Epoch: 7  Loss: 0.30454996
Epoch: 8  Loss: 0.19087416
Epoch: 9  Loss: 0.11425026
Epoch: 10  Loss: 0.07130065
Epoch: 11  Loss: 0.04788036
Epoch: 12  Loss: 0.037668318
Epoch: 13  Loss: 0.027806947
Epoch: 14  Loss: 0.023091868
Epoch: 15  Loss: 0.02009943
Epoch: 16  Loss: 0.017878532
Epoch: 17  Loss: 0.01727507
Epoch: 18  Loss: 0.015186549
Epoch: 19  Loss: 0.014040182

Hence one can see the with in 20 epochs, the network has learned the pattern