There is a time series international-airline-passengers.csv, How do you use it? RNN To predict ? This paper elaborates on it in detail .

This time series consists of 144 that 's ok , The amount of data is small , But use it to learn RNN It's enough to use it .

use RNN The overall idea of forecasting time series is as follows :

Take the second column of the time series (international-airline-passengers.csv The first column of data is time , Not used in this program ), Because the second column values are quite different , So this paper uses the “( Original value - average value )/ standard deviation ” The data were standardized by using the method of , front 80% The training set is based on the selected data train_x, after 20% As the test set test_x.
* set up RNN Parameters of :input_dim=1,seq_size=5,hidden_dim=100
The labels of training set and test set are marked as train_y,test_y,train_x and train_y The value of is staggered by one unit ,test_x and test_y The value of is also staggered by one unit , Easy to calculate cost value
* RNN Output of the model out by 5 A one-dimensional array of values
Implementation procedure

read CSV file , Data standardization
import csv import numpy as np import matplotlib.pyplot as plt def
load_series(filename, series_idx=1): try: with open(filename) as csvfile:
csvreader = csv.reader(csvfile) data = [float(row[series_idx]) for row in
csvreader if len(row) > 0] #
Data standardization , Can make the data floating difference is not so big , Make the prediction result more accurate .np.mean Averaging ,np.std Seeking standard deviation . normalized_data = (data -
np.mean(data)) / np.std(data) return normalized_data except IOError: return
None # Cut the data into 80% Training set ,20% Test set def split_data(data, percent_train=0.80): num_rows =
len(data) train_data, test_data = [], [] for idx, row in enumerate(data): if
idx < num_rows * percent_train: train_data.append(row) else:
test_data.append(row) return train_data, test_data if __name__ == '__main__':
timeseries = load_series('international-airline-passengers.csv')
print(np.shape(timeseries)) plt.figure() plt.plot(timeseries)
144 Display results of data :

model training
import numpy as np import tensorflow as tf from tensorflow.contrib import rnn
import data_loader import matplotlib.pyplot as plt class SeriesPredictor: def
__init__(self, input_dim, seq_size, hidden_dim): # Hyperparameters
self.input_dim = input_dim self.seq_size = seq_size self.hidden_dim =
hidden_dim # Weight variables and input placeholders self.W_out =
tf.Variable(tf.random_normal([hidden_dim, 1]), name='W_out') self.b_out =
tf.Variable(tf.random_normal([1]), name='b_out') self.x =
tf.placeholder(tf.float32, [None, seq_size, input_dim]) # 5 Here's a little clip , yes 5 Forecast value self.y =
tf.placeholder(tf.float32, [None, seq_size]) # Cost optimizer self.cost =
tf.reduce_mean(tf.square(self.model() - self.y)) self.train_op =
tf.train.AdamOptimizer(learning_rate=0.01).minimize(self.cost) # Auxiliary ops
self.saver = tf.train.Saver() def model(self): """ :param x: inputs of size [T,
batch_size, input_size] :param W: matrix of fully-connected output layer
weights :param b: vector of fully-connected output layer biases """ cell =
rnn.BasicLSTMCell(self.hidden_dim) outputs, states = tf.nn.dynamic_rnn(cell,
self.x, dtype=tf.float32) num_examples = tf.shape(self.x)[0] W_repeated =
tf.tile(tf.expand_dims(self.W_out, 0), [num_examples, 1, 1]) out =
tf.matmul(outputs, W_repeated) + self.b_out out = tf.squeeze(out) # The return length is 5 One dimensional array of
return out def train(self, train_x, train_y, test_x, test_y): with tf.Session()
as sess: tf.get_variable_scope().reuse_variables() max_patience = 3 patience =
max_patience # minimum err Specified as infinite min_test_err = float('inf') step = 0 #
test_err appear 3 The first float stops while patience > 0: _, train_err =[self.train_op,
self.cost], feed_dict={self.x: train_x, self.y: train_y}) if step % 100 == 0:
test_err =, feed_dict={self.x: test_x, self.y: test_y})
print('step:{}\t\ttrain err:{}\t\ttest err:{}'.format(step, train_err,
test_err)) if test_err < min_test_err: min_test_err = test_err patience =
max_patience else: patience -= 1 step += 1 save_path =,
'./model/') print('Model saved to {}'.format(save_path)) def test(self, sess,
test_x): tf.get_variable_scope().reuse_variables() self.saver.restore(sess,
'./model/') output =, feed_dict={self.x: test_x}) return
output def plot_results(train_x, predictions, actual, filename): plt.figure()
num_train = len(train_x) # Training set .plt.plot(x,y,format_string,**kwargs) x Axis data ,y Axis data
plt.plot(list(range(num_train)), train_x, color='b', label='training data') #
Prediction set plt.plot(list(range(num_train, num_train + len(predictions))), predictions,
color='r', label='predicted') # True value plt.plot(list(range(num_train, num_train +
len(actual))), actual, color='g', label='test_data') # Add legend plt.legend() if
filename is not None: plt.savefig(filename) else: if __name__ ==
'__main__': # Sequence length , To predict the next value based on a small fragment seq_size = 5 predictor =
SeriesPredictor(input_dim=1, seq_size=seq_size, hidden_dim=100) data =
data_loader.load_series('international-airline-passengers.csv') # Data segmentation into training sets , Test set
train_data, actual_vals = data_loader.split_data(data) train_x, train_y = [],
[] for i in range(len(train_data) - seq_size - 1): # Training data and tags are staggered 1 Units
train_x.append(np.expand_dims(train_data[i:i + seq_size], axis=1).tolist())
train_y.append(train_data[i + 1: i + seq_size + 1]) test_x, test_y = [], [] for
i in range(len(actual_vals) - seq_size - 1):
test_x.append(np.expand_dims(actual_vals[i:i + seq_size], axis=1).tolist())
test_y.append(actual_vals[i + 1: i + seq_size + 1]) predictor.train(train_x,
train_y, test_x, test_y) with tf.Session() as sess: # [:, 0] Why 0 What about it ? It shouldn't be -1 What ? #
1, Use the trained model './model/' forecast , So the first value is also predicted based on the previous sequence . # 2, When drawing the value and comparing the value, it has the reality . predicted_vals
= predictor.test(sess, test_x)[:, 0] print('predicted_vals',
np.shape(predicted_vals)) plot_results(train_data, predicted_vals, actual_vals,
'predictions.png') # Take out the end of the training set 5 Data prev_seq = train_x[-1] predicted_vals = [] for
i in range(20): next_seq = predictor.test(sess, [prev_seq]) #
Take the predicted result as the current result value , Continue to forecast . predicted_vals.append(next_seq[-1]) #
np.vstack: In vertical direction ( Line order ) Stacked arrays form a new array ;np.hstack: In horizontal direction ( Column order ) Stacked arrays form a new array #
prev_seq[1:] Take the second to fifth data , altogether 4 Data prev_seq = np.vstack((prev_seq[1:], next_seq[-1]))
plot_results(train_data, predicted_vals, actual_vals, 'hallucinations.png')
Running results :
step:0 train err:1.8898743391036987 test err:2.7799108028411865 step:100 train
err:0.04205527901649475 test err:0.2253977209329605 step:200 train
err:0.039602071046829224 test err:0.28264862298965454 step:300 train
err:0.03779347985982895 test err:0.2434949427843094 step:400 train
err:0.03636837378144264 test err:0.2533899247646332 Model saved to ./model/
predicted_vals (22,)


There are about three ways to stop iteration :

* Precision is greater than a certain threshold, stop . example :acc>=0.98 Stop ;
* test err There are several floats and stops ;
* The number of iterations reached XXX Stop for the first time .
This paper adopts the second method .