时域卷积网络(Temporal Convolutional Network,TCN)
TCN基本结构
时域卷积网络(Temporal Convolutional Network,TCN)由Shaojie Bai et al.在2018年提出的,可以用于时序数据处理,详细内容请看论文。
1.因果卷积(Causal Convolution)
因果卷积如上图所示。对于上一层t时刻的值,只依赖于下一层t时刻及其之前的值。与传统的卷积神经网络的不同之处在于,因果卷积不能看到未来的数据,它是单向的结构,不是双向的。也就是说,先有前因,才能有后果,它是一种严格的时间约束模型,因此被称为因果卷积。
2.膨胀卷积(Dilated Convolution)
膨胀卷积(Dilated Convolution)也被称为空洞卷积
纯净的因果卷积仍然存在传统卷积神经网络的问题,即建模时间的长短受到卷积核大小的限制。 如果想获得更长的依赖关系,需要线性的堆叠许多层。 为了解决这个问题,研究人员提出了膨胀卷积,如下图所示。
与传统卷积不同,膨胀卷积允许在卷积期间对输入进行间隔采样,并且采样率由图中的控制。 底层的表示在输入的过程中对每个点进行采样,中间层的表示在输入过程中对每2个点采样一次作为输入。 一般来说,层级越高,d的数值越大。 因此,膨胀卷积使有效窗口的大小随着层数呈指数型增长。 通过这种方法,卷积网络可以使用较少的层,就能获得大的感受野。
3.残差连接(Residual Connections)
残差连接被证明是训练深度网络的有效方法,它允许网络以跨层方式传输信息。
论文中构造了一个残差块来替换卷积层。 如上图所示,一个残差块包含两层卷积和非线性映射,并将WeightNorm和Dropout添加到每一层用来正则化网络。
TCN总结
优点
(1)并行性。当给定一个句子,TCN可以将并行处理句子,而不需要像RNN那样顺序的处理。
(2)灵活的感受野。TCN的感受野的大小由层数、卷积核大小、扩张系数确定。可以根据不同的任务不同的特点点进行灵活定制。
(3)梯度稳定。RNN经常存在梯度消失和梯度爆炸的问题,这主要是由于在不同时间段共享参数导致的。像传统的卷积神经网络一样,TCN也不存在梯度消失和梯度爆炸的问题。
(4)内存更低。RNN在使用时需要保存每一步的信息,这会占用大量的内存,TCN的卷积内核在一个层中共享,内存使用更低。
缺点
(1)TCN 在迁移学习方面可能没有那么强的适应性。这是因为在不同的领域,模型预测所需的历史信息量可能会有所不同。因此,在将一个模型从一个需要较少内存信息的问题迁移到一个需要较长内存的问题上时,TCN 的性能可能会很差,因为其感受野不够大。
(2)论文中描述的TCN仍然是单向结构。在诸如语音识别和语音合成等任务上,纯单向结构仍然非常有用。然而,大多数文本使用双向结构。TCN可以很容易扩展为双向结构,只需使用传统的卷积结构代替因果卷积即可。
(3)TCN毕竟是卷积神经网络的一种变体。虽然使用扩展卷积可以扩大感受野,但仍然受到限制。与Transformer相比,任意长度的相关信息都可以获取的特性仍然很差。TCN在文本中的应用还有待检验。
TCN应用
MINST手写数字分类
单标签,即(xi1,xi2,xi3,...xin)-yi
本地环境:
Python 3.6 IDE:Pycharm
库版本:
keras 2.2.0 numpy 1.16.2 tensorflow 1.9.0
1.下载数据集
2.创建TCN.py,输入如下代码
代码参考:Keras-based TCN
# TCN for minst data from tensorflow.examples.tutorials.mnist import input_data from keras.models import Model from keras.layers import add, Input, Conv1D, Activation, Flatten, Dense # Load data 载入数据 def read_data(path): mnist = input_data.read_data_sets(path, one_hot=True) train_x, train_y = mnist.train.images.reshape(-1, 28, 28), mnist.train.labels, valid_x, valid_y = mnist.validation.images.reshape(-1, 28, 28), mnist.validation.labels, test_x, test_y = mnist.test.images.reshape(-1, 28, 28), mnist.test.labels return train_x, train_y, valid_x, valid_y, test_x, test_y # Residual block 残差块 def ResBlock(x, filters, kernel_size, dilation_rate): r = Conv1D(filters, kernel_size, padding='same', dilation_rate=dilation_rate, activation='relu')( x) # first convolution r = Conv1D(filters, kernel_size, padding='same', dilation_rate=dilation_rate)(r) # Second convolution if x.shape[-1] == filters: shortcut = x else: shortcut = Conv1D(filters, kernel_size, padding='same')(x) # shortcut (shortcut) o = add([r, shortcut]) # Activation function o = Activation('relu')(o) return o # Sequence Model 时序模型 def TCN(train_x, train_y, valid_x, valid_y, test_x, test_y, classes, epoch): inputs = Input(shape=(28, 28)) x = ResBlock(inputs, filters=32, kernel_size=3, dilation_rate=1) x = ResBlock(x, filters=32, kernel_size=3, dilation_rate=2) x = ResBlock(x, filters=16, kernel_size=3, dilation_rate=4) x = Flatten()(x) x = Dense(classes, activation='softmax')(x) model = Model(input=inputs, output=x) # View network structure 查看网络结构 model.summary() # Compile model 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # Training model 训练模型 model.fit(train_x, train_y, batch_size=500, nb_epoch=epoch, verbose=2, validation_data=(valid_x, valid_y)) # Assessment model 评估模型 pre = model.evaluate(test_x, test_y, batch_size=500, verbose=2) print('test_loss:', pre[0], '- test_acc:', pre[1]) # MINST数字从0-9共10个,即10个类别 classes = 10 epoch = 30 train_x, train_y, valid_x, valid_y, test_x, test_y = read_data('MNIST_data') #print(train_x, train_y) TCN(train_x, train_y, valid_x, valid_y, test_x, test_y, classes, epoch)
3.结果
test_loss: 0.05342669463425409 - test_acc: 0.987100002169609
多个标签
(xi1,xi2,xi3,...xin)- (yi1,yi2)
只需根据上述代码进行修改,重新构建训练、测试数据,设置对应的输入输出维度、参数等信息即可。
本地环境:
Python 3.6 IDE:Pycharm
库版本:
keras 2.2.0 numpy 1.16.2 pandas 0.24.1 sklearn 0.20.1 tensorflow 1.9.0
具体代码:
# TCN for indoor location import math from tensorflow.examples.tutorials.mnist import input_data from keras.models import Model from keras.layers import add, Input, Conv1D, Activation, Flatten, Dense import numpy as np import pandas from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error # 创建时序数据 def create_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back), :] dataX.append(a) dataY.append(dataset[i + look_back, -2:]) return np.array(dataX), np.array(dataY) # Residual block def ResBlock(x, filters, kernel_size, dilation_rate): r = Conv1D(filters, kernel_size, padding='same', dilation_rate=dilation_rate, activation='relu')( x) # first convolution r = Conv1D(filters, kernel_size, padding='same', dilation_rate=dilation_rate)(r) # Second convolution if x.shape[-1] == filters: shortcut = x else: shortcut = Conv1D(filters, kernel_size, padding='same')(x) # shortcut (shortcut) o = add([r, shortcut]) o = Activation('relu')(o) # Activation function return o # Sequence Model def TCN(train_x, train_y, test_x, test_y, look_back, n_features, n_output, epoch): inputs = Input(shape=(look_back, n_features)) x = ResBlock(inputs, filters=32, kernel_size=3, dilation_rate=1) x = ResBlock(x, filters=32, kernel_size=3, dilation_rate=2) x = ResBlock(x, filters=16, kernel_size=3, dilation_rate=4) x = Flatten()(x) x = Dense(n_output, activation='softmax')(x) model = Model(input=inputs, output=x) # View network structure model.summary() # Compile model model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # Training model model.fit(train_x, train_y, batch_size=500, nb_epoch=epoch, verbose=2) # Assessment model pre = model.evaluate(test_x, test_y, batch_size=500, verbose=2) # print(pre) print('test_loss:', pre[0], '- test_acc:', pre[1]) # 公共参数 np.random.seed(7) features = 24 output = 2 EPOCH = 30 look_back = 5 trainPath = '../data/train.csv' testPath = '../data/test.csv' trainData = pandas.read_csv(trainPath, engine='python') testData = pandas.read_csv(testPath, engine='python') # features = 1 dataset = trainData.values dataset = dataset.astype('float32') datatestset = testData.values datatestset = datatestset.astype('float32') # print(dataset) # normalize the dataset scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset) datatestset = scaler.fit_transform(datatestset) trainX, trainY = create_dataset(dataset, look_back) testX, testY = create_dataset(datatestset, look_back) # print(trainX) print(len(trainX), len(testX)) print(testX.shape) # reshape input to be [samples, time steps, features] trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1], features)) testX = np.reshape(testX, (testX.shape[0], testX.shape[1], features)) # train_x, train_y, valid_x, valid_y, test_x, test_y = read_data('MNIST_data') print(trainX, trainY) TCN(trainX, trainY, testX, testY, look_back, features, output, EPOCH)
未完待续...
参考资料
An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling
TCN-Time Convolutional Network
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~