时间卷积网络(TCN):结构+pytorch代码

article/2025/11/5 8:24:54

文章目录

  • TCN
    • TCN结构
      • 1-D FCN的结构
      • 因果卷积(Causal Convolutions)
      • 膨胀因果卷积(Dilated Causal Convolutions)
      • 膨胀非因果卷积(Dilated Non-Causal Convolutions)
      • 残差块结构
    • pytorch代码讲解

TCN

  TCN(Temporal Convolutional Network)是由Shaojie Bai et al.提出的,paper地址:https://arxiv.org/pdf/1803.01271.pdf

  想要了解TCN,最好先知道CNN和RNN。

  以往一旦提起sequence,或者存在时间序列的数据,想到的神经网络模型就是RNN及其变种LSTM、GRU等。在上面论文提到,很多工作表明,在RNN这个框架中,很难再找到新的模型,其效果可以在很多任务中超越LSTM,但是跳出RNN这个框架,paper作者展示了利用CNN衍生出的TCN结构就很容易在很多任务中取得超过LSTM、GRU的效果。当然paper作者也表示,TCN并不指代一种模型,更像是一种类似RNN的框架,paper作者渴望抛砖引玉,让更多人来探索挖掘这个框架的能力。

TCN结构

  TCN的设计十分巧妙,同ConvLSTM不同的是,ConvLSTM通过引入卷积操作,让LSTM网络可以处理图像信息,其卷积只对一个时间的输入图像进行操作,TCN则直接利用卷积强大的特性,跨时间步提取特征。

  TCN结构很像Wavenet,paper作者也表示确实借鉴了Wavenet的结构,TCN的结构在paper中表示如下,这是一个 k e r n e l s i z e = 3 , d i l a t i o n s = [ 1 , 2 , 4 ] kernel~size = 3, dilations = [1, 2, 4] kernel size=3,dilations=[1,2,4]的TCN。

下图展示了更直接的TCN结构, k e r n e l s i z e = 2 , d i l a t i o n s = [ 1 , 2 , 4 , 8 ] kernel~size = 2, dilations = [1, 2, 4, 8] kernel size=2,dilations=[1,2,4,8]

kernel size等于2,即每一层的输入,是上一层的两个时刻的输出;dilations = [1, 2, 4, 8],即每一层的输入的时间间隔有多大,dilation=4,即上一层每前推4个时间步的输出,作为这一层的输入,直到取够kernal size个输入。

  TCN要实现RNN的类似功能,需要解决两个问题,

  1. TCN如何像RNN那样,输入多长的时间步,输出时间步也是同样长度,或者说,每个时间的输入都有对应的输出;
  2. 如何保证历史数据不漏接(no leakage)。

  为了解决上面的两个问题,paper作者分别引入了1-D FCN和因果卷积(Causal Convolutions),可以说
T C N = 1 D F C N + C a u s a l C o n v o l u t i o n s TCN = 1D~FCN + Causal~Convolutions TCN=1D FCN+Causal Convolutions

1-D FCN的结构

  为了解决第一个问题,TCN利用了1-D FCN的结构,每一个隐层的输入输出的时间长度都相同,维持相同的时间步,具体来看,第一隐层不管kernel size和dilation为多少,输入若是n个时间步,输出也是n个时间步,同样第二隐层,第三隐层。。。的输入输出时间步长度都是n,这点和RNN就很像,不管在哪一层,每个时间步的输入都会有对应的输出。

  对于第一个时间步,没有任何历史的信息,TCN认为其历史数据全是0 (其实就是卷积操作的padding,这一点最好结合下面的代码理解),同时paper作者通过实验发现,TCN保留长远历史信息的能力较LSTM更强。

因果卷积(Causal Convolutions)

  为了解决第二个问题,TCN利用因果卷积(Causal Convolutions),所谓因果,也就是对于输出t时刻的数据 y t y_{t} yt,其输入只可能是t以及t以前的时刻,即 x 0 … x t x_{0}\dots x_{t} x0xt,其结构如下:

不难发现,这样的卷积连接好像和最上面的TCN结构图不太一样,理论上利用因果卷积是可以搭建TCN,但是如果我们的输出和之前的1000个时间点都存在联系,要获取这种联系,因果卷积构成的TCN深度就是1000-1,如果和历史的10000个时间点有联系,那么深度就是10000-1…,那样TCN就太深了。

膨胀因果卷积(Dilated Causal Convolutions)

  为了有效的应对长历史信息这一问题,paper作者利用了膨胀因果卷积(Dilated Causal Convolutions),还是具有因果性,只不过引入了膨胀因子(dilation factor) d d d,对于 k e r n e l s i z e = 2 , d i l a t i o n s = [ 1 , 2 , 4 , 8 ] kernel~size = 2, dilations = [1, 2, 4, 8] kernel size=2,dilations=[1,2,4,8]的TCN,其结构如下:

一般膨胀系数是2的指数次方,即1,2,4,8,16,32…

膨胀非因果卷积(Dilated Non-Causal Convolutions)

  LSTM是可以双边输入的,输入不仅利用历史信息,也利用了未来信息,TCN也能做到类似的实现,利用膨胀非因果卷积(Dilated Non-Causal Convolutions),下图展示了 k e r n e l s i z e = 3 , d i l a t i o n s = [ 1 , 2 , 4 , 8 ] kernel~size = 3, dilations = [1, 2, 4, 8] kernel size=3,dilations=[1,2,4,8]的膨胀非因果卷积构成的TCN:

残差块结构

  同时,就算我们使用了膨胀因果卷积,有时模型可能仍然很深,较深的网络结构可能会引起梯度消失等问题,为了应对这种情况,paper作者利用了一种类似于ResNet中的残差块的结构,这样设计的TCN结构更加的具有泛化能力(generic)。

o = A c t i v a t i o n ( x + F ( x ) ) o=Activation(x+F(x)) o=Activation(x+F(x))

可以看出来,残差结构替代了TCN层与层之间的简单连接,由于 x x x F ( x ) F(x) F(x)之间的通道数可能不一样,所以这里设计了一个 1 × 1 C o n v 1\times1~Conv 1×1 Conv来对x做一个简单的变换,使得变换后的 x x x F ( x ) F(x) F(x)可以相加。其实这里的图都有一定的欺骗性,每一层每个时刻只有一个网格并不代表这一时刻的通道数等于1

pytorch代码讲解

  paper给的代码是pytorch版本的,获取点这里,其中TCN模型部分的代码如下,重难点部分给出了注释。

import torch
import torch.nn as nn
from torch.nn.utils import weight_normclass Chomp1d(nn.Module):def __init__(self, chomp_size):super(Chomp1d, self).__init__()self.chomp_size = chomp_sizedef forward(self, x):"""其实这就是一个裁剪的模块,裁剪多出来的padding"""return x[:, :, :-self.chomp_size].contiguous()class TemporalBlock(nn.Module):def __init__(self, n_inputs, n_outputs, kernel_size, stride, dilation, padding, dropout=0.2):"""相当于一个Residual block:param n_inputs: int, 输入通道数:param n_outputs: int, 输出通道数:param kernel_size: int, 卷积核尺寸:param stride: int, 步长,一般为1:param dilation: int, 膨胀系数:param padding: int, 填充系数:param dropout: float, dropout比率"""super(TemporalBlock, self).__init__()self.conv1 = weight_norm(nn.Conv1d(n_inputs, n_outputs, kernel_size,stride=stride, padding=padding, dilation=dilation))# 经过conv1,输出的size其实是(Batch, input_channel, seq_len + padding)self.chomp1 = Chomp1d(padding)  # 裁剪掉多出来的padding部分,维持输出时间步为seq_lenself.relu1 = nn.ReLU()self.dropout1 = nn.Dropout(dropout)self.conv2 = weight_norm(nn.Conv1d(n_outputs, n_outputs, kernel_size,stride=stride, padding=padding, dilation=dilation))self.chomp2 = Chomp1d(padding)  #  裁剪掉多出来的padding部分,维持输出时间步为seq_lenself.relu2 = nn.ReLU()self.dropout2 = nn.Dropout(dropout)self.net = nn.Sequential(self.conv1, self.chomp1, self.relu1, self.dropout1,self.conv2, self.chomp2, self.relu2, self.dropout2)self.downsample = nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else Noneself.relu = nn.ReLU()self.init_weights()def init_weights(self):"""参数初始化:return:"""self.conv1.weight.data.normal_(0, 0.01)self.conv2.weight.data.normal_(0, 0.01)if self.downsample is not None:self.downsample.weight.data.normal_(0, 0.01)def forward(self, x):""":param x: size of (Batch, input_channel, seq_len):return:"""out = self.net(x)res = x if self.downsample is None else self.downsample(x)return self.relu(out + res)class TemporalConvNet(nn.Module):def __init__(self, num_inputs, num_channels, kernel_size=2, dropout=0.2):"""TCN,目前paper给出的TCN结构很好的支持每个时刻为一个数的情况,即sequence结构,对于每个时刻为一个向量这种一维结构,勉强可以把向量拆成若干该时刻的输入通道,对于每个时刻为一个矩阵或更高维图像的情况,就不太好办。:param num_inputs: int, 输入通道数:param num_channels: list,每层的hidden_channel数,例如[25,25,25,25]表示有4个隐层,每层hidden_channel数为25:param kernel_size: int, 卷积核尺寸:param dropout: float, drop_out比率"""super(TemporalConvNet, self).__init__()layers = []num_levels = len(num_channels)for i in range(num_levels):dilation_size = 2 ** i   # 膨胀系数:1,2,4,8……in_channels = num_inputs if i == 0 else num_channels[i-1]  # 确定每一层的输入通道数out_channels = num_channels[i]  # 确定每一层的输出通道数layers += [TemporalBlock(in_channels, out_channels, kernel_size, stride=1, dilation=dilation_size,padding=(kernel_size-1) * dilation_size, dropout=dropout)]self.network = nn.Sequential(*layers)def forward(self, x):"""输入x的结构不同于RNN,一般RNN的size为(Batch, seq_len, channels)或者(seq_len, Batch, channels),这里把seq_len放在channels后面,把所有时间步的数据拼起来,当做Conv1d的输入尺寸,实现卷积跨时间步的操作,很巧妙的设计。:param x: size of (Batch, input_channel, seq_len):return: size of (Batch, output_channel, seq_len)"""return self.network(x)

参考资料:
TCN: https://arxiv.org/pdf/1803.01271.pdf

因果卷积(causal)与扩展卷积(dilated):https://blog.csdn.net/tonygsw/article/details/81280364

philipperemy/keras-tcn
:https://github.com/philipperemy/keras-tcn#why-temporal-convolutional-network


http://chatgpt.dhexx.cn/article/QDOWMUMK.shtml

相关文章

时间序列预测——时序卷积网络(TCN)

本文展示了使用时序卷积网络(TCN)进行时间序列预测的全过程,包含详细的注释。整个过程主要包括:数据导入、数据清洗、结构转化、建立TCN模型、训练模型(包括动态调整学习率和earlystopping的设置)、预测、结…

TCN-时间卷积网络

目录 一、引言 二、时序卷积神经网络 2.1 因果卷积(Causal Convolution) 2.2 膨胀卷积(Dilated Convolution) 2.3 残差链接(Residual Connections) 三、讨论和总结 1. TCN的优点 2. TCN的缺点 参考…

时间卷积网络TCN:CNN也可以处理时序数据并且比LSTM更好

本文回顾了 Shaojie Bai、J. Zico Kolter 和 Vladlen Koltun 撰写的论文:An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling。 TCN源代码:https://github.com/locuslab/TCN 文章目录 1. 序列建模2. 因果…

TCN(Temporal Convolutional Network,时间卷积网络)

1 前言 实验表明,RNN 在几乎所有的序列问题上都有良好表现,包括语音/文本识别、机器翻译、手写体识别、序列数据分析(预测)等。 在实际应用中,RNN 在内部设计上存在一个严重的问题:由于网络一次只能处理一个…

机器学习进阶之 时域/时间卷积网络 TCN 概念+由来+原理+代码实现

TCN 从“阿巴阿巴”到“巴拉巴拉” TCN的概念(干嘛来的!能解决什么问题)TCN的父母(由来)TCN的原理介绍上代码! 1、TCN(时域卷积网络、时间卷积网络)是干嘛的,能干嘛 主…

htop与top的区别

总览: 什么是htop top和htop的区别 htop和top的比较 在centos7上安装htop 下载htop源码交叉编译安装 如何使用htop命令 更改htop刷新时间间隔 htop命令的快捷键 什么是htop? htop是一个交互式和实时监视进程查看器的linux编写的 它取代了Unix程序的top …

AIX的topas命令详解

说明 topas命令的说明可以直接执行man topas了解,或者直接看IBM给的 原始文档,路径为:https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.cmds5/topas.htm 命令详解 先上在AIX服务器上执行topas命令后的图片 区域1&…

Linux中 top命令详解

一、基础概念 指令: top 作用: 查看服务器的进程占用资源 进入命令: top (动态显示) 推出命令: 按 q 键 二、输出结果 表头字段含义: PID: 进程id USER: 该进程对应的用户 PR: …

TOP用法详解

1、top命令:相当于Windows下的资源管理器,能够动态实时的显示系统中进程的资源占用情况。 2、在Linux终端上输入top命令出现的结果及其表示的含义如下图: 顺便说一下uptime命令 3、以上是默认的显示内容,可以通过快捷键来更改显示…

topas命令解析

topas命令解析 Posted on 2011-12-08 11:40 疯狂 阅读(984) 评论(1) 编辑 收藏 所属分类: unix <!----> 上一张我们测试机的topas的图(aix 5.3)&#xff1a;然后后面附上解释&#xff1a; topas命令用于监控各种系统资源&#xff0c;如CPU的使用情况&#xff0c;CPU…

Top-Down性能分析

2014年Ahmand Yasin在它的IEEE论文《A top-down method for performance analysis and counter architercture》中&#xff0c;革命性地给出了一个从CPU指令执行的顺畅程度来评估和发现瓶颈的方法&#xff0c;允许我们从黑盒的角度来看问题。 TMAM&#xff1a;自顶向下的微体系…

TOP-K

目录 TOP-K介绍 TOP-K实现 源码 TOP-K介绍 什么是TOP-K&#xff1f; 贴近生活来说&#xff0c;点外卖&#xff0c;打游戏。比如某团&#xff0c;你点一个美食&#xff0c;选你选在城市后&#xff0c;你选择按评分排序&#xff0c;那么它会将这个城市里所有美食店铺评分最高的…

AIX系统 topas查看系统各项指标性能

AIX系统 topas查看系统各项指标性能 topas命令默认2秒更新一次 一、topas命令以区域形式表现系统各项指标性能 如下图&#xff1a; 1、 CPU&#xff1a;反应CPU性能区域&#xff0c;如果有多个 CPU&#xff0c;按 c 键两次就可显示 CPU 列表。仅按 c 键一次会关闭此区域 Us…

top 与 htop

top 与 htop 区别 一、相同点 两者均是可以查看cpu使用情况的命令 二、不同点 top 在linux系统中&#xff0c;top 命令用来显示系统中正在运行的进程的实时状态&#xff0c;它显示了一些非常有用的信息&#xff0c;比如 CPU 利用情况、内存消耗情况&#xff0c;以及每个进…

top cpu

我们有时会把%CPU和us%搞晕&#xff0c;也就是下图所示在top的时候查看cpu的信息。 这时有人会问&#xff1a;这两个CPU到底哪个是对的。 其实都是对的&#xff0c;只是表达的意思不一样。 官方解释如下 Cpu(s)&#xff1a;34.0% us: 用户空间占用CPU百分比 %CPU&#xff1…

TOP TOPAS

在IBM的OS AIX中,root用户输入topas可以查看系统的运行情况(有的OS是使用top查看),如图: (此图截于IBM eServer p5 590)Kernel:内存使用百分率 Network:网络信息区User: 用户进程使用百分率 Disk: 存储信息区Wait: …

安装TOPAS RTion extension, 出现的问题及解决方法

TOPAS MC上有安装general extension的教程&#xff0c;在To add User Extensions部分中。GitHub dicom-interface的readme应该是由于长时间没有更新&#xff0c;所以有些错误。本文是在Linux系统下安装RTion extension&#xff0c;其他系统应该也能借鉴。计算机小白&#xff0c…

TOPAS详解

原文出处&#xff1a;http://www.blogjava.net/freeman1984/archive/2011/12/08/365848.html 上一张我们测试机的topas的图(aix 5.3)&#xff1a;然后后面附上解释&#xff1a; topas命令用于监控各种系统资源&#xff0c;如CPU的使用情况&#xff0c;CPU事件和队列&#xff0…

AIX之topas命令详解

AIX基本命令topas简介 Posted on 2015 年 11 月 11 日 by xiaoyu 由于最近工作需要涉及到AIX主机、存储层面&#xff0c;就对这方面的内容做个简要的笔记&#xff0c;以供后续参考。 topas命令利用System Performance Measurement Interface&#xff08;SPMI) API获得有关信…

AIX topas命令详解

topas命令默认2秒更新一次 一、topas命令以区域形式表现系统各项指标性能&#xff0c; 如下图&#xff1a; 1、 CPU&#xff1a;反应CPU性能区域&#xff0c;如果有多个 CPU&#xff0c;按 c 键两次就可显示 CPU 列表。仅按 c 键一次会关闭此区域 User%&#xff1a;用户进程占…