长短时记忆网络( Long short-term memory,LSTM )是RNN的一种,可以解决RNN短时记忆的不足,当一条序列足够长,那RNN将很难将信息从较早的时间步传送到后面的时间步,而LSTM能学习长期依赖的信息,记住较早时间步的信息。
LSTM是一种循环神经网络 (Recurrent neural network, RNN)的特殊变体,具有“门”结构,通过门单元的逻辑控制决定数据是否更新或是选择丢弃,克服了 RNN 权重影响过大、容易产生梯度消失和爆炸的缺点,使网络可以更好、更快地收敛,能够有效提高预测精度。
LSTM的参数训练算法,依然是反向传播算法。主要有如下三个步骤:
第一步:前向计算每个神经元的输出值。对于LSTM而言,依据前面介绍的算法,分别进行计算。
第二步:确定优化目标函数。在训练早期,输出值和预期值会不一致,于是计算每个神经元的误差项值,构造出损失函数。
第三步:根据损失函数的梯度指引,更新网络权值参数。与传统RNN类似,LSTM误差项的反向传播包括两个层面:一个是空间上层面的,将误差项向网络的上一层传播。另一个是时间层面上的,沿时间反向传播,即从当前t时刻开始,计算每个时刻的误差。
然后跳转第一步,重复做第一、二和三步,直至网络误差小于给定值。
LSTM结构详解:
LSTM实现了三个门计算,即遗忘门、输入门和输出门,用来保护和控制细胞状态。
LSTM网络能通过一种被称为门的结构对细胞状态进行删除或者添加信息。门能够有选择性的决定让哪些信息通过。门的结构为一个sigmoid层和一个点乘操作的组合,sigmoid层输出0到1之间的数,描述每个部分有多少量可以通过,0代表不允许任何量通过,1表示允许任何量通过。
LSTM 拥有三个门, 分别为遗忘门、输入门、输出门,以此决定每一时刻信息记忆与遗忘。输入门决定有多少新的信息加入到细胞当中,遗忘门控制每一时刻信息是否会被遗忘,输出门决定每一时刻是否有信息输出。
LSTM实例:
拟合一个LSTM网络,训练数据:
# 每个4位序列中,第1位作为x,后3位作为预测值y
X, y = train[:, 0:n_lag], train[:, n_lag:]
# 重构训练数据结构->[samples, timesteps, features]->[22,1,1]
X = X.reshape(X.shape[0], 1, X.shape[1])
print(X)
print(y)
# 网络结构
model = Sequential()
# 一个神经元, batch_input_shape(1,1,1),传递序列状态
model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]),
stateful=True))
model.add(Dense(y.shape[1]))
model.compile(loss='mean_squared_error', optimizer='adam')
# 开始训练
for i in range(nb_epoch):
# 数据训练1次,每次训练1组数据,不混淆序列顺序
model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False)
# 每次训练完初始化网络状态(不是权重)
model.reset_states()
用模型进行预测:
forecasts = list()
# 对X值进行逐个预测
for i in range(len(test)):
# X, y = test[i, 0:n_lag], test[i, n_lag:]
X = test[i, 0:n_lag]
# LSTM 单步预测
forecast = forecast_lstm(model, X, n_batch)
# 存储预测数据
forecasts.append(forecast)
对预测后的数据逆转换:
inverted = list()
for i in range(len(forecasts)):
# create array from forecast
forecast = array(forecasts[i])
forecast = forecast.reshape(1, len(forecast))
# 数据逆缩放
inv_scale = scaler.inverse_transform(forecast)
inv_scale = inv_scale[0, :]
# 数据逆差分
index = len(series) - n_test + i - 1
last_ob = series.values[index]
inv_diff = inverse_difference(last_ob, inv_scale)
# 存储转换后的数据
inverted.append(inv_diff)
参考文章:
LSTM介绍_马铃大番薯的博客-CSDN博客
点个赞关个注叭