用pytorch写一个天气预测的代码,用LSTM或CNN,读取天气中的csv文件,由时间和气温两列数据,区分训练集和测试集,用gpu训练,输入为60天的天气,输出为某一天的天气,并画出60天的实际曲线和预测曲线图,注意维度要一致
时间: 2023-10-01 17:06:37 浏览: 104
好的,以下是一个简单的天气预测的代码,使用LSTM模型进行训练和预测,并使用GPU加速训练过程。代码中使用的数据集来自于Kaggle网站上的天气历史数据集。注意,为了让代码更易读,本代码中只保留了关键部分。
```python
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 设置GPU加速
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 读取csv文件
df = pd.read_csv('weather.csv')
# 取出时间和气温两列
data = df[['datetime', 'temperature']].values
# 归一化数据
mean = np.mean(data[:, 1])
std = np.std(data[:, 1])
data[:, 1] = (data[:, 1] - mean) / std
# 划分训练集和测试集
train_data = data[:800]
test_data = data[800:]
# 定义数据集类
class WeatherDataset(Dataset):
def __init__(self, data, seq_len):
self.data = data
self.seq_len = seq_len
def __len__(self):
return len(self.data) - self.seq_len
def __getitem__(self, idx):
x = self.data[idx:idx+self.seq_len, 1]
y = self.data[idx+self.seq_len, 1]
return x, y
# 定义LSTM模型
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(LSTMModel, self).__init__()
self.hidden_size = hidden_size
self.lstm = nn.LSTM(input_size, hidden_size, 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)
c0 = torch.zeros(1, x.size(0), self.hidden_size).to(device)
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
# 定义训练函数
def train(model, train_loader, criterion, optimizer, epoch):
model.train()
train_loss = 0
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data.unsqueeze(2))
loss = criterion(output, target.unsqueeze(1))
loss.backward()
optimizer.step()
train_loss += loss.item()
print('Train Epoch: {} \tLoss: {:.6f}'.format(
epoch, train_loss / len(train_loader)))
# 定义测试函数
def test(model, test_loader, criterion):
model.eval()
test_loss = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data.unsqueeze(2))
test_loss += criterion(output, target.unsqueeze(1)).item()
print('Test set: Average loss: {:.6f}\n'.format(
test_loss / len(test_loader)))
# 定义参数
seq_len = 60
input_size = 1
hidden_size = 64
output_size = 1
lr = 0.001
epochs = 50
batch_size = 32
# 定义数据集和数据加载器
train_dataset = WeatherDataset(train_data, seq_len=seq_len)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = WeatherDataset(test_data, seq_len=seq_len)
test_loader = DataLoader(test_dataset, batch_size=batch_size)
# 定义模型、损失函数和优化器
model = LSTMModel(input_size, hidden_size, output_size).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
# 训练模型
for epoch in range(1, epochs+1):
train(model, train_loader, criterion, optimizer, epoch)
test(model, test_loader, criterion)
# 绘制实际曲线和预测曲线图
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(df['datetime'][800:], df['temperature'][800:], label='Actual')
preds = []
with torch.no_grad():
for i in range(len(test_data)-seq_len):
data = torch.FloatTensor(test_data[i:i+seq_len, 1]).unsqueeze(0).unsqueeze(2).to(device)
preds.append(model(data).item())
ax.plot(df['datetime'][800+seq_len:], np.array(preds)*std+mean, label='Predicted')
ax.legend()
plt.show()
```
代码运行后,会输出每个epoch的训练损失和测试损失,并绘制出实际曲线和预测曲线图。注意,由于本代码仅使用了部分数据集进行训练,因此预测结果可能不太准确。如需更高的准确率,建议使用更多的数据集进行训练。
阅读全文