基于TCN时间卷积网络(含因果膨胀卷积)的多特征输入风速预测项目实战(pytorch)(八维特征)【有数据集和代码,可运行】

 一、项目简介

本项目是基于PyTorch深度学习框架实现一个使用时间卷积网络(TCN,Temporal Convolutional Network)来进行风速预测的项目,该网络通过堆叠因果卷积和扩张卷积,能够捕捉时间序列依赖关系和特征,可以有效地处理时间序列数据,最后进行预测。网络的输入是风速等8个特征,输出是预测的下一天风速。【本项目的代码文件分模块整理,包含模型构建、数据划分、训练过程等模块都清晰分明】

二、TCN时间卷积网络简介

该算法于2016年由Lea等人他们在做视频动作分割的研究首先提出,CNN模型以 CNN 模型为基础,并做了如下改进:①适用序列模型:因果卷积(Causal Convolution)②记忆历史:空洞卷积/膨胀卷积(Dilated Convolution),残差模块(Residual block)。

1、因果卷积(Causal Convolution)

因果卷积是一种卷积操作,主要应用于时间序列数据或具有时序性的数据分析任务。因果卷积在卷积操作中引入了因果性,确保输出只依赖于过去的输入数据,不受未来信息的影响。(下图为因果卷积过程)

2、膨胀因果卷积(Dilated Causal Convolutions)
膨胀因果卷积(Dilated Causal Convolution)是在因果卷积的基础上引入了膨胀(Dilation)操作的一种卷积操作。它结合了因果卷积和扩张卷积(Dilated Convolution)的特性,能够增加感受野(Receptive Field)并保持因果性。(下图为膨胀因果卷积,相比于上图,以较少的计算代价实现了更大的感受野)
 

3、TCN整体框架

整体的TCN模型如下图所示,较深的网络结构可能会引起梯度消失等问题,该模型利用了一种类似于ResNet中的残差块的结构,这样设计的TCN结构更加的具有泛化能力。

三、实验数据集

 采用的是wind_dataset.csv,本项目采用数据集中WIND、TND等八个特征参数进行预测,数据划分:以滑窗的方式进行数据划分,滑窗大小为20,输入特征为8,每次滑窗的第21天为预测的标签值。数据展示如下:

四、实验环境

平台:Window 11;语言:python3.9;编译器:Pycharm;框架:Pytorch:1.13.1

五、实验内容及部分代码展示

1、model_TCN.py 模型构建

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]))

2、train.py 训练通用模板

训练过程集成到fit函数里面,包含测试集训练过程和验证集计算过程,是项目训练过程的通用代码,其他项目也可以在它的基础上修改后使用。

3、Config.py 参数定义

config中定义了项目的基本参数,可以在里面修改训练参数。

4、DataSplit.py 数据划分

 DataSplit.py 是实现数据划分的函数,通过滑动窗口,将每个窗口大小的数据作为训练数据,将其后面一个数据作为预测结果,再进行划分训练数据和标签,最后分成训练集和验证集。

 5、test_wind_TCN_run.py 训练文件

该py文件实现整体训练流程并做绘图操作。依次实现加载数据、数据标准化、取出WIND数据、划分训练集测试集、数据转化为Tensor、形成数据更迭器、载入模型、定义损失、定义优化器、开始训练、损失可视化、显示预测结果。

6、test_pth.py 模型训练后的测试文件

采用模型训练完成后的pth对数据进行预测,可以展示模型预测效果,前面的处理过程类似test_wind_TCN_run.py所示。

7、loss_draw.py 模型训练后的loss绘图

将训练后产生并收集的loss.csv展示出来,也就是损失图,红框可调展示范围。 

8、predict_pth.py 用某20天数据预测后1天的风速数值  

用某前20天的八个风速特征数据预测后1天风速并绘图和可视化具体的数值

六、实验结果及分析

1、训练过程

这是训练过程中的可视化,会输出train_loss和test_loss

2、loss损失图

该损失是训练了200个epoch的损失图:

3、test_pth.py预测效果展示(预测图)

train-训练epoch=200后的风速预测效果train如下,展示前两百天的预测效果:(红色是真实的,蓝色是预测的)

test-训练epoch=200后的风速预测效果如下(使用pth参数文件进行测试预测),展示前两百天的预测效果):红色是真实的,蓝色是预测的)

4、predict_pth.py预测效果展示(预测具体的某50天)

使用如下图所示的前20天风速,预测后1天的风速值

七、总结及资源

若有朋友需要可运行的源码和数据集,可以guan注【科研小条】gong众号,回复【TCN多特征风速预测】,即可获得。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科研小条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值