Skip to content

Keras - Time Series Prediction using LSTM RNN

Keras - 使用 LSTM 进行时间序列预测

Section titled “Keras - 使用 LSTM 进行时间序列预测”

循环神经网络(RNNs),特别是长短期记忆(LSTM)网络,非常适合处理涉及序列数据的任务,在这些任务中信息的顺序很重要。时间序列预测(基于过去值预测未来值)和自然语言处理(理解文本)是常见的应用。

在本章中,我们将使用 tf.keras 构建一个简单的基于 LSTM 的模型,对 IMDB 电影评论执行情感分析。情感分析是一种分类任务:判断一段文本是表达积极还是消极的观点。虽然文本并非严格意义上的“时间”序列,但它是一个序列,其中单词的顺序对意义至关重要。

为什么序列任务使用 LSTM?LSTM 具有内部机制(门),允许它们在长序列上有选择地记住或遗忘信息,克服了简单 RNN 在捕获长距离依赖方面的局限性。

序列分类的概念模型:

输入序列(例如评论中的单词)-> Embedding 层(将单词映射到密集向量)-> LSTM 层(处理序列,捕获上下文)-> Dense 输出层(分类情感)。

模型规格:

  • 数据集: IMDB 电影评论(由 tf.keras.datasets 提供)。
  • 预处理: 限制词汇量大小(例如,前 20,000 个单词),将序列填充到固定长度(例如,80 个单词)。
  • 输入层: Embedding 层将整数单词索引转换为密集向量(例如,128 维度)。
  • 循环层: LSTM 层(例如,128 个单元)处理嵌入序列。包括 dropout 用于正则化。
  • 输出层: 具有 1 个单元和 ‘sigmoid’ 激活的 Dense 层,用于二分类(积极/消极)。
  • 编译: binary_crossentropy 损失,Adam 优化器,accuracy 指标。
  • 训练: 使用合适的批次大小和轮次数量。
import tensorflow as tf
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, LSTM # Changed import
from tensorflow.keras.datasets import imdb
import numpy as np
max_features = 20000 # Vocabulary size (consider only top N words)
maxlen = 80 # Max sequence length (cut texts after this number of words)
batch_size = 32
embedding_dims = 128
lstm_units = 128
print('Loading data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')

imdb.load_data 函数返回单词索引的序列(整数)。

RNN 需要输入序列长度一致。我们使用 pad_sequences 来截断较长的评论或用一个特殊值(通常是 0)填充较短的评论,使其达到 maxlen。

print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)

形状现在将是 (样本数, maxlen)。

print('Build model...')
model = Sequential()
# Input Embedding Layer
model.add(Embedding(max_features, embedding_dims, input_length=maxlen))
# LSTM Layer
# Note: 'dropout' applies to input, 'recurrent_dropout' to recurrent state (can be computationally expensive on GPU)
model.add(LSTM(lstm_units, dropout=0.2, recurrent_dropout=0.2))
# Output Classification Layer
model.add(Dense(1, activation='sigmoid'))
model.summary() # Print model architecture

Embedding 层将每个单词索引映射到一个密集向量。LSTM 层依次处理这些向量的序列。最后的 Dense 层输出单个概率。

配置学习过程。

model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])

在训练数据上拟合模型。我们将使用测试集作为验证数据,以便在训练期间监控性能。

print('Train...')
epochs = 5 # Reduced epochs for faster demonstration
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(x_test, y_test))

训练输出将显示每个轮次在训练集和验证集上的损失和准确率。监控 val_accuracy 和 val_loss 以判断是否出现过拟合迹象(训练性能提高但验证性能停滞或下降)。

0.8528
# Example Output Snippet (actual values will vary):
# Epoch 1/5
# Epoch 2/5
# 782/782 [==============================] - 85s 109ms/step - loss: 0.2218 - accuracy: 0.9134 - val_loss: 0.3636 - val_accuracy: 0.8430
# ... (subsequent epochs)

评估在测试集上的最终性能。

score, acc = model.evaluate(x_test, y_test,
batch_size=batch_size)
print('Test score:', score)
print('Test accuracy:', acc)

这提供了在未见过的数据上的最终评估指标。

  • 超参数调优: 尝试不同的 embedding_dims、lstm_units、dropout 率、maxlen、优化器学习率等。
  • 双向 LSTM: 在前向和后向两个方向处理序列(tf.keras.layers.Bidirectional(LSTM(...)))),通常通过捕获来自过去和未来的上下文来提高性能。
  • 堆叠 LSTM: 使用多个 LSTM 层(除最后一个 LSTM 外,其他层使用 return_sequences=True)。
  • 其他架构: 探索 GRU (tf.keras.layers.GRU) 或基于 Transformer 的模型用于序列任务。