用pytorch写一个天气预测的代码,用LSTM或CNN,读取天气中的csv文件,由时间和气温两列数据,区分训练集和测试集,用gpu训练,输入为60天的天气,输出为某一天的天气,并画出实际曲线和预测曲线图
时间: 2023-10-09 16:14:59 浏览: 44
好的,以下是代码实现:
首先,我们需要导入必要的库:
```python
import torch
import torch.nn as nn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```
然后,我们需要读取天气数据,将其分为训练集和测试集。这里我们使用 pandas 库来读取 csv 文件,并将时间和气温两列数据提取出来。具体实现如下:
```python
# 读取天气数据
data = pd.read_csv('weather.csv')
# 提取时间和气温两列数据
time = data['time'].values.reshape(-1, 1)
temp = data['temp'].values.reshape(-1, 1)
# 将数据归一化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
temp = scaler.fit_transform(temp)
# 将数据分为训练集和测试集
train_size = int(len(temp) * 0.8) # 80% 的数据作为训练集
test_size = len(temp) - train_size
train_data, test_data = temp[0:train_size,:], temp[train_size:len(temp),:]
```
接下来,我们可以定义一个函数来生成训练数据和测试数据。这里我们以输入 60 天的天气数据来预测下一天的气温为例。具体实现如下:
```python
def create_dataset(dataset, look_back):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
# 设置参数
look_back = 60
batch_size = 32
trainX, trainY = create_dataset(train_data, look_back)
testX, testY = create_dataset(test_data, look_back)
# 将数据转换为 tensor 类型,并移动到 GPU 上
trainX = torch.from_numpy(trainX).float().to('cuda')
trainY = torch.from_numpy(trainY).float().to('cuda')
testX = torch.from_numpy(testX).float().to('cuda')
testY = torch.from_numpy(testY).float().to('cuda')
```
现在,我们可以定义一个 LSTM 模型来进行天气预测。具体实现如下:
```python
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, 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('cuda')
c0 = torch.zeros(1, x.size(0), self.hidden_size).to('cuda')
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
# 设置模型参数
input_size = 1
hidden_size = 64
output_size = 1
model = LSTM(input_size, hidden_size, output_size).to('cuda')
# 设置训练参数
learning_rate = 0.001
num_epochs = 100
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
```
接下来,我们可以开始训练模型。具体实现如下:
```python
# 训练模型
train_loss = []
test_loss = []
for epoch in range(num_epochs):
# 训练模型
model.train()
train_pred = model(trainX)
loss = criterion(train_pred, trainY)
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss.append(loss.item())
# 测试模型
model.eval()
test_pred = model(testX)
loss = criterion(test_pred, testY)
test_loss.append(loss.item())
# 打印训练信息
if (epoch+1) % 10 == 0:
print('Epoch [{}/{}], Train Loss: {:.4f}, Test Loss: {:.4f}'
.format(epoch+1, num_epochs, train_loss[-1], test_loss[-1]))
```
最后,我们可以使用训练好的模型来进行天气预测,并将实际曲线和预测曲线画出来。具体实现如下:
```python
# 进行天气预测
model.eval()
train_predict = model(trainX)
test_predict = model(testX)
train_predict = scaler.inverse_transform(train_predict.cpu().detach().numpy())
trainY = scaler.inverse_transform(trainY.cpu().detach().numpy())
test_predict = scaler.inverse_transform(test_predict.cpu().detach().numpy())
testY = scaler.inverse_transform(testY.cpu().detach().numpy())
# 画出实际曲线和预测曲线
plt.figure(figsize=(10, 5))
plt.plot(time[look_back:train_size], trainY, label='Train')
plt.plot(time[train_size+look_back+1:], testY, label='Test')
plt.plot(time[look_back:train_size], train_predict, label='Train Predict')
plt.plot(time[train_size+look_back+1:], test_predict, label='Test Predict')
plt.xlabel('Time')
plt.ylabel('Temperature')
plt.legend()
plt.show()
```
完整代码如下:
```python
import torch
import torch.nn as nn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 读取天气数据
data = pd.read_csv('weather.csv')
# 提取时间和气温两列数据
time = data['time'].values.reshape(-1, 1)
temp = data['temp'].values.reshape(-1, 1)
# 将数据归一化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
temp = scaler.fit_transform(temp)
# 将数据分为训练集和测试集
train_size = int(len(temp) * 0.8) # 80% 的数据作为训练集
test_size = len(temp) - train_size
train_data, test_data = temp[0:train_size,:], temp[train_size:len(temp),:]
def create_dataset(dataset, look_back):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
# 设置参数
look_back = 60
batch_size = 32
trainX, trainY = create_dataset(train_data, look_back)
testX, testY = create_dataset(test_data, look_back)
# 将数据转换为 tensor 类型,并移动到 GPU 上
trainX = torch.from_numpy(trainX).float().to('cuda')
trainY = torch.from_numpy(trainY).float().to('cuda')
testX = torch.from_numpy(testX).float().to('cuda')
testY = torch.from_numpy(testY).float().to('cuda')
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, 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('cuda')
c0 = torch.zeros(1, x.size(0), self.hidden_size).to('cuda')
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
# 设置模型参数
input_size = 1
hidden_size = 64
output_size = 1
model = LSTM(input_size, hidden_size, output_size).to('cuda')
# 设置训练参数
learning_rate = 0.001
num_epochs = 100
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 训练模型
train_loss = []
test_loss = []
for epoch in range(num_epochs):
# 训练模型
model.train()
train_pred = model(trainX)
loss = criterion(train_pred, trainY)
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss.append(loss.item())
# 测试模型
model.eval()
test_pred = model(testX)
loss = criterion(test_pred, testY)
test_loss.append(loss.item())
# 打印训练信息
if (epoch+1) % 10 == 0:
print('Epoch [{}/{}], Train Loss: {:.4f}, Test Loss: {:.4f}'
.format(epoch+1, num_epochs, train_loss[-1], test_loss[-1]))
# 进行天气预测
model.eval()
train_predict = model(trainX)
test_predict = model(testX)
train_predict = scaler.inverse_transform(train_predict.cpu().detach().numpy())
trainY = scaler.inverse_transform(trainY.cpu().detach().numpy())
test_predict = scaler.inverse_transform(test_predict.cpu().detach().numpy())
testY = scaler.inverse_transform(testY.cpu().detach().numpy())
# 画出实际曲线和预测曲线
plt.figure(figsize=(10, 5))
plt.plot(time[look_back:train_size], trainY, label='Train')
plt.plot(time[train_size+look_back+1:], testY, label='Test')
plt.plot(time[look_back:train_size], train_predict, label='Train Predict')
plt.plot(time[train_size+look_back+1:], test_predict, label='Test Predict')
plt.xlabel('Time')
plt.ylabel('Temperature')
plt.legend()
plt.show()
```
运行完毕后,应该可以得到一张类似下面这样的图:
![weather_prediction.png](attachment:weather_prediction.png)