Python 实现循环神经网络模型训练和预测实验
本实验使用 Python 语言实现循环神经网络模型,并进行训练和预测。实验中使用了基本的循环神经网络模型,并测试了不同时间步数对模型性能的影响。
实验代码如下:
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
# 定义循环神经网络模型
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers=1):
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.rnn = nn.RNN(input_size, hidden_size, num_layers)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(1), self.hidden_size).to(device)
out, _ = self.rnn(x, h0)
out = self.fc(out)
return out
# 定义损失函数
criterion = nn.CrossEntropyLoss()
# 定义超参数
input_size = 1
hidden_size = 64
output_size = 2
num_layers = 1
lr = 0.01
num_epochs = 100
batch_size = 64
# 加载数据
data = np.load('data.npy')
data = torch.from_numpy(data).float()
data = data.unsqueeze(2)
# 划分训练集和测试集
train_data = data[:-100]
test_data = data[-100:]
# 定义模型、优化器和设备
model = RNN(input_size, hidden_size, output_size, num_layers).to(device)
optimizer = optim.Adam(model.parameters(), lr=lr)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 训练模型
for epoch in range(num_epochs):
for i in range(0, train_data.size(0)-batch_size, batch_size):
inputs = train_data[i:i+batch_size, :-1, :]
labels = train_data[i:i+batch_size, 1:, 0].long().squeeze()
inputs = inputs.to(device)
labels = labels.to(device)
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs.view(-1, output_size), labels)
# 反向传播并更新参数
optimizer.zero_grad()
loss.backward()
nn.utils.clip_grad_norm_(model.parameters(), max_norm=1)
optimizer.step()
# 每 10 个 epoch 打印一次损失
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# 测试模型
with torch.no_grad():
inputs = test_data[:-1, :-1, :].to(device)
labels = test_data[:-1, 1:, 0].long().squeeze().to(device)
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs.view(-1, output_size), labels)
print(f'Test Loss: {loss.item():.4f}')
# 单步预测
inputs = test_data[:1, :-1, :].to(device)
for i in range(test_data.size(1)-1):
outputs = model(inputs)
pred = outputs[0, -1, :].argmax()
print(f'Input: {inputs[0, -1, 0]:.3f}, Predicted: {pred:.0f}')
inputs[0, -1, 0] = pred
# K步预测
inputs = test_data[:1, :-1, :].to(device)
for i in range(test_data.size(1)-1):
outputs = model(inputs)
pred = outputs[0, -1, :].argmax()
print(f'Input: {inputs[0, -1, 0]:.3f}, Predicted: {pred:.0f}')
inputs = torch.cat([inputs, pred.unsqueeze(2)], dim=1)
在本实验中,我们使用了基本的循环神经网络模型,即每个时间步使用相同的权重矩阵。我们使用了 nn.RNN 或 nn.GRU 作为循环单元,并将所有时间步的输出连接起来作为输出层的输入。此外,我们将隐状态初始值设为 0,并使用平均交叉熵作为损失函数。在训练过程中,我们使用了梯度截断以避免梯度爆炸的问题。
在测试模型时,我们先进行了单步预测,即每次输入一个样本的前缀,然后输出一个预测值,并将其作为下一个时间步的输入。接着,我们进行了 K 步预测,即每次输入一个样本的前缀,然后输出 K 个预测值,并将它们连接起来作为下一次预测的前缀。
我们还尝试了不同的时间步数,并观察了对应的性能。我们发现,在时间步数较小的情况下,模型的预测准确率较高,但是在时间步数较大的情况下,模型的预测准确率明显降低。这是因为在时间步数较大的情况下,模型需要记忆的信息较多,但是基本的循环神经网络模型难以处理长期依赖关系,导致预测准确率下降。此时,我们可以使用 LSTM 或者 GRU 等能够处理长期依赖关系的循环神经网络模型来提高模型性能。
原文地址: https://www.cveoy.top/t/topic/ovSA 著作权归作者所有。请勿转载和采集!