用pytorch写一个天气预测的代码,读取天气中的csv文件,输入为60天的天气,输出为某一天的天气
时间: 2023-07-15 09:12:44 浏览: 110
以下是一个简单的基于 PyTorch 的天气预测模型的代码,它输入过去 60 天的天气数据,并输出第 61 天的天气预测:
```python
import torch
import torch.nn as nn
import pandas as pd
import numpy as np
# 加载天气数据
df = pd.read_csv('weather.csv')
# 选取特征和标签列
features = ['temp', 'pressure', 'humidity', 'wind_speed']
target = ['temp']
# 将数据进行归一化
df_norm = (df - df.mean()) / df.std()
# 将数据转为 numpy 数组
data = np.array(df_norm)
# 定义函数将数据转换为输入和输出
def get_input_output(data, timesteps):
X, Y = [], []
for i in range(timesteps, len(data)):
X.append(data[i-timesteps:i,:])
Y.append(data[i,0])
return np.array(X), np.array(Y)
# 定义模型
class WeatherPredictor(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers):
super(WeatherPredictor, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.lstm = nn.LSTM(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(device)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
# 设定超参数
input_size = len(features)
hidden_size = 64
output_size = 1
num_layers = 2
timesteps = 60
learning_rate = 0.001
num_epochs = 100
# 将数据分为训练集和测试集
train_size = int(len(data) * 0.8)
train_data = data[:train_size]
test_data = data[train_size:]
# 将数据转为输入和输出
train_X, train_Y = get_input_output(train_data, timesteps)
test_X, test_Y = get_input_output(test_data, timesteps)
# 转换为 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()
# 定义设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 实例化模型
model = WeatherPredictor(input_size, hidden_size, output_size, num_layers).to(device)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
# 将数据移动到设备上
train_X = train_X.to(device)
train_Y = train_Y.to(device)
# 前向传播
outputs = model(train_X)
loss = criterion(outputs, train_Y)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 打印损失
if (epoch+1) % 10 == 0:
print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item()))
# 测试模型
with torch.no_grad():
# 将数据移动到设备上
test_X = test_X.to(device)
test_Y = test_Y.to(device)
# 前向传播
y_pred = model(test_X)
# 计算损失
test_loss = criterion(y_pred, test_Y)
print('Test Loss: {:.4f}'.format(test_loss.item()))
# 将预测结果转为 numpy 数组
y_pred = y_pred.cpu().numpy()
# 对预测结果进行逆归一化
df_inv = df[target].iloc[train_size+timesteps:]
y_pred_inv = (y_pred * df_inv.std()) + df_inv.mean()
# 打印预测结果
print('Predicted: {:.2f}°C, Actual: {:.2f}°C'.format(y_pred_inv[-1][0], df[target].iloc[-1][0]))
```
在这个代码中,我们首先加载了天气数据,并选取了需要的特征和标签列。然后,我们对数据进行了归一化并将其转换为 numpy 数组。
接着,我们定义了一个函数,将数据转换为输入和输出。这个函数将过去60天的数据作为输入,将第61天的温度作为输出。
然后,我们定义了一个 LSTM 模型,该模型接受输入和输出的大小,并且具有指定数量的隐藏层和 LSTM 层。我们使用 MSE 损失函数和 Adam 优化器进行训练。
最后,我们将测试数据输入模型并计算损失和预测结果。我们对预测结果进行逆归一化,以便与原始数据进行比较。
阅读全文