循环神经网络
TensorFlow - 循环神经网络
Section titled “TensorFlow - 循环神经网络”循环神经网络(Recurrent Neural Networks,简称 RNNs)是一类非常适合处理序列数据的神经网络,例如时间序列、文本或语音。与假设输入独立的[前馈神经网络](feedforward neural networks)不同,RNN 具有形成有向循环的连接,这使得它们能够维持一种内部状态或对过去信息的“记忆”。这种记忆使其能够捕获序列数据中的时间依赖性和模式。
RNN 的核心思想是,它对序列中的每个元素执行相同的计算,并且每一步的输出都依赖于之前的计算。它们之所以被称为“循环”(recurrent),是因为它们对序列中的每个元素执行相同的任务,并且输出依赖于先前的计算结果。
训练 RNN 通常涉及以下概念性步骤:
步骤 1:提供数据集中的一个序列(或一批序列,batch of sequences)作为输入。
步骤 2:网络逐个处理序列元素,更新其内部状态(internal state)并在每一步(或在序列末尾)产生输出。初始状态和权重(weights)通常随机初始化。
步骤 3:根据网络的输出计算预测结果。
步骤 4:使用[损失函数](loss function)将预测结果与实际目标值进行比较,生成误差信号。
步骤 5:误差通过时间反向传播(Backpropagation Through Time,简称 BPTT 的算法),并通过网络层反向传播,以调整模型的权重。
步骤 6:重复步骤 1-5 多个[周期](epochs)和批次(batches),直到模型在[验证集](validation set)上的性能令人满意。
步骤 7:训练好的模型可用于对新的、未见过的序列进行预测。
一个简单的 RNN 可以可视化为一个循环。在每个时间步(time step)‘t’,RNN 接收输入 x(t) 和来自前一个时间步的隐藏状态(hidden state)h(t-1),以计算新的隐藏状态 h(t) 和输出 y(t)。在所有时间步中都使用相同的权重集合(U, W, V)。
使用 TensorFlow Keras 实现循环神经网络
Section titled “使用 TensorFlow Keras 实现循环神经网络”我们将演示如何使用 tf.keras 实现一个简单的 RNN 来对手写数字 MNIST 进行分类。虽然 CNNs 通常更适合图像数据,但此示例展示了 RNN 如何通过将其行(或列)视为序列来处理图像。
步骤 1:导入必要的模块并加载数据。
import tensorflow as tffrom tensorflow import kerasfrom tensorflow.keras import layersimport numpy as np
# Load MNIST dataset(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Preprocess data: Normalize pixel valuesx_train = x_train.astype("float32") / 255.0x_test = x_test.astype("float32") / 255.0
# Convert labels to one-hot encoded vectorsnum_classes = 10y_train = keras.utils.to_categorical(y_train, num_classes)y_test = keras.utils.to_categorical(y_test, num_classes)
print(f"x_train shape: {x_train.shape}") # (60000, 28, 28)print(f"y_train shape: {y_train.shape}") # (60000, 10)对于 RNN,我们可以将每张图像(28x28 像素)视为由 28 个时间步组成的序列,其中每个时间步有 28 个特征(features)(即一行的像素值)。
步骤 2:定义 RNN 模型参数并构建模型。
# RNN 参数# 输入图像为 28x28。我们将其视为 28 个时间步,每个时间步有 28 个特征。n_steps = 28 # 时间步数量(图像高度)n_input = 28 # 每个时间步的特征数量(图像宽度)n_hidden = 128 # LSTM 层中的单元数量
model = keras.Sequential([ # LSTM 层:处理行序列 # input_shape 为 (时间步, 每个时间步的特征) layers.LSTM(n_hidden, input_shape=(n_steps, n_input)), # 如有需要,可在此添加 Dropout 进行正则化 # layers.Dropout(0.5), # 用于分类的全连接(Dense)输出层 layers.Dense(num_classes, activation='softmax')])
model.summary()我们使用 LSTM(Long Short-Term Memory,长短期记忆网络)层,它是一种特殊的 RNN 单元,特别擅长捕获长期依赖性并缓解可能影响简单 RNN 的[梯度消失问题](vanishing gradient problem)。LSTM 层的 input_shape 为 (n_steps, n_input)。
步骤 3:编译模型。
learning_rate = 0.001optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])我们使用 Adam 优化器、[分类交叉熵损失](categorical cross-entropy loss,适用于多类别分类)来编译模型,并跟踪准确率(accuracy)。
步骤 4:训练模型。
batch_size = 128training_epochs = 5 # 为快速演示而减少周期数
print("\n正在训练模型...")history = model.fit(x_train, y_train, batch_size=batch_size, epochs=training_epochs, validation_data=(x_test, y_test), verbose=1)
print("\n优化完成!")
# 在测试集上评估模型print("\n正在测试数据上评估模型...")loss, acc = model.evaluate(x_test, y_test, verbose=0)print(f"测试损失: {loss:.6f}")print(f"测试准确率: {acc:.5f}")
# 示例预测if len(x_test) > 0: sample_idx = 0 sample_image = x_test[sample_idx] prediction = model.predict(np.expand_dims(sample_image, axis=0)) predicted_class = np.argmax(prediction[0]) actual_class = np.argmax(y_test[sample_idx]) print(f"样本 {sample_idx} - 预测类别: {predicted_class}, 实际类别: {actual_class}")训练过程将会显示,随后是最终的测试准确率。虽然 LSTMs 可以用这种方式处理图像,但由于 CNNs 更善于高效捕获局部空间模式,它们通常在图像任务中更有效。
预期输出(准确率可能有所不同,特别是周期数较少时):
x_train shape: (60000, 28, 28)y_train shape: (60000, 10)Model: "sequential"_________________________________________________________________ Layer (type) Output Shape Param #================================================================= lstm (LSTM) (None, 128) 80384
dense (Dense) (None, 10) 1290
=================================================================Total params: 81,674Trainable params: 81,674Non-trainable params: 0_________________________________________________________________
Training the model...Epoch 1/5469/469 [==============================] - 7s 11ms/step - loss: 0.7749 - accuracy: 0.7544 - val_loss: 0.2873 - val_accuracy: 0.9136Epoch 2/5469/469 [==============================] - 5s 10ms/step - loss: 0.2228 - accuracy: 0.9335 - val_loss: 0.1629 - val_accuracy: 0.9509Epoch 3/5469/469 [==============================] - 5s 10ms/step - loss: 0.1466 - accuracy: 0.9564 - val_loss: 0.1250 - val_accuracy: 0.9610Epoch 4/5469/469 [==============================] - 5s 10ms/step - loss: 0.1125 - accuracy: 0.9660 - val_loss: 0.1048 - val_accuracy: 0.9667Epoch 5/5469/469 [==============================] - 5s 10ms/step - loss: 0.0914 - accuracy: 0.9726 - val_loss: 0.0938 - val_accuracy: 0.9709
Optimization Finished!
Evaluating model on test data...Test Loss: 0.093812Test Accuracy: 0.97090Sample 0 - Predicted class: 7, Actual class: 7