使用PyTorch构建3层1D CNN LSTM Attention网络模型 ,实现风速预测
时间: 2023-05-27 16:03:21 浏览: 433
Python-在PyTorch中使用LSTM进行风速预测
3星 · 编辑精心推荐
以下示例给出了使用PyTorch构建3层1D CNN LSTM Attention网络模型以进行风速预测的一种方法:
首先,我们需要导入所需的库和数据集。例如,我们使用UCI机器学习库中的气象数据集。
```python
import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.utils.data import DataLoader, Dataset
import pandas as pd
import numpy as np
# Load data
cols = ['year', 'month', 'day', 'hour', 'PM2.5', 'DEWP', 'TEMP', 'PRES', 'cbwd', 'Iws', 'Is', 'Ir']
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/00381/PRSA_data_2010.1.1-2014.12.31.csv',
header=0, names=cols).fillna(0)
```
然后,我们需要对数据集进行适当的处理和变换。例如,我们将在此处为每个数据点定义一个时间序列,并将其随机分割成训练集和测试集。
```python
# Define time series
df['time'] = pd.to_datetime(df[['year', 'month', 'day', 'hour']])
df = df.set_index('time')
df = df.drop(['year', 'month', 'day', 'hour'], axis=1)
# Set training and test data
train_size = int(len(df) * 0.70)
train_data, test_data = df.iloc[:train_size], df.iloc[train_size:]
```
接下来,我们需要为模型创建一个数据集类。我们需要定义数据点的长度和要使用的特征。
```python
# Define Dataset class
class WindDataset(Dataset):
def __init__(self, data, window_size=24, features=['DEWP', 'TEMP', 'PRES', 'Iws', 'Is', 'Ir']):
self.data = data[features].values
self.targets = data['PM2.5'].values
self.window_size = window_size
def __len__(self):
return len(self.data) - self.window_size
def __getitem__(self, index):
return {
'x': torch.tensor(self.data[index:index+self.window_size], dtype=torch.float32),
'y': torch.tensor(self.targets[index+self.window_size], dtype=torch.float32)
}
```
然后,我们需要为模型定义一个1D CNN层。我们将使用3个卷积核和ReLU激活函数。
```python
# Define 1D CNN layer
class CNN1D(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1):
super(CNN1D, self).__init__()
self.conv = nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=stride)
self.relu = nn.ReLU()
def forward(self, x):
x = self.conv(x)
x = self.relu(x)
return x
```
接下来,我们需要为模型定义一个LSTM层。我们将使用2个隐藏层和一个输出层。每一层都有64个LSTM单元。在每个时间步长上,LSTM层的输出将作为1D CNN层的输入。
```python
# Define LSTM layer
class LSTM(nn.Module):
def __init__(self, input_dim, hidden_dim, batch_size, num_layers):
super(LSTM, self).__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.batch_size = batch_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=num_layers)
self.hidden = self.init_hidden()
def init_hidden(self):
hidden = (torch.zeros(self.num_layers, self.batch_size, self.hidden_dim),
torch.zeros(self.num_layers, self.batch_size, self.hidden_dim))
return hidden
def forward(self, x):
lstm_out, self.hidden = self.lstm(x.view(len(x), self.batch_size, -1), self.hidden)
return lstm_out[-1]
# Define model
class Net(nn.Module):
def __init__(self, input_dim, cnn_channels, cnn_kernel_size, cnn_stride, lstm_hidden_dim, lstm_num_layers):
super(Net, self).__init__()
self.cnn = CNN1D(input_dim, cnn_channels, kernel_size=cnn_kernel_size, stride=cnn_stride)
self.lstm = LSTM(cnn_channels, lstm_hidden_dim, batch_size=1, num_layers=lstm_num_layers)
self.attention = nn.Linear(lstm_hidden_dim, 1)
self.out = nn.Linear(lstm_hidden_dim, 1)
def forward(self, x):
cnn_out = self.cnn(x)
lstm_out = self.lstm(cnn_out)
attention_out = self.attention(lstm_out)
attention_weights = torch.softmax(attention_out, dim=0)
attention_applied = attention_weights * lstm_out
out = self.out(attention_applied)
return out.squeeze()
```
最后,我们需要定义要使用的超参数。这些可以根据实际情况进行更改。
```python
# Define hyperparameters
window_size = 24
input_dim = 6
cnn_channels = 64
cnn_kernel_size = 3
cnn_stride = 1
lstm_hidden_dim = 64
lstm_num_layers = 2
learning_rate = 0.001
num_epochs = 50
batch_size = 32
```
然后,我们可以训练模型并针对测试数据评估其性能。
```python
# Train model
train_dataset = WindDataset(train_data, window_size=window_size)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
net = Net(input_dim, cnn_channels, cnn_kernel_size, cnn_stride, lstm_hidden_dim, lstm_num_layers)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
for batch in train_loader:
x = batch['x']
y_true = batch['y']
optimizer.zero_grad()
y_pred = net(x)
loss = criterion(y_pred, y_true)
loss.backward()
optimizer.step()
# Evaluate model
test_dataset = WindDataset(test_data, window_size=window_size)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False)
y_pred_list = []
y_true_list = []
with torch.no_grad():
for batch in test_loader:
x = batch['x']
y_true = batch['y']
y_pred = net(x)
y_pred_list.append(y_pred.item())
y_true_list.append(y_true.item())
rmse = np.sqrt(np.mean((np.array(y_pred_list) - np.array(y_true_list))**2))
print(f'Epoch: {epoch}, RMSE: {rmse:.3f}')
```
最后,我们可以使用该模型进行预测,例如:
```python
# Make prediction
test_point = np.array([[-9, 0.1, 1016, 23, 0, 0]])
net.eval()
with torch.no_grad():
pred = net(torch.tensor(test_point, dtype=torch.float32))
print(f'Predicted wind speed: {pred.item():.3f} m/s')
```
阅读全文