当前位置:   article > 正文

深度学习算法transformer(时序预测)_transformer预测代码

transformer预测代码

 transformer代码部分(关于原理网上资料已经很多,这里只展示代码,数据集为开源ETT数据集)

本文采用nn.Transformer,nn.Transformer没有加入embedding、位置embedding、linear+softmax

本文使用的是时序数据,embedding使用的是nn.Linear;位置embedding使用的是传统常见的位置embedding,详情见代码;nn.Transformer之后再接一个nn.Linear做预测

encoder的输入序列长度是seq_length = 96,decoder的输入序列长度label_length + pred_length = 72

讲的比较好的transformer原理Transformer模型详解(图解最完整版) - 知乎

1. 导入必须要的包

  1. import torch
  2. import torch.nn as nn
  3. import numpy as np
  4. import pandas as pd
  5. import plotly.express as px
  6. from sklearn import metrics
  7. from torch.utils.data import Dataset, DataLoader

2. 定义transformer网络

  1. class PositionalEncoding(nn.Module):
  2. def __init__(self, d_model, device, max_len=5000):
  3. super(PositionalEncoding, self).__init__()
  4. position = torch.arange(0, max_len).unsqueeze(1)
  5. div_term = torch.exp(torch.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
  6. pe = torch.zeros(max_len, d_model)
  7. pe[:, 0::2] = torch.sin(position * div_term)
  8. pe[:, 1::2] = torch.cos(position * div_term)
  9. self.pe = pe.unsqueeze(0).transpose(1, 0).to(device)
  10. def forward(self, x):
  11. return self.pe[:x.size(0), :]
  12. class TransformerTimeSeriesModel(nn.Module):
  13. def __init__(self, input_size, d_model, device, nhead,
  14. num_encoder_layers, num_decoder_layers, dim_feedforward, dropout=0.1):
  15. super(TransformerTimeSeriesModel, self).__init__()
  16. self.value_encoding = nn.Linear(input_size, d_model)
  17. self.positional_encoding = PositionalEncoding(d_model, device)
  18. self.transformer = nn.Transformer(d_model=d_model, nhead=nhead,
  19. num_encoder_layers=num_encoder_layers,
  20. num_decoder_layers=num_decoder_layers,
  21. dim_feedforward=dim_feedforward,
  22. dropout=dropout)
  23. self.fc_out = nn.Linear(d_model, 1)
  24. def forward(self, src, tgt, device, tgt_mask=None):
  25. tgt_mask = nn.Transformer.generate_square_subsequent_mask(tgt.size(0)).to(device)
  26. src = self.value_encoding(src) + self.positional_encoding(src)
  27. tgt = self.value_encoding(tgt) + self.positional_encoding(tgt)
  28. output = self.transformer(src, tgt, tgt_mask=tgt_mask)
  29. return self.fc_out(output)

3. 定义有关Dataset的数据整理

  1. # 定义Dataset
  2. class get_dataset(Dataset):
  3. def __init__(self, data_path, seq_length, label_length, pred_length,
  4. features, train_split, mode):
  5. self.mode = mode
  6. self.data_path = data_path
  7. self.features = features
  8. self.seq_length = seq_length
  9. self.label_length = label_length
  10. self.pred_length = pred_length
  11. self.data, self.data_max, self.data_min = self.get_data()
  12. # print(self.data)
  13. # print(self.data[0, :-1, :])
  14. # print(self.data[0, -1, -1])
  15. # print(self.data[0, -1, -1].unsqueeze(0))
  16. # print(self.data[0, -1, -1].unsqueeze(0).unsqueeze(1))
  17. train_num = int(train_split * len(self.data))
  18. if self.mode == 'train':
  19. self.data = self.data[:train_num, :, :]
  20. else:
  21. self.data = self.data[train_num:, :, :]
  22. def __len__(self):
  23. return len(self.data)
  24. def __getitem__(self, index):
  25. return self.data[index, :-self.pred_length, :], \
  26. self.data[index, (self.seq_length - self.label_length):, :], \
  27. self.data[index, (self.seq_length - self.label_length):, -1].unsqueeze(1)
  28. def get_data(self):
  29. data = pd.read_csv(self.data_path)
  30. data.index = pd.to_datetime(data['date'])
  31. data = data.drop('date', axis=1)
  32. data_max = data.max()
  33. data_min = data.min()
  34. data = (data - data_min) / (data_max - data_min)
  35. num_sample = len(data) - self.seq_length - self.pred_length + 1
  36. seq_data = torch.zeros(num_sample,
  37. self.seq_length + self.pred_length,
  38. len(self.features))
  39. # print(data.iloc[0:0 + self.seq_length + 1, self.features].values)
  40. for i in range(num_sample):
  41. seq_data[i] = torch.tensor(data.iloc[i:i + self.seq_length + self.pred_length,
  42. self.features].values)
  43. # print(data_max)
  44. # print(data_min)
  45. return seq_data, data_max, data_min

4. 定义训练

  1. def train(model, dataset, epochs, optim, loss_function, device, batch_size, shuffle=True):
  2. data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle)
  3. for epoch in range(epochs):
  4. train_loss = 0
  5. model.train()
  6. for x, y, label in data_loader:
  7. x, y, label = x.transpose(1, 0).to(device),
  8. y.transpose(1, 0).to(device),
  9. label.transpose(1, 0).to(device)
  10. # print('x', x.shape)
  11. # print('y', y.shape)
  12. pred = model(x, y, device)
  13. # print('pred', pred)
  14. # print(pred.shape)
  15. loss = loss_function(pred, label)
  16. optim.zero_grad()
  17. loss.backward()
  18. optim.step()
  19. train_loss += loss.item()
  20. train_loss /= len(data_loader)
  21. print('epoch / epochs : %d / %d, loss : %.6f' % (epoch, epochs, train_loss))

5. 定义测试

  1. def test(model, dataset, device, batch_size, label_length, pred_length, root_path, shuffle=False):
  2. model.eval()
  3. data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle)
  4. # print('data_loader : ', len(data_loader))
  5. # print('dataset : ', len(dataset))
  6. preds, labels = np.zeros(len(dataset) * (label_length + pred_length)), \
  7. np.zeros(len(dataset) * (label_length + pred_length))
  8. left, right = 0, 0
  9. for x, y, label in data_loader:
  10. left = right
  11. # if len(label) != 32:
  12. # print('--')
  13. right += len(label) * (label_length + pred_length)
  14. x, y = x.transpose(1, 0).to(device), y.transpose(1, 0).to(device)
  15. pred = model(x, y, device).detach().cpu().numpy().flatten()
  16. # print('right:', right)
  17. # print('label : ', label.flatten())
  18. # print('pred : ', pred)
  19. # print(label.flatten().shape)
  20. # print(pred.shape)
  21. preds[left:right] = pred
  22. labels[left:right] = label.transpose(1, 0).detach().cpu().numpy().flatten()
  23. preds_ = preds * (dataset.data_max['OT'] - dataset.data_min['OT']) + dataset.data_min['OT']
  24. labels_ = labels * (dataset.data_max['OT'] - dataset.data_min['OT']) + dataset.data_min['OT']
  25. np.save(root_path + '_preds.npy', preds)
  26. np.save(root_path + '_labels.npy', labels)
  27. return preds_, labels_

6. 定义模型评估指标

  1. def model_eva(pred, label):
  2. fig = px.line(title='transformer模型预测')
  3. fig.add_scatter(y=label, name='label')
  4. fig.add_scatter(y=pred, name='pred')
  5. fig.show()
  6. # print(label)
  7. # print(pred)
  8. # label_nozero = labels[labels == 0] = 1e-3
  9. index = np.where(label > 0.01)
  10. mse = np.mean((label - pred) ** 2)
  11. r2 = 1 - np.sum((label - pred) ** 2) / np.sum((label - np.mean(label)) ** 2)
  12. mape = np.abs((pred[index] - label[index]) / label[index]).mean()
  13. mae = np.abs(label - pred).mean()
  14. print('MSE : %.6f' % (mse))
  15. print('R2 : %.6f' % (r2))
  16. print('MAPE : %.6f' % (mape))
  17. print('MAE : %.6f' % (mae))

7. main函数以及运行结果

  1. seed = 0
  2. torch.manual_seed(seed)
  3. if torch.cuda.is_available():
  4. torch.cuda.manual_seed(seed)
  5. torch.cuda.manual_seed_all(seed)
  6. np.random.seed(seed)
  7. torch.backends.cudnn.benchmark = False
  8. torch.backends.cudnn.deterministic = True
  9. device = 'cuda' if torch.cuda.is_available() else 'cpu'
  10. seq_length = 96
  11. label_length = 48
  12. pred_length = 24
  13. features = [6] # [HUFL,HULL,MUFL,MULL,LUFL,LULL,OT]
  14. input_size = len(features)
  15. epochs = 100
  16. lr = 0.005
  17. batch_size = 32
  18. train_split = 0.8
  19. d_model = 128
  20. nhead = 2
  21. num_encoder_layers = 2
  22. num_decoder_layers = 2
  23. dim_feedforward = 128
  24. dropout = 0.1
  25. root_path = './' + 'seq_' + str(seq_length) + '_label_' + str(label_length) + '_pred_' + str(pred_length)
  26. save_path = root_path + '_transformer.pth'
  27. model = TransformerTimeSeriesModel(input_size, d_model, device, nhead,
  28. num_encoder_layers, num_decoder_layers,
  29. dim_feedforward, dropout=0.1).to(device)
  30. optim = torch.optim.SGD(model.parameters(), lr=lr)
  31. loss_function = nn.MSELoss()
  32. dataset_train = get_dataset(data_path, seq_length, label_length, pred_length, features, train_split = train_split, mode = 'train')
  33. dataset_test = get_dataset(data_path, seq_length, label_length, pred_length, features, train_split = train_split, mode = 'test')
  34. train(model, dataset_train, epochs, optim, loss_function, device, batch_size, shuffle = True)
  35. torch.save(model.state_dict(), save_path)
  36. preds, labels = test(model, dataset_test, device, batch_size, label_length, pred_length, root_path, shuffle=False)
  37. model_eva(preds, labels)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/656760
推荐阅读
相关标签
  

闽ICP备14008679号