用pytorch完成下列三个问题,并给出代码:(1) 生成时序数据:使用正弦函数和一些高斯噪声来生成序列数据。时间步为 1,2,… ,500;高斯噪声均值为 0,标准差为 0.1; (2) 以前 400 个时间点为训练数据,对后 100 个时间点进行单步预测,并绘制训练值与 真实值对比图; (3) 以前 400 个时间点为训练数据,对后面的时间点进行多步预测,并绘制训练值与 真实值对比图。
时间: 2024-03-16 08:46:53 浏览: 20
好的,以下是代码实现:
(1) 生成时序数据
```python
import numpy as np
import matplotlib.pyplot as plt
# 生成时序数据
def generate_data():
# 时间步为 1,2,… ,500
x = np.arange(0, 500, 0.1)
# 正弦函数
y = np.sin(x)
# 添加高斯噪声
y += 0.1 * np.random.randn(len(x))
return y
# 绘制时序数据
data = generate_data()
plt.plot(data)
plt.show()
```
(2) 单步预测
```python
import torch
import torch.nn as nn
# 构建数据集
def create_dataset(data, look_back=1):
dataX, dataY = [], []
for i in range(len(data)-look_back-1):
a = data[i:(i+look_back)]
dataX.append(a)
dataY.append(data[i+look_back])
return torch.Tensor(dataX), torch.Tensor(dataY)
# 构建简单的RNN模型
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, num_layers=1, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(1, x.size(0), self.hidden_size).to(device)
out, _ = self.rnn(x, h0)
out = self.fc(out[:, -1, :])
return out
# 训练模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
look_back = 400
train_data = data[:look_back]
test_data = data[look_back:]
trainX, trainY = create_dataset(train_data)
testX, testY = create_dataset(test_data)
model = RNN(1, 32, 1).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(100):
optimizer.zero_grad()
outputs = model(trainX.to(device))
loss = criterion(outputs, trainY.to(device))
loss.backward()
optimizer.step()
if epoch % 10 == 0:
print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, 100, loss.item()))
# 单步预测
model.eval()
test_predict = []
input_data = train_data[-look_back:]
for i in range(len(test_data)):
input_tensor = torch.Tensor(input_data).reshape(1, -1, 1).to(device)
output = model(input_tensor)
test_predict.append(output.cpu().detach().numpy()[0][0])
input_data = np.concatenate((input_data[1:], output.cpu().detach().numpy()[0]))
# 绘制单步预测结果
plt.plot(testY, label='True Data')
plt.plot(test_predict, label='Predicted Data')
plt.legend()
plt.show()
```
(3) 多步预测
```python
# 构建多步预测数据集
def create_dataset_multi(data, look_back=1, look_forward=1):
dataX, dataY = [], []
for i in range(len(data)-look_back-look_forward):
a = data[i:(i+look_back)]
dataX.append(a)
dataY.append(data[(i+look_back):(i+look_back+look_forward)])
return torch.Tensor(dataX), torch.Tensor(dataY)
# 构建多步预测的RNN模型
class RNNMulti(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(RNNMulti, self).__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, num_layers=1, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(1, x.size(0), self.hidden_size).to(device)
out, _ = self.rnn(x, h0)
out = self.fc(out[:, -1, :])
return out
# 训练多步预测的模型
look_forward = 50
trainX_multi, trainY_multi = create_dataset_multi(train_data, look_back, look_forward)
testX_multi, testY_multi = create_dataset_multi(test_data, look_back, look_forward)
model_multi = RNNMulti(1, 32, look_forward).to(device)
criterion_multi = nn.MSELoss()
optimizer_multi = torch.optim.Adam(model_multi.parameters(), lr=0.001)
for epoch in range(100):
optimizer_multi.zero_grad()
outputs_multi = model_multi(trainX_multi.to(device))
loss_multi = criterion_multi(outputs_multi, trainY_multi.to(device))
loss_multi.backward()
optimizer_multi.step()
if epoch % 10 == 0:
print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, 100, loss_multi.item()))
# 多步预测
model_multi.eval()
test_predict_multi = []
input_data_multi = train_data[-look_back:]
for i in range(len(test_data)):
input_tensor_multi = torch.Tensor(input_data_multi).reshape(1, -1, 1).to(device)
output_multi = model_multi(input_tensor_multi)
test_predict_multi.append(output_multi.cpu().detach().numpy()[0])
input_data_multi = np.concatenate((input_data_multi[1:], output_multi.cpu().detach().numpy()[0]))
# 绘制多步预测结果
plt.plot(testY_multi[:, 0], label='True Data')
plt.plot(test_predict_multi[:, 0], label='Predicted Data')
plt.legend()
plt.show()
```