Lstm
This code reposisotry if to predicit the price of Bitcoin using Long Short Term Memory
#Packages
import time
import warnings
import numpy as np
import pandas as pd
from numpy import newaxis
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
from keras.models import Sequential
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
Using TensorFlow backend.
The default version of TensorFlow in Colab will soon switch to TensorFlow 2.x.
We recommend you upgrade now
or ensure your notebook will continue to use TensorFlow 1.x via the %tensorflow_version 1.x magic:
more info.
url = 'https://raw.githubusercontent.com/lahorekid/crypto/master/btc.csv'
btc = pd.read_csv(url)
btc.head()
| Date | Open | High | Low | Close | Volume | Market Cap | |
|---|---|---|---|---|---|---|---|
| 0 | 28-Apr-13 | 135.30 | 135.98 | 132.10 | 134.21 | - | 1,500,520,000 |
| 1 | 29-Apr-13 | 134.44 | 147.49 | 134.00 | 144.54 | - | 1,491,160,000 |
| 2 | 30-Apr-13 | 144.00 | 146.93 | 134.05 | 139.00 | - | 1,597,780,000 |
| 3 | 1-May-13 | 139.00 | 139.89 | 107.72 | 116.99 | - | 1,542,820,000 |
| 4 | 2-May-13 | 116.38 | 125.60 | 92.28 | 105.21 | - | 1,292,190,000 |
data_to_use = btc['Close'].values
#Scaling data
scaler = StandardScaler()
scaled_data = scaler.fit_transform(data_to_use.reshape(-1, 1))
#Plot
plt.figure(figsize=(12,7), frameon=False, facecolor='brown', edgecolor='blue')
plt.title('Scaled Bitcoin closing price from April 2013 to November 2017')
plt.xlabel('Days')
plt.ylabel('Scaled value of Bitcoin')
plt.plot(scaled_data, label='Bitcoin data')
plt.legend()
plt.show()

def window_data(data, window_size):
X = []
y = []
i = 0
while (i + window_size) <= len(data) - 1:
X.append(data[i:i+window_size])
y.append(data[i+window_size])
i += 1
assert len(X) == len(y)
return X, y
X, y = window_data(scaled_data, 7)
X_train = np.array(X[:1000])
y_train = np.array(y[:1000])
X_test = np.array(X[1000:])
y_test = np.array(y[1000:])
print("X_train size: {}".format(X_train.shape))
print("y_train size: {}".format(y_train.shape))
print("X_test size: {}".format(X_test.shape))
print("y_test size: {}".format(y_test.shape))
X_train size: (1000, 7, 1)
y_train size: (1000, 1)
X_test size: (648, 7, 1)
y_test size: (648, 1)
#Hyperparameters used in the network
batch_size = 7 #how many windows of data we are passing at once
window_size = 7 #how big window_size is (Or How many days do we consider to predict next point in the sequence)
hidden_layer = 256 #How many units do we use in LSTM cell
clip_margin = 4 #To prevent exploding gradient, we use clipper to clip gradients below -margin or above this margin
learning_rate = 0.001
epochs = 200
inputs = tf.placeholder(tf.float32, [batch_size, window_size, 1])
targets = tf.placeholder(tf.float32, [batch_size, 1])
# LSTM weights
#Weights for the input gate
weights_input_gate = tf.Variable(tf.truncated_normal([1, hidden_layer], stddev=0.05))
weights_input_hidden = tf.Variable(tf.truncated_normal([hidden_layer, hidden_layer], stddev=0.05))
bias_input = tf.Variable(tf.zeros([hidden_layer]))
#weights for the forgot gate
weights_forget_gate = tf.Variable(tf.truncated_normal([1, hidden_layer], stddev=0.05))
weights_forget_hidden = tf.Variable(tf.truncated_normal([hidden_layer, hidden_layer], stddev=0.05))
bias_forget = tf.Variable(tf.zeros([hidden_layer]))
#weights for the output gate
weights_output_gate = tf.Variable(tf.truncated_normal([1, hidden_layer], stddev=0.05))
weights_output_hidden = tf.Variable(tf.truncated_normal([hidden_layer, hidden_layer], stddev=0.05))
bias_output = tf.Variable(tf.zeros([hidden_layer]))
#weights for the memory cell
weights_memory_cell = tf.Variable(tf.truncated_normal([1, hidden_layer], stddev=0.05))
weights_memory_cell_hidden = tf.Variable(tf.truncated_normal([hidden_layer, hidden_layer], stddev=0.05))
bias_memory_cell = tf.Variable(tf.zeros([hidden_layer]))
## Output layer weigts
weights_output = tf.Variable(tf.truncated_normal([hidden_layer, 1], stddev=0.05))
bias_output_layer = tf.Variable(tf.zeros([1]))
def LSTM_cell(input, output, state):
input_gate = tf.sigmoid(tf.matmul(input, weights_input_gate) + tf.matmul(output, weights_input_hidden) + bias_input)
forget_gate = tf.sigmoid(tf.matmul(input, weights_forget_gate) + tf.matmul(output, weights_forget_hidden) + bias_forget)
output_gate = tf.sigmoid(tf.matmul(input, weights_output_gate) + tf.matmul(output, weights_output_hidden) + bias_output)
memory_cell = tf.tanh(tf.matmul(input, weights_memory_cell) + tf.matmul(output, weights_memory_cell_hidden) + bias_memory_cell)
state = state * forget_gate + input_gate * memory_cell
output = output_gate * tf.tanh(state)
return state, output
outputs = []
for i in range(batch_size): #Iterates through every window in the batch
#for each batch I am creating batch_state as all zeros and output for that window which is all zeros at the beginning as well.
batch_state = np.zeros([1, hidden_layer], dtype=np.float32)
batch_output = np.zeros([1, hidden_layer], dtype=np.float32)
#for each point in the window we are feeding that into LSTM to get next output
for ii in range(window_size):
batch_state, batch_output = LSTM_cell(tf.reshape(inputs[i][ii], (-1, 1)), batch_state, batch_output)
#last output is conisdered and used to get a prediction
outputs.append(tf.matmul(batch_output, weights_output) + bias_output_layer)
outputs
losses = []
for i in range(len(outputs)):
losses.append(tf.losses.mean_squared_error(tf.reshape(targets[i], (-1, 1)), outputs[i]))
loss = tf.reduce_mean(losses)
gradients = tf.gradients(loss, tf.trainable_variables())
clipped, _ = tf.clip_by_global_norm(gradients, clip_margin)
optimizer = tf.train.AdamOptimizer(learning_rate)
trained_optimizer = optimizer.apply_gradients(zip(gradients, tf.trainable_variables()))
session = tf.Session()
session.run(tf.global_variables_initializer())
for i in range(epochs):
traind_scores = []
ii = 0
epoch_loss = []
while(ii + batch_size) <= len(X_train):
X_batch = X_train[ii:ii+batch_size]
y_batch = y_train[ii:ii+batch_size]
o, c, _ = session.run([outputs, loss, trained_optimizer], feed_dict={inputs:X_batch, targets:y_batch})
epoch_loss.append(c)
traind_scores.append(o)
ii += batch_size
if (i % 30) == 0:
print('Epoch {}/{}'.format(i, epochs), ' Current loss: {}'.format(np.mean(epoch_loss)))
sup =[]
for i in range(len(traind_scores)):
for j in range(len(traind_scores[i])):
sup.append(traind_scores[i][j][0])
tests = []
i = 0
while i+batch_size <= len(X_test):
o = session.run([outputs], feed_dict={inputs:X_test[i:i+batch_size]})
i += batch_size
tests.append(o)
tests_new = []
for i in range(len(tests)):
for j in range(len(tests[i][0])):
tests_new.append(tests[i][0][j])
test_results = []
for i in range(1640):
if i >= 1000:
test_results.append(tests_new[i-1000])
else:
test_results.append(None)
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/losses/losses_impl.py:121: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where
Epoch 0/200 Current loss: 0.023934917524456978
Epoch 30/200 Current loss: 0.001430075615644455
Epoch 60/200 Current loss: 0.0006088022491894662
Epoch 90/200 Current loss: 0.0007689392077736557
Epoch 120/200 Current loss: 0.0004893745644949377
Epoch 150/200 Current loss: 0.00046395210665650666
Epoch 180/200 Current loss: 0.0005062734708189964
#Plotting predictions from the network
plt.figure(figsize=(16, 7))
plt.plot(scaled_data, label='Original data')
plt.plot(sup, label='Training data')
plt.plot(test_results, label='Testing data')
plt.legend()
plt.show()
