LSTM模型原理详解及Python实现
深度学习和人工智能领域,处理序列数据,比如时间序列、文本或音频,是一个巨大的挑战。特别是当我们试图捕获数据中的长期模式或依赖关系时。想象一下,如果你正在阅读一篇文章,你可能需要记住文章开始的内容,以便理解结尾的内容。对于传统的神经网络来说,这是很困难的。这就是LSTM,或长短时记忆网络,发挥作用的地方。
LSTM 架构
长短时记忆网络 (LSTM) 是由 Sepp Hochreiter 和 Jürgen Schmidhuber 在 1997 年设计的循环神经网络架构。
LSTM 架构由一个单元组成,即记忆单元(也称为 LSTM 单元)。LSTM 单元由四个前馈神经网络组成。每个神经网络都包括一个输入层和一个输出层。在每个神经网络中,输入神经元都连接到所有输出神经元。因此,LSTM 单元具有四个完全连接的层。
四个前馈神经网络中的三个负责选择信息。它们是遗忘门、输入门和输出门。这三个门用于执行三个典型的记忆管理操作:从记忆中删除信息(遗忘门)、在记忆中插入新信息(输入门)和使用存储在记忆中的信息(输出门)。
第四个神经网络,即候选记忆,用于创建新的候选信息以插入到记忆中。下面是几个重要环节的介绍。
遗忘门 (Forget Gate)
它决定了什么信息应该被遗忘或丢弃。它使用sigmoid激活函数,得到一个0到1之间的数值。这个数值决定了有多少信息会被保留。0表示“丢弃所有信息”,1表示“保留所有信息”。
输入门 (Input Gate)
- 它有两部分。第一部分是sigmoid层,它决定了我们将更新什么 值。第二部分是tanh层,它创建一个新的候选值向量,这个向量可能会被加到状态中。

更新单元状态 (Update Cell State)
这是LSTM的核心部分。首先,我们通过遗忘门丢弃掉不需要的信息,然后加入新的候选值。
输出门 (Output Gate)
它决定了基于单元状态输出什么值。首先,使用sigmoid层决定哪部分状态将输出,然后将单元状态通过tanh函数(得到值在-1到1之间)并乘以sigmoid门的输出,得到我们想要输出的最终预测。
其中, 是sigmoid激活函数, 表示逐元素相乘, 和 是权重和 偏置,分别对应于遗忘门、输入门、更新和输出门。
LSTM的主要优点是能够捕获长时间的依赖关系,避免了传统RNN中的 梯度消失问题。因此,LSTM在许多涉及时间序列和序列预测的任务中都被广泛使用。
代码示例
生成一组时间序列数据。为了简单起见,我们将生成一组基于正弦波的数据,其中包含一些随机噪声。
import numpy as np
import matplotlib.pyplot as plt
# Generate the time steps for the series
time = np.arange(0, 1000)
# Generate a sinusoidal series with some random noise
series = np.sin(0.02 * time) + np.random.normal(size=1000) * 0.2
# Visualize the series
plt.figure(figsize=(10, 6))
plt.plot(series)
plt.title("Generated Time Series Data")
plt.xlabel("Time")
plt.ylabel("Value")
plt.grid(True)
plt.show()
series.shape
使用LSTM模型进行预测.不过我们需要将这个时间序列转换为可以用于训练LSTM模型的形式。在处理时间序列预测问题时,我们通常使用过去的一段时间(例如,过去n个时间步)的信息来预测未来的值我们需要将我们的序列重塑为一个滑动窗口的形式。
具体来说,使用过去20个时间步的信息来预测下一个时间步的值。这意味着我们的输入将是一个形状为20,1的数组(表示过去20个时间步的值),我们的目标将是一个单一的值(表示下一个时间步的值)。为了训练我们的模型,我们需要为序列中的每一个可能的20步窗口生成一个这样的输入/目标对。
def create_dataset(series, window_size):
"""
Convert a series into a dataset of input-output pairs for LSTM.
"""
X, Y = [], []
for i in range(len(series) - window_size):
X.append(series[i:i+window_size])
Y.append(series[i+window_size])
return np.array(X), np.array(Y)
window_size = 20
X, Y = create_dataset(series, window_size)
# Reshaping X to be in the format [samples, time steps, features]
X = np.reshape(X, (X.shape[0], X.shape[1], 1))
X.shape, Y.shape
from keras.models import Sequential
from keras.layers import LSTM, Dense
# Build the LSTM model
model = Sequential()
model.add(LSTM(50, input_shape=(window_size, 1)))
model.add(Dense(1))
# Compile the model
model.compile(optimizer='adam', loss='mse')
model.summary()
预测并绘制对比图象
# Train the model
model.fit(X, Y, epochs=10)
# Predict using the model
predictions = model.predict(X)
# Plot the original data and predictions
plt.plot(series, label='Original Data')
plt.plot(np.arange(20, 1000), predictions, label='Predictions', linestyle='--')
plt.legend()
plt.show()