1. Descripción general de RNN
Redes Neuronales Recurrentes (RNN) Redes Neuronales Recurrentes.
Las redes neuronales tradicionales no pueden recordar interacciones pasadas, RNN resuelve este problema. Son redes con bucles que permiten que la información persista. Como se muestra en la figura a continuación, Xt se ingresa al nodo A de la red neuronal y se emite un valor Ht. Los bucles en una red permiten que la información pase de un paso de la red al siguiente.
2. Aplicación sencilla de RNN
1 、 RNN simple
Utilice una implementación RNN simple de Keras para predecir las ventas a partir de conjuntos de datos históricos.
El prototipo de la función Simple RNN es el siguiente:
Un RNN simple es un RNN completamente conectado.
tensorflow.python.keras.layers.SimpleRNN(
units,
activation='tanh',
use_bias=True,
kernel_initializer='glorot_uniform',
recurrent_initializer='orthogonal',
bias_initializer='zeros',
kernel_regularizer=None,
recurrent_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
recurrent_constraint=None,
bias_constraint=None,
dropout=0.,
recurrent_dropout=0.,
return_sequences=False,
return_state=False,
go_backwards=False,
stateful=False,
unroll=False)
2. Conjunto de datos
La primera columna es el mes y la segunda columna son los datos de ventas de cada mes. Data de muestra:
Mes | Ventas de champú en un período de tres años. |
enero 1 | 266 |
2 de enero | 145.9 |
3 de enero | 183.1 |
4 de enero | 119.3 |
5 de enero | 180.3 |
Mirando el gráfico, se puede ver que las ventas son muy volátiles, pero hay una línea de tendencia ascendente.
3. Código de referencia
# load and plot dataset
from pandas import read_csv
from pandas import datetime
from matplotlib import pyplot
import pandas as pd
# 解析时间
def parser(x):
return datetime.strptime('200' + x, '%Y-%m')
series = read_csv('sales-of-shampoo-over-a-three-ye.csv', header=0, parse_dates=[0], index_col=0, squeeze=True,
date_parser=parser)
# summarize first few rows
print(series.head())
# line plot
series.plot()
pyplot.show()
from pandas import DataFrame
from pandas import Series
from pandas import concat
from pandas import read_csv
from pandas import datetime
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import SimpleRNN
#from keras.regularizers import L1L2
from math import sqrt
import matplotlib
# be able to save images on server
matplotlib.use('Agg')
from matplotlib import pyplot
import numpy
# frame a sequence as a supervised learning problem
def timeseries_to_supervised(data, lag=1):
df = DataFrame(data)
columns = [df.shift(i) for i in range(1, lag + 1)]
columns.append(df)
df = concat(columns, axis=1)
return df
# create a differenced series
def difference(dataset, interval=1):
diff = list()
for i in range(interval, len(dataset)):
value = dataset[i] - dataset[i - interval]
diff.append(value)
return Series(diff)
# invert differenced value
def inverse_difference(history, yhat, interval=1):
return yhat + history[-interval]
# scale train and test data to [-1, 1]
def scale(train, test):
# fit scaler
scaler = MinMaxScaler(feature_range=(-1, 1))
scaler = scaler.fit(train)
# transform train
train = train.reshape(train.shape[0], train.shape[1])
train_scaled = scaler.transform(train)
# transform test
test = test.reshape(test.shape[0], test.shape[1])
test_scaled = scaler.transform(test)
return scaler, train_scaled, test_scaled
# inverse scaling for a forecasted value
def invert_scale(scaler, X, yhat):
new_row = [x for x in X] + [yhat]
array = numpy.array(new_row)
array = array.reshape(1, len(array))
inverted = scaler.inverse_transform(array)
return inverted[0, -1]
# fit an LSTM network to training data
def fit_rnn(train, n_batch, nb_epoch, n_neurons):
X, y = train[:, 0:-1], train[:, -1]
X = X.reshape(X.shape[0], 1, X.shape[1])
model = Sequential()
model.add(SimpleRNN(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
for i in range(nb_epoch):
model.fit(X, y, epochs=1, batch_size=n_batch, verbose=1, shuffle=False)
model.reset_states()
return model
# run a repeated experiment
def run_rnn(series, n_lag, n_repeats, n_epochs, n_batch, n_neurons):
# transform data to be stationary
raw_values = series.values
diff_values = difference(raw_values, 1)
# transform data to be supervised learning
supervised = timeseries_to_supervised(diff_values, n_lag)
supervised_values = supervised.values[n_lag:, :]
# split data into train and test-sets
train, test = supervised_values[0:-12], supervised_values[-12:]
# transform the scale of the data
scaler, train_scaled, test_scaled = scale(train, test)
# run experiment
error_scores = list()
for r in range(n_repeats):
# fit the model
train_trimmed = train_scaled[2:, :]
rnn_model = fit_rnn(train_trimmed, n_batch, n_epochs, n_neurons)
# forecast test dataset
test_reshaped = test_scaled[:, 0:-1]
test_reshaped = test_reshaped.reshape(len(test_reshaped), 1, 1)
output = rnn_model.predict(test_reshaped, batch_size=n_batch)
predictions = list()
for i in range(len(output)):
yhat = output[i, 0]
X = test_scaled[i, 0:-1]
# invert scaling
yhat = invert_scale(scaler, X, yhat)
# invert differencing
yhat = inverse_difference(raw_values, yhat, len(test_scaled) + 1 - i)
# store forecast
predictions.append(yhat)
# report performance
rmse = sqrt(mean_squared_error(raw_values[-12:], predictions))
print('%d) Test RMSE: %.3f' % (r + 1, rmse))
error_scores.append(rmse)
return error_scores
# configure the experiment
def run():
# load dataset
series = read_csv('sales-of-shampoo-over-a-three-ye.csv', header=0, parse_dates=[0], index_col=0, squeeze=True,
date_parser=parser)
# configure the experiment
n_lag = 1
n_repeats = 30
n_epochs = 1000
n_batch = 4
n_neurons = 3
# run the experiment
results = DataFrame()
results['results'] = run_rnn(series, n_lag, n_repeats, n_epochs, n_batch, n_neurons)
results.plot(title="RNN RMSE Iteration")
pyplot.show()
# summarize results
print(results.describe())
# save boxplot
pyplot.savefig('plot_rnn_rmse.png')
# entry point
run()
El ciclo de época debe realizarse manualmente, de modo que al final de cada época, reset_states y elimine el estado interno. Si usa epochs=nb_epoch directamente sin bucle manual, la red restablecerá_states al final de cada lote.
Los resultados del entrenamiento son los siguientes
1) Prueba RMSE: 98.509
2) Prueba RMSE: 96.719
3) Prueba RMSE: 97.397
4) Prueba RMSE: 82.224
5) Prueba RMSE: 77.399
6) Prueba RMSE: 87.999
7) Prueba RMSE: 98.929
8) Prueba RMSE: 105.284
9) Prueba RMSE: 103.274
10) Prueba RMSE: 74.841
11) Prueba RMSE: 95.774
12) Prueba RMSE: 101.559
13) Prueba RMSE: 120.763
14) Prueba RMSE: 95.495
15) Prueba RMSE: 107.296
16) Prueba RMSE1
817.4 : 76.648
18) Prueba RMSE: 83.285
19) Prueba RMSE: 112.248
20) Prueba RMSE: 77.225
21) Prueba RMSE: 96.166
22) Prueba RMSE: 84.767
23) Prueba RMSE: 84.564
24) Prueba RMSE: 92.602
25) Prueba RMSE: 75.713
26) Prueba RMSE: 86.159
27) Prueba RMSE: 101.537
28) Prueba RMSE: 109.397
29) Prueba RMSE: 93.453
30) Prueba RMSE: 99.279
recuento de resultados
30,000000
media 93,432153 estándar
11,782779
mín 74,840867
25 % 84,614619
50 % 95,634082
75 % 100,972315
máx 120,763087
Múltiples resultados de entrenamiento, como puede ver en el gráfico a continuación, el RMSE varía entre 74 y 120 durante las iteraciones, pero se vuelve más estable con el tiempo.