赞
踩
本项目是基于PyTorch深度学习框架实现一个使用时间卷积网络(TCN,Temporal Convolutional Network)来进行风速预测的项目,该网络通过堆叠因果卷积和扩张卷积,能够捕捉时间序列依赖关系和特征,可以有效地处理时间序列数据,最后进行预测。网络的输入是风速等8个特征,输出是预测的下一天风速。【本项目的代码文件分模块整理,包含模型构建、数据划分、训练过程等模块都清晰分明】
该算法于2016年由Lea等人他们在做视频动作分割的研究首先提出,CNN模型以 CNN 模型为基础,并做了如下改进:①适用序列模型:因果卷积(Causal Convolution)②记忆历史:空洞卷积/膨胀卷积(Dilated Convolution),残差模块(Residual block)。
因果卷积是一种卷积操作,主要应用于时间序列数据或具有时序性的数据分析任务。因果卷积在卷积操作中引入了因果性,确保输出只依赖于过去的输入数据,不受未来信息的影响。(下图为因果卷积过程)
整体的TCN模型如下图所示,较深的网络结构可能会引起梯度消失等问题,该模型利用了一种类似于ResNet中的残差块的结构,这样设计的TCN结构更加的具有泛化能力。
采用的是wind_dataset.csv,本项目采用数据集中WIND、TND等八个特征参数进行预测,数据划分:以滑窗的方式进行数据划分,滑窗大小为20,输入特征为8,每次滑窗的第21天为预测的标签值。数据展示如下:
平台:Window 11;语言:python3.9;编译器:Pycharm;框架:Pytorch:1.13.1
model_TCN.py定义了项目用到的网络TCN模型,该模型由多个组件组成,包括Crop模块、TemporalCasualLayer模块、TemporalConvolutionNetwork模块和TCN模块。Crop模块用于裁剪输入张量的时间维度,去除多余的padding部分。TemporalCasualLayer模块实现了一个膨胀卷积层,由两个膨胀卷积块组成。每个膨胀卷积块包含一个带有权重归一化的卷积层、裁剪模块、ReLU激活函数和Dropout正则化。此外,还包括一个用于快捷连接的卷积层。TemporalConvolutionNetwork模块通过堆叠多个TemporalCasualLayer组成了一个完整的TCN网络。每个TemporalCasualLayer具有不同的膨胀系数,并根据输入和输出通道的数量进行设置。TCN模块封装了TemporalConvolutionNetwork,并添加了一个线性层用于最终的预测。在前向传播中,先经过TCN网络,然后将输出的最后一个时间步传入线性层,并通过ReLU激活函数进行非线性变换。通过以上组件的组合,该TCN模型可以用于时间序列建模任务,并在最后输出预测结果。
- import torch.nn as nn
- from torch.nn.utils import weight_norm
-
- #用于裁剪输入张量的时间维度,去除多余的 padding 部分。
- class Crop(nn.Module):
-
- def __init__(self, crop_size):
- super(Crop, self).__init__()
- self.crop_size = crop_size
-
- def forward(self, x):
- #裁剪张量以去除额外的填充
- return x[:, :, :-self.crop_size].contiguous()
-
- #实现了一个膨胀卷积层,由两个膨胀卷积块组成。每个膨胀卷积块包含一个带有权重归一化的卷积层、裁剪模块、ReLU激活函数和 Dropout 正则化。此外,还包括了一个用于快捷连接的卷积层
- class TemporalCasualLayer(nn.Module):
-
- def __init__(self, n_inputs, n_outputs, kernel_size, stride, dilation, dropout=0.2):
- super(TemporalCasualLayer, self).__init__()
- padding = (kernel_size - 1) * dilation
- conv_params = {
- 'kernel_size': kernel_size,
- 'stride': stride,
- 'padding': padding,
- 'dilation': dilation
- }
-
- self.conv1 = weight_norm(nn.Conv1d(n_inputs, n_outputs, **conv_params))
- self.crop1 = Crop(padding)
- self.relu1 = nn.ReLU()
- self.dropout1 = nn.Dropout(dropout)
-
- self.conv2 = weight_norm(nn.Conv1d(n_outputs, n_outputs, **conv_params))
- self.crop2 = Crop(padding)
- self.relu2 = nn.ReLU()
- self.dropout2 = nn.Dropout(dropout)
-
- self.net = nn.Sequential(self.conv1, self.crop1, self.relu1, self.dropout1,
- self.conv2, self.crop2, self.relu2, self.dropout2)
- #快捷连接
- self.bias = nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
- self.relu = nn.ReLU()
-
- def forward(self, x):
- # 应用因果卷积和快捷连接
- y = self.net(x)
- b = x if self.bias is None else self.bias(x)
- return self.relu(y + b)
-
- #通过堆叠多个 TemporalCasualLayer 组成了一个完整的 TCN 网络。每个 TemporalCasualLayer 具有不同的膨胀系数,并根据输入和输出通道的数量进行设置。
- class TemporalConvolutionNetwork(nn.Module):
-
- def __init__(self, num_inputs, num_channels, kernel_size=2, dropout=0.2):
- super(TemporalConvolutionNetwork, self).__init__()
- layers = []
- num_levels = len(num_channels)
- tcl_param = {
- 'kernel_size': kernel_size,
- 'stride': 1,
- 'dropout': dropout
- }
- for i in range(num_levels):
- dilation = 2 ** i
- in_ch = num_inputs if i == 0 else num_channels[i - 1]
- out_ch = num_channels[i]
- tcl_param['dilation'] = dilation
- tcl = TemporalCasualLayer(in_ch, out_ch, **tcl_param)
- # tcl = self.relu(tcl)
- layers.append(tcl)
-
- self.network = nn.Sequential(*layers)
-
- def forward(self, x):
- return self.network(x)
-
- #封装了 TemporalConvolutionNetwork,并添加了一个线性层用于最终的预测。在前向传播中,先经过 TCN 网络,然后将输出的最后一个时间步传入线性层,并通过 ReLU 激活函数进行非线性变换。
- class TCN(nn.Module):
-
- def __init__(self, input_size, output_size, num_channels, kernel_size, dropout):
- super(TCN, self).__init__()
- self.tcn = TemporalConvolutionNetwork(input_size, num_channels, kernel_size=kernel_size, dropout=dropout)
- self.linear = nn.Linear(num_channels[-1], output_size)
- self.relu = nn.ReLU()
-
- def forward(self, x):
- # 应用TCN和线性层,然后使用ReLU激活函数
- y = self.tcn(x) # [N,C_out,L_out=L_in]
- return self.relu(self.linear(y[:, :, -1]))
训练过程集成到fit函数里面,包含测试集训练过程和验证集计算过程,是项目训练过程的通用代码,其他项目也可以在它的基础上修改后使用。
config中定义了项目的基本参数,可以在里面修改训练参数。
DataSplit.py 是实现数据划分的函数,通过滑动窗口,将每个窗口大小的数据作为训练数据,将其后面一个数据作为预测结果,再进行划分训练数据和标签,最后分成训练集和验证集。
该py文件实现整体训练流程并做绘图操作。依次实现加载数据、数据标准化、取出WIND数据、划分训练集测试集、数据转化为Tensor、形成数据更迭器、载入模型、定义损失、定义优化器、开始训练、损失可视化、显示预测结果。
采用模型训练完成后的pth对数据进行预测,可以展示模型预测效果,前面的处理过程类似test_wind_TCN_run.py所示。
将训练后产生并收集的loss.csv展示出来,也就是损失图,红框可调展示范围。
用某前20天的八个风速特征数据预测后1天风速并绘图和可视化具体的数值
这是训练过程中的可视化,会输出train_loss和test_loss
该损失是训练了200个epoch的损失图:
train-训练epoch=200后的风速预测效果train如下,展示前两百天的预测效果:(红色是真实的,蓝色是预测的)
test-训练epoch=200后的风速预测效果如下(使用pth参数文件进行测试预测),展示前两百天的预测效果):红色是真实的,蓝色是预测的)
使用如下图所示的前20天风速,预测后1天的风速值
若有朋友需要可运行的源码和数据集,可以guan注【科研小条】gong众号,回复【TCN多特征风速预测】,即可获得。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。