用pytorch写一个天气预测的代码,用LSTM或CNN,读取天气中的csv文件,由时间和气温两列数据,区分训练集和测试集,用gpu训练,输入为60天的天气,输出为某一天的天气,并画出60天的实际曲线和预测曲线图,注意维度要一致
时间: 2023-10-01 20:06:37 浏览: 135
好的,以下是一个简单的天气预测的代码,使用LSTM模型:
```python
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 读取csv文件
df = pd.read_csv('weather.csv')
# 提取时间和气温两列数据
data = df[['Time', 'Temperature']].values.astype(float)
# 归一化数据
mean = np.mean(data, axis=0)
std = np.std(data, axis=0)
data = (data - mean) / std
# 划分训练集和测试集
train_size = int(len(data) * 0.8)
train_data = data[:train_size]
test_data = data[train_size:]
# 定义函数将数据转换为序列形式
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, 1]
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)
# 将数据转换为序列形式
seq_length = 60
train_x, train_y = create_sequences(train_data, seq_length)
test_x, test_y = create_sequences(test_data, seq_length)
# 转换为PyTorch张量
train_x = torch.from_numpy(train_x).float()
train_y = torch.from_numpy(train_y).float()
test_x = torch.from_numpy(test_x).float()
test_y = torch.from_numpy(test_y).float()
# 定义LSTM模型
class LSTM(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(LSTM, self).__init__()
self.hidden_size = hidden_size
self.lstm = nn.LSTM(input_size, hidden_size)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
lstm_out, _ = self.lstm(x.view(len(x), 1, -1))
output = self.fc(lstm_out.view(len(x), -1))
return output[-1]
# 设置GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 初始化模型和优化器
input_size = 2
hidden_size = 64
output_size = 1
model = LSTM(input_size, hidden_size, output_size).to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 定义训练函数
def train(model, optimizer, loss_fn, train_x, train_y):
model.train()
loss_train = 0
for i in range(len(train_x)):
optimizer.zero_grad()
output = model(train_x[i].to(device))
loss = loss_fn(output, train_y[i].to(device))
loss_train += loss.item()
loss.backward()
optimizer.step()
return loss_train / len(train_x)
# 定义测试函数
def test(model, loss_fn, test_x, test_y):
model.eval()
loss_test = 0
with torch.no_grad():
for i in range(len(test_x)):
output = model(test_x[i].to(device))
loss = loss_fn(output, test_y[i].to(device))
loss_test += loss.item()
return loss_test / len(test_x)
# 训练模型
num_epochs = 100
loss_fn = nn.MSELoss()
train_losses = []
test_losses = []
for epoch in range(num_epochs):
train_loss = train(model, optimizer, loss_fn, train_x, train_y)
test_loss = test(model, loss_fn, test_x, test_y)
train_losses.append(train_loss)
test_losses.append(test_loss)
print(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {train_loss:.4f}, Test Loss: {test_loss:.4f}')
# 画出损失曲线
plt.plot(train_losses, label='Train Loss')
plt.plot(test_losses, label='Test Loss')
plt.legend()
plt.show()
# 预测测试集数据
model.eval()
pred_y = []
with torch.no_grad():
for i in range(len(test_x)):
output = model(test_x[i].to(device))
pred_y.append(output.item())
# 反归一化数据
train_mean = mean[1]
train_std = std[1]
test_mean = mean[1]
test_std = std[1]
train_y = train_y * train_std + train_mean
test_y = test_y * test_std + test_mean
pred_y = np.array(pred_y) * test_std + test_mean
# 画出预测和实际曲线图
plt.plot(test_y, label='Actual')
plt.plot(pred_y, label='Predicted')
plt.legend()
plt.show()
```
需要注意的是,此代码并没有进行超参优化和模型调整,可能存在过拟合或欠拟合的问题。在实际项目中,需要根据具体数据情况进行调整。
阅读全文