
循环神经网络(RNN)示例代码
正弦函数数据:使用正弦函数 y = sin(x) 生成序列数据,作为目标预测的基准。将数据分成序列块(长度为 seq_length),并构造输入 x_train 和输出 y_train。训练损失可视化:在训练过程中记录每个 epoch 的损失,并绘制损失曲线。预测结果可视化:使用训练好的模型对正弦波后续部分进行预测。通过滑动窗口机制逐步预测整个序列,并绘制真实值与预测值的对比图。输出:损失曲线:观
·
代码功能
正弦函数数据:
使用正弦函数 y = sin(x) 生成序列数据,作为目标预测的基准。
将数据分成序列块(长度为 seq_length),并构造输入 x_train 和输出 y_train。
训练损失可视化:
在训练过程中记录每个 epoch 的损失,并绘制损失曲线。
预测结果可视化:
使用训练好的模型对正弦波后续部分进行预测。
通过滑动窗口机制逐步预测整个序列,并绘制真实值与预测值的对比图。
输出:
损失曲线:
观察损失如何随着训练迭代逐渐下降。
正弦波预测:
蓝色线为真实的正弦波,红色虚线为模型预测值,观察模型对序列的拟合能力。
代码
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import numpy as np
# 定义超参数
input_size = 1 # 输入特征维度
hidden_size = 20 # 隐藏层维度
output_size = 1 # 输出特征维度
seq_length = 10 # 序列长度
num_epochs = 200 # 训练轮数
learning_rate = 0.01
# 定义 RNN 模型
class RNNModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(RNNModel, self).__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) # RNN 层
self.fc = nn.Linear(hidden_size, output_size) # 全连接层
def forward(self, x):
h0 = torch.zeros(1, x.size(0), self.hidden_size) # 初始化隐藏状态
out, _ = self.rnn(x, h0) # RNN 前向传播
out = self.fc(out[:, -1, :]) # 只取最后一个时间步的输出
return out
# 生成正弦函数数据
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
# 创建训练数据(分段序列)
x_train = []
y_train = []
for i in range(len(x) - seq_length):
x_train.append(y[i:i + seq_length])
y_train.append(y[i + seq_length])
x_train = torch.tensor(x_train, dtype=torch.float32).unsqueeze(-1) # 增加特征维度
y_train = torch.tensor(y_train, dtype=torch.float32).unsqueeze(-1)
# 模型实例化
model = RNNModel(input_size, hidden_size, output_size)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 训练模型
losses = []
for epoch in range(num_epochs):
model.train()
outputs = model(x_train)
loss = criterion(outputs, y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
losses.append(loss.item())
if (epoch + 1) % 20 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
# 绘制训练损失
plt.figure(figsize=(10, 5))
plt.plot(losses, label="Training Loss")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training Loss Over Epochs")
plt.legend()
plt.show()
# 测试模型
model.eval()
with torch.no_grad():
test_input = y[:seq_length] # 取初始正弦序列
test_input = torch.tensor(test_input, dtype=torch.float32).unsqueeze(0).unsqueeze(-1) # 调整形状
predictions = []
for _ in range(len(x) - seq_length):
pred = model(test_input)
predictions.append(pred.item())
# 滑动窗口更新输入
pred = pred.unsqueeze(-1) # 确保形状为 [batch_size, 1, 1]
test_input = torch.cat((test_input[:, 1:, :], pred), dim=1)
# 绘制预测结果
plt.figure(figsize=(10, 5))
plt.plot(x, y, label="True Sine Wave", color="blue")
plt.plot(x[seq_length:], predictions, label="Predicted Wave", color="red", linestyle="--")
plt.xlabel("x")
plt.ylabel("y")
plt.title("True vs Predicted Sine Wave")
plt.legend()
plt.show()
更多推荐
所有评论(0)