写了一个GRU代码,用来估计上证指数的收盘价,模型训练都没有什么问题,一旦变为model.eval(),所有的输出值都变成一样的了,请大家帮忙看一看究竟是怎么一回事
import pandas as pd
import numpy as np
import torch
from torch import nn, optim
from torch.utils.data import TensorDataset, DataLoader
import matplotlib.pyplot as plt
data_all = pd.read_csv('shangzheng_close.CSV',parse_dates=['date'])
data_all.set_index('date', inplace=True)
data = data_all['close']
# 定义create_sequences函数来创建序列
def create_sequences(data, seq_length):
xs, ys = [], []
for i in range(len(data)-seq_length-1):
x = data[i:(i+seq_length)]
y = data[i+seq_length]
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)
# 设置序列长度为10
seq_length = 10
# 调用create_sequences函数创建序列
X, Y = create_sequences(data, seq_length)
# 转换为PyTorch张量
x_tensor = torch.tensor(X, dtype=torch.float32).unsqueeze(-1)# 添加一个维度以匹配输出形状
y_tensor = torch.tensor(Y, dtype=torch.float32).unsqueeze(-1)
# 划分训练集和测试集
train_size = int(len(x_tensor) * 0.8)
test_size = len(x_tensor) - train_size
train_x, test_x = x_tensor[0:train_size, :], x_tensor[train_size:len(x_tensor), :]
train_y, test_y = y_tensor[0:train_size], y_tensor[train_size:len(y_tensor)]
# 创建数据加载器
batch_size = 1
train_loader = DataLoader(TensorDataset(train_x, train_y), batch_size=batch_size, shuffle=True)
test_loader = DataLoader(TensorDataset(test_x, test_y), batch_size=batch_size, shuffle=False)
class GRUModel(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size):
super(GRUModel, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
out, _ = self.gru(x, h0)
out = self.fc(out[:,-1,:])
return out
input_size = 1 # 一个特征(收盘价)
hidden_size = 150 # 隐藏层大小
num_layers = 1 # GRU层数
output_size = 1 # 输出大小(预测下一个收盘价)
model = GRUModel(input_size, hidden_size, num_layers, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.1)
num_epochs = 10
train_losses = []
test_losses = []
for epoch in range(num_epochs):
model.train()
running_loss = 0.0
outputs = []
for i, (inputs, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(inputs)
#print(f'60 time-step estimate [{outputs}], real: {labels}')
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
# 计算每个epoch的平均训练损失
train_loss = running_loss / len(train_loader)
train_losses.append(train_loss)
# 在每个epoch结束后评估模型
model.eval()
with torch.no_grad():
total_test_loss = 0.0
for inputs, labels in test_loader:
outputs = model(inputs)
print(f'60 time-step estimate [{outputs}], real: {inputs}')
loss = criterion(outputs, labels)
total_test_loss += loss.item()
avg_test_loss = total_test_loss / len(test_loader)
test_losses.append(avg_test_loss)
if (epoch + 1) % 5 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {train_loss}')