目录
I. 前言II. TransformerIII. 代码实现3.1 数据处理3.2 模型训练/测试3.3 实验结果IV. 源码及数据I. 前言
前面已经写了很多关于时间序列预测的文章:
深入理解PyTorch中LSTM的输入和输出(从input输入到Linear输出)PyTorch搭建LSTM实现时间序列预测(负荷预测)PyTorch搭建LSTM实现多变量时间序列预测(负荷预测)PyTorch搭建双向LSTM实现时间序列预测(负荷预测)PyTorch搭建LSTM实现多变量多步长时间序列预测(一):直接多输出PyTorch搭建LSTM实现多变量多步长时间序列预测(二):单步滚动预测PyTorch搭建LSTM实现多变量多步长时间序列预测(三):多模型单步预测PyTorch搭建LSTM实现多变量多步长时间序列预测(四):多模型滚动预测PyTorch搭建LSTM实现多变量多步长时间序列预测(五):seq2seqPyTorch中实现LSTM多步长时间序列预测的几种方法总结(负荷预测)PyTorch-LSTM时间序列预测中如何预测真正的未来值PyTorch搭建LSTM实现多变量输入多变量输出时间序列预测(多任务学习)PyTorch搭建ANN实现时间序列预测(风速预测)PyTorch搭建CNN实现时间序列预测(风速预测)PyTorch搭建CNN-LSTM混合模型实现多变量多步长时间序列预测(负荷预测)PyTorch搭建Transformer实现多变量多步长时间序列预测(负荷预测)PyTorch时间序列预测系列文章总结(代码使用方法)TensorFlow搭建LSTM实现时间序列预测(负荷预测)TensorFlow搭建LSTM实现多变量时间序列预测(负荷预测)TensorFlow搭建双向LSTM实现时间序列预测(负荷预测)TensorFlow搭建LSTM实现多变量多步长时间序列预测(一):直接多输出TensorFlow搭建LSTM实现多变量多步长时间序列预测(二):单步滚动预测TensorFlow搭建LSTM实现多变量多步长时间序列预测(三):多模型单步预测TensorFlow搭建LSTM实现多变量多步长时间序列预测(四):多模型滚动预测TensorFlow搭建LSTM实现多变量多步长时间序列预测(五):seq2seqTensorFlow搭建LSTM实现多变量输入多变量输出时间序列预测(多任务学习)TensorFlow搭建ANN实现时间序列预测(风速预测)TensorFlow搭建CNN实现时间序列预测(风速预测)TensorFlow搭建CNN-LSTM混合模型实现多变量多步长时间序列预测(负荷预测)
上述文章中都没有涉及到近些年来比较火的Attention机制,随Attention机制一起提出的是transformer模型,关于transformer模型的原理网上各种讲解很多,这里就不具体描述了,有机会再写。
II. Transformer
PyTorch封装了Transformer的具体实现,如果导入失败可以参考:torch.nn.Transformer导入失败。
Transformer模型搭建如下:
class TransformerModel(nn.Module):def __init__(self, args):super(TransformerModel, self).__init__()self.args = args# embed_dim = head_dim * num_heads?self.input_fc = nn.Linear(args.input_size, args.d_model)self.output_fc = nn.Linear(args.input_size, args.d_model)self.pos_emb = PositionalEncoding(args.d_model)encoder_layer = nn.TransformerEncoderLayer(d_model=args.d_model,nhead=8,dim_feedforward=4 * args.d_model,batch_first=True,dropout=0.1,device=device)decoder_layer = nn.TransformerDecoderLayer(d_model=args.d_model,nhead=8,dropout=0.1,dim_feedforward=4 * args.d_model,batch_first=True,device=device)self.encoder = torch.nn.TransformerEncoder(encoder_layer, num_layers=5)self.decoder = torch.nn.TransformerDecoder(decoder_layer, num_layers=5)self.fc = nn.Linear(args.output_size * args.d_model, args.output_size)self.fc1 = nn.Linear(args.seq_len * args.d_model, args.d_model)self.fc2 = nn.Linear(args.d_model, args.output_size)def forward(self, x):# print(x.size()) # (256, 24, 7)y = x[:, -self.args.output_size:, :]# print(y.size()) # (256, 4, 7)x = self.input_fc(x) # (256, 24, 128)x = self.pos_emb(x) # (256, 24, 128)x = self.encoder(x)# 不经过解码器x = x.flatten(start_dim=1)x = self.fc1(x)out = self.fc2(x)# y = self.output_fc(y) # (256, 4, 128)# out = self.decoder(y, x) # (256, 4, 128)# out = out.flatten(start_dim=1) # (256, 4 * 128)# out = self.fc(out) # (256, 4)return out
初始时的数据输入维度为7,也就是每个时刻的负荷值以及6个环境变量。在Transformer的原始论文中,文本的嵌入维度为512,而且PyTorch规定nhead数和d_model也就是嵌入维度必须满足整除关系,因此首先将原始数据从7维映射到d_model维度:
x = self.input_fc(x)
其中input_fc:
self.input_fc = nn.Linear(args.input_size, args.d_model)
然后对原始输入进行位置编码:
x = self.pos_emb(x)
然后经过编码层:
x = self.encoder(x)
得到的输出和输入维度一致。
原始Transformer中的解码器效果很差,因此这里直接将编码器的编码结果经过两个线性层得到输出:
x = x.flatten(start_dim=1)x = self.fc1(x)out = self.fc2(x)
III. 代码实现
3.1 数据处理
利用前24小时的负荷值+环境变量预测后12个时刻的负荷值,数据处理和前面一致。
3.2 模型训练/测试
和前文一致。
3.3 实验结果
训练50轮,MAPE为7.09%:
IV. 源码及数据
后面将陆续公开~