精华内容
下载资源
问答
  • 时间序列预测——时序卷积网络中用到的tcn库文件。
  • 基于时序卷积网络的云服务器性能预测模型.pdf
  • 卷积神经网络-时序卷积

    千次阅读 2020-06-18 10:09:02
    传统的卷积神经网络一般认为不太适合时序问题的建模,这主要由于其卷积核大小的限制,不能很好的抓取长时的依赖信息。 但是也有很多的工作显示,特定的卷积神经网络结构也可以达到很好的效果,比如Goolgle提出的用来...

    一、简介

    时序问题的建模大家一般习惯性的采用循环神经网络(RNN)来建模,这是因为RNN天生的循环自回归的结构是对时间序列的很好的表示。传统的卷积神经网络一般认为不太适合时序问题的建模,这主要由于其卷积核大小的限制,不能很好的抓取长时的依赖信息。 但是也有很多的工作显示,特定的卷积神经网络结构也可以达到很好的效果,比如Goolgle提出的用来做语音合成的wavenet,Facebook提出的用来做翻译的卷积神经网络。这就带来一个问题,用卷积来做神经网络到底是只适用于特定的领域还是一种普适的模型? 本文就带着这个问题,将一种特殊的卷积神经网络——时序卷积网络(Temporal convolutional network, TCN)与多种RNN结构相对比,发现在多种任务上TCN都能达到甚至超过RNN模型。

    二、时序卷积神经网络

    2.1 因果卷积(Causal Convolution)
    在这里插入图片描述
    因果卷积可以用上图直观表示。 即对于上一层t时刻的值,只依赖于下一层t时刻及其之前的值。和传统的卷积神经网络的不同之处在于,因果卷积不能看到未来的数据,它是单向的结构,不是双向的。也就是说只有有了前面的因才有后面的果,是一种严格的时间约束模型,因此被成为因果卷积。

    2.2 膨胀卷积(Dilated Convolution)
    单纯的因果卷积还是存在传统卷积神经网络的问题,即对时间的建模长度受限于卷积核大小的,如果要想抓去更长的依赖关系,就需要线性的堆叠很多的层。为了解决这个问题,研究人员提出了膨胀卷积。如下图所示:
    在这里插入图片描述
    和传统卷积不同的是,膨胀卷积允许卷积时的输入存在间隔采样,采样率受图中的d控制。 最下面一层的d=1,表示输入时每个点都采样,中间层d=2,表示输入时每2个点采样一个作为输入。一般来讲,越高的层级使用的d的大小越大。所以,膨胀卷积使得有效窗口的大小随着层数呈指数型增长。这样卷积网络用比较少的层,就可以获得很大的感受野。

    2.3 残差链接(Residual Connections)
    在这里插入图片描述
    残差链接被证明是训练深层网络的有效方法,它使得网络可以以跨层的方式传递信息。本文构建了一个残差块来代替一层的卷积。如上图所示,一个残差块包含两层的卷积和非线性映射,在每层中还加入了WeightNorm和Dropout来正则化网络。

    TCN的优点
    (1)并行性。当给定一个句子时,TCN可以将句子并行的处理,而不需要像RNN那样顺序的处理。
    (2)灵活的感受野。TCN的感受野的大小受层数、卷积核大小、扩张系数等决定。可以根据不同的任务不同的特性灵活定制。
    (3)稳定的梯度。RNN经常存在梯度消失和梯度爆炸的问题,这主要是由不同时间段上共用参数导致的,和传统卷积神经网络一样,TCN不太存在梯度消失和爆炸问题。
    (4)内存更低。RNN在使用时需要将每步的信息都保存下来,这会占据大量的内存,TCN在一层里面卷积核是共享的,内存使用更低。
    2. TCN的缺点
    (1)TCN 在迁移学习方面可能没有那么强的适应能力。这是因为在不同的领域,模型预测所需要的历史信息量可能是不同的。因此,在将一个模型从一个对记忆信息需求量少的问题迁移到一个需要更长记忆的问题上时,TCN 可能会表现得很差,因为其感受野不够大。
    (2)论文中描述的TCN还是一种单向的结构,在语音识别和语音合成等任务上,纯单向的结构还是相当有用的。但是在文本中大多使用双向的结构,当然将TCN也很容易扩展成双向的结构,不使用因果卷积,使用传统的卷积结构即可。
    (3)TCN毕竟是卷积神经网络的变种,虽然使用扩展卷积可以扩大感受野,但是仍然受到限制,相比于Transformer那种可以任意长度的相关信息都可以抓取到的特性还是差了点。TCN在文本中的应用还有待检验。

    展开全文
  • 时间序列预测——时序卷积网络(TCN)

    千次阅读 多人点赞 2021-04-11 08:47:38
      本文展示了使用时序卷积网络(TCN)进行时间序列预测的全过程,包含详细的注释。整个过程主要包括:数据导入、数据清洗、结构转化、建立TCN模型、训练模型(包括动态调整学习率和earlystopping的设置)、预测、...

      本文展示了使用时序卷积网络(TCN)进行时间序列预测的全过程,包含详细的注释。整个过程主要包括:数据导入、数据清洗、结构转化、建立TCN模型、训练模型(包括动态调整学习率和earlystopping的设置)、预测、结果展示、误差评估等完整的时间序列预测流程。
      本文使用的tcn库在本人上传的资源中,链接为tcn.py
      本文使用的数据集在本人上传的资源中,链接为mock_kaggle.csv

    import pandas as pd
    import numpy as np
    import math
    from matplotlib import pyplot as plt
    from matplotlib.pylab import mpl
    import tensorflow as tf
    from sklearn.preprocessing import MinMaxScaler
    from keras import backend as K
    from keras.layers import LeakyReLU
    from tcn import TCN,tcn_full_summary
    from sklearn.metrics import mean_squared_error # 均方误差
    from keras.callbacks import LearningRateScheduler
    from keras.callbacks import EarlyStopping
    from tensorflow.keras import Input, Model,Sequential
    
    
    mpl.rcParams['font.sans-serif'] = ['SimHei']   #显示中文
    mpl.rcParams['axes.unicode_minus']=False       #显示负号
    

    取数据

    data=pd.read_csv('mock_kaggle.csv',encoding ='gbk',parse_dates=['datetime'])
    Date=pd.to_datetime(data.datetime)
    data['date'] = Date.map(lambda x: x.strftime('%Y-%m-%d'))
    datanew=data.set_index(Date)
    series = pd.Series(datanew['股票'].values, index=datanew['date'])
    
    series
    
    date
    2014-01-01    4972
    2014-01-02    4902
    2014-01-03    4843
    2014-01-04    4750
    2014-01-05    4654
                  ... 
    2016-07-27    3179
    2016-07-28    3071
    2016-07-29    4095
    2016-07-30    3825
    2016-07-31    3642
    Length: 937, dtype: int64
    

    滞后扩充数据

    dataframe1 = pd.DataFrame()
    num_hour = 16
    for i in range(num_hour,0,-1):
        dataframe1['t-'+str(i)] = series.shift(i)
    dataframe1['t'] = series.values
    dataframe3=dataframe1.dropna()
    dataframe3.index=range(len(dataframe3))
    
    dataframe3
    
    t-16t-15t-14t-13t-12t-11t-10t-9t-8t-7t-6t-5t-4t-3t-2t-1t
    04972.04902.04843.04750.04654.04509.04329.04104.04459.05043.05239.05118.04984.04904.04822.04728.04464
    14902.04843.04750.04654.04509.04329.04104.04459.05043.05239.05118.04984.04904.04822.04728.04464.04265
    24843.04750.04654.04509.04329.04104.04459.05043.05239.05118.04984.04904.04822.04728.04464.04265.04161
    34750.04654.04509.04329.04104.04459.05043.05239.05118.04984.04904.04822.04728.04464.04265.04161.04091
    44654.04509.04329.04104.04459.05043.05239.05118.04984.04904.04822.04728.04464.04265.04161.04091.03964
    ......................................................
    9161939.01967.01670.01532.01343.01022.0813.01420.01359.01075.01015.0917.01550.01420.01358.02893.03179
    9171967.01670.01532.01343.01022.0813.01420.01359.01075.01015.0917.01550.01420.01358.02893.03179.03071
    9181670.01532.01343.01022.0813.01420.01359.01075.01015.0917.01550.01420.01358.02893.03179.03071.04095
    9191532.01343.01022.0813.01420.01359.01075.01015.0917.01550.01420.01358.02893.03179.03071.04095.03825
    9201343.01022.0813.01420.01359.01075.01015.0917.01550.01420.01358.02893.03179.03071.04095.03825.03642

    921 rows × 17 columns

    二折划分数据并标准化

    # pot=int(len(dataframe3)*0.8)
    pd.DataFrame(np.random.shuffle(dataframe3.values))  #shuffle
    pot=len(dataframe3)-12
    train=dataframe3[:pot]
    test=dataframe3[pot:]
    scaler = MinMaxScaler(feature_range=(0, 1)).fit(train)
    #scaler = preprocessing.StandardScaler().fit(train)
    train_norm=pd.DataFrame(scaler.fit_transform(train))
    test_norm=pd.DataFrame(scaler.transform(test))
    
    test_norm.shape,train_norm.shape
    
    ((12, 17), (909, 17))
    
    X_train=train_norm.iloc[:,1:]
    X_test=test_norm.iloc[:,1:]
    Y_train=train_norm.iloc[:,:1]
    Y_test=test_norm.iloc[:,:1]
    

    转换为3维数据 [samples, timesteps, features]

    source_x_train=X_train
    source_x_test=X_test
    X_train=X_train.values.reshape([X_train.shape[0],1,X_train.shape[1]]) #从(909,16)-->(909,1,16)
    X_test=X_test.values.reshape([X_test.shape[0],1,X_test.shape[1]])  #从(12,16)-->(12,1,16)
    Y_train=Y_train.values
    Y_test=Y_test.values
    
    X_train.shape,Y_train.shape
    
    ((909, 1, 16), (909, 1))
    
    X_test.shape,Y_test.shape
    
    ((12, 1, 16), (12, 1))
    
    type(X_train),type(Y_test)
    
    (numpy.ndarray, numpy.ndarray)
    

    动态调整学习率与提前终止函数

    def scheduler(epoch):
        # 每隔50个epoch,学习率减小为原来的1/10
        if epoch % 50 == 0 and epoch != 0:
            lr = K.get_value(tcn.optimizer.lr)
            if lr>1e-5:
                K.set_value(tcn.optimizer.lr, lr * 0.1)
                print("lr changed to {}".format(lr * 0.1))
        return K.get_value(tcn.optimizer.lr)
    
    reduce_lr = LearningRateScheduler(scheduler)
    early_stopping = EarlyStopping(monitor='loss', 
                                   patience=20, 
                                   min_delta=1e-5,
                                   mode='auto',
                                   restore_best_weights=False,#是否从具有监测数量的最佳值的时期恢复模型权重
                                   verbose=2)
    

    构造TCN模型

    batch_size=None
    timesteps=X_train.shape[1]
    input_dim=X_train.shape[2] #输入维数
    tcn = Sequential()
    input_layer =Input(batch_shape=(batch_size,timesteps,input_dim))
    tcn.add(input_layer)
    tcn.add(TCN(nb_filters=64, #在卷积层中使用的过滤器数。可以是列表。
            kernel_size=3, #在每个卷积层中使用的内核大小。
            nb_stacks=1,   #要使用的残差块的堆栈数。
            dilations=[2 ** i for i in range(6)], #扩张列表。示例为:[1、2、4、8、16、32、64]。
            #用于卷积层中的填充,值为'causal' 或'same'。
            #“causal”将产生因果(膨胀的)卷积,即output[t]不依赖于input[t+1:]。当对不能违反时间顺序的时序信号建模时有用。
            #“same”代表保留边界处的卷积结果,通常会导致输出shape与输入shape相同。
            padding='causal',
            use_skip_connections=True, #是否要添加从输入到每个剩余块的跳过连接。
            dropout_rate=0.1, #在0到1之间浮动。要下降的输入单位的分数。
            return_sequences=False,#是返回输出序列中的最后一个输出还是完整序列。
            activation='relu', #残差块中使用的激活函数 o = Activation(x + F(x)).
            kernel_initializer='he_normal', #内核权重矩阵(Conv1D)的初始化程序。
            use_batch_norm=True, #是否在残差层中使用批处理规范化。
            use_layer_norm=True, #是否在残差层中使用层归一化。
            name='tcn' #使用多个TCN时,要使用唯一的名称
            ))
    tcn.add(tf.keras.layers.Dense(64))
    tcn.add(tf.keras.layers.LeakyReLU(alpha=0.3))
    tcn.add(tf.keras.layers.Dense(32))
    tcn.add(tf.keras.layers.LeakyReLU(alpha=0.3))
    tcn.add(tf.keras.layers.Dense(16))
    tcn.add(tf.keras.layers.LeakyReLU(alpha=0.3))
    tcn.add(tf.keras.layers.Dense(1))
    tcn.add(tf.keras.layers.LeakyReLU(alpha=0.3))
    tcn.compile('adam', loss='mse', metrics=['accuracy'])
    tcn.summary()
    
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    tcn (TCN)                    (None, 64)                143168    
    _________________________________________________________________
    dense (Dense)                (None, 64)                4160      
    _________________________________________________________________
    leaky_re_lu (LeakyReLU)      (None, 64)                0         
    _________________________________________________________________
    dense_1 (Dense)              (None, 32)                2080      
    _________________________________________________________________
    leaky_re_lu_1 (LeakyReLU)    (None, 32)                0         
    _________________________________________________________________
    dense_2 (Dense)              (None, 16)                528       
    _________________________________________________________________
    leaky_re_lu_2 (LeakyReLU)    (None, 16)                0         
    _________________________________________________________________
    dense_3 (Dense)              (None, 1)                 17        
    _________________________________________________________________
    leaky_re_lu_3 (LeakyReLU)    (None, 1)                 0         
    =================================================================
    Total params: 149,953
    Trainable params: 148,417
    Non-trainable params: 1,536
    _________________________________________________________________
    

    训练

    history=tcn.fit(X_train,Y_train, epochs=80,batch_size=32,callbacks=[reduce_lr])
    
    Train on 909 samples
    Epoch 1/80
    909/909 [==============================] - 14s 16ms/sample - loss: 0.1332 - accuracy: 0.0187
    Epoch 2/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0449 - accuracy: 0.0176
    Epoch 3/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0333 - accuracy: 0.0187
    Epoch 4/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0206 - accuracy: 0.0187
    Epoch 5/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0194 - accuracy: 0.0187
    Epoch 6/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0261 - accuracy: 0.0187
    Epoch 7/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0182 - accuracy: 0.0176
    Epoch 8/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0144 - accuracy: 0.0187
    Epoch 9/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0137 - accuracy: 0.0187
    Epoch 10/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0135 - accuracy: 0.0187
    Epoch 11/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0104 - accuracy: 0.0187
    Epoch 12/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0100 - accuracy: 0.0187
    Epoch 13/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0099 - accuracy: 0.0187
    Epoch 14/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0100 - accuracy: 0.0187
    Epoch 15/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0102 - accuracy: 0.0187
    Epoch 16/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0105 - accuracy: 0.0187
    Epoch 17/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0095 - accuracy: 0.0187
    Epoch 18/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0102 - accuracy: 0.0187
    Epoch 19/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0097 - accuracy: 0.0187
    Epoch 20/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0091 - accuracy: 0.0187
    Epoch 21/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0093 - accuracy: 0.0187
    Epoch 22/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0101 - accuracy: 0.0187
    Epoch 23/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0086 - accuracy: 0.0187
    Epoch 24/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0117 - accuracy: 0.0187
    Epoch 25/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0071 - accuracy: 0.01870s - loss: 0.006
    Epoch 26/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0087 - accuracy: 0.0187
    Epoch 27/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0111 - accuracy: 0.0187
    Epoch 28/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0095 - accuracy: 0.0176
    Epoch 29/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0080 - accuracy: 0.0187
    Epoch 30/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0090 - accuracy: 0.0176
    Epoch 31/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0081 - accuracy: 0.0187
    Epoch 32/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0092 - accuracy: 0.0187
    Epoch 33/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0086 - accuracy: 0.0187
    Epoch 34/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0071 - accuracy: 0.0187
    Epoch 35/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0074 - accuracy: 0.0187
    Epoch 36/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0066 - accuracy: 0.0187
    Epoch 37/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0057 - accuracy: 0.0187
    Epoch 38/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0068 - accuracy: 0.0187
    Epoch 39/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0065 - accuracy: 0.0187
    Epoch 40/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0059 - accuracy: 0.0187
    Epoch 41/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0073 - accuracy: 0.0187
    Epoch 42/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0076 - accuracy: 0.0187
    Epoch 43/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0068 - accuracy: 0.0187
    Epoch 44/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0053 - accuracy: 0.0187
    Epoch 45/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0054 - accuracy: 0.0187
    Epoch 46/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0060 - accuracy: 0.0187
    Epoch 47/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0064 - accuracy: 0.01870s - loss: 0.0063 - accuracy: 0.01
    Epoch 48/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0055 - accuracy: 0.0187
    Epoch 49/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0056 - accuracy: 0.0187
    Epoch 50/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0067 - accuracy: 0.0187
    lr changed to 0.00010000000474974513
    Epoch 51/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0058 - accuracy: 0.0187
    Epoch 52/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0050 - accuracy: 0.0187
    Epoch 53/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0058 - accuracy: 0.0187
    Epoch 54/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0047 - accuracy: 0.0187
    Epoch 55/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0054 - accuracy: 0.0187
    Epoch 56/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0047 - accuracy: 0.0187
    Epoch 57/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0051 - accuracy: 0.0187
    Epoch 58/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0063 - accuracy: 0.0187
    Epoch 59/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0060 - accuracy: 0.0187
    Epoch 60/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0047 - accuracy: 0.0187
    Epoch 61/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0054 - accuracy: 0.0187
    Epoch 62/80
    909/909 [==============================] - 2s 2ms/sample - loss: 0.0049 - accuracy: 0.0187
    Epoch 63/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0051 - accuracy: 0.0187
    Epoch 64/80
    909/909 [==============================] - 1s 2ms/sample - loss: 0.0051 - accuracy: 0.0187
    Epoch 65/80
    909/909 [==============================] - 2s 2ms/sample - loss: 0.0048 - accuracy: 0.0187
    Epoch 66/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0052 - accuracy: 0.0187
    Epoch 67/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0051 - accuracy: 0.0187
    Epoch 68/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0048 - accuracy: 0.0187
    Epoch 69/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0049 - accuracy: 0.0187
    Epoch 70/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0057 - accuracy: 0.0187
    Epoch 71/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0050 - accuracy: 0.0187
    Epoch 72/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0049 - accuracy: 0.0187
    Epoch 73/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0052 - accuracy: 0.0187
    Epoch 74/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0048 - accuracy: 0.0187
    Epoch 75/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0053 - accuracy: 0.0187
    Epoch 76/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0049 - accuracy: 0.0187
    Epoch 77/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0054 - accuracy: 0.0187
    Epoch 78/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0055 - accuracy: 0.0187
    Epoch 79/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0055 - accuracy: 0.0187
    Epoch 80/80
    909/909 [==============================] - 1s 1ms/sample - loss: 0.0050 - accuracy: 0.0187
    
    history.history.keys() #查看history中存储了哪些参数
    plt.plot(history.epoch,history.history.get('loss')) #画出随着epoch增大loss的变化图
    #plt.plot(history.epoch,history.history.get('acc'))#画出随着epoch增大准确率的变化图
    

    在这里插入图片描述

    预测

    predict = tcn.predict(X_test)
    real_predict=scaler.inverse_transform(np.concatenate((source_x_test,predict),axis=1))
    real_y=scaler.inverse_transform(np.concatenate((source_x_test,Y_test),axis=1))
    real_predict=real_predict[:,-1]
    real_y=real_y[:,-1]
    

    误差评估

    plt.figure(figsize=(15,6))
    bwith = 0.75 #边框宽度设置为2
    ax = plt.gca()#获取边框
    ax.spines['bottom'].set_linewidth(bwith)
    ax.spines['left'].set_linewidth(bwith)
    ax.spines['top'].set_linewidth(bwith)
    ax.spines['right'].set_linewidth(bwith)
    plt.plot(real_predict,label='real_predict')
    plt.plot(real_y,label='real_y')
    plt.plot(real_y*(1+0.15),label='15%上限',linestyle='--',color='green')
    # plt.plot(real_y*(1+0.1),label='10%上限',linestyle='--')
    # plt.plot(real_y*(1-0.1),label='10%下限',linestyle='--')
    plt.plot(real_y*(1-0.15),label='15%下限',linestyle='--',color='green')
    plt.fill_between(range(0,12),real_y*(1+0.15),real_y*(1-0.15),color='gray',alpha=0.2)
    plt.legend()
    plt.show()
    

    在这里插入图片描述

    round(mean_squared_error(Y_test,predict),4)
    
    0.0012
    
    from sklearn.metrics import r2_score
    round(r2_score(real_y,real_predict),4)
    
    0.5192
    
    per_real_loss=(real_y-real_predict)/real_y
    avg_per_real_loss=sum(abs(per_real_loss))/len(per_real_loss)
    print(avg_per_real_loss)
    
    0.13984217335814073
    
    #计算指定置信水平下的预测准确率
    #level为小数
    def comput_acc(real,predict,level):
        num_error=0
        for i in range(len(real)):
            if abs(real[i]-predict[i])/real[i]>level:
                num_error+=1
        return 1-num_error/len(real)
    
    comput_acc(real_y,real_predict,0.2),comput_acc(real_y,real_predict,0.15),comput_acc(real_y,real_predict,0.1)
    
    (0.75, 0.6666666666666667, 0.33333333333333337)
    
    展开全文
  • 使用卷积神经网络处理时间序列,属于最新的处理模型,非常适合处理时间序列
  • T-C3D 实时行为识别时序卷积网络

    千次阅读 2019-12-11 22:43:40
    为了详细阐述这个结构,文章引入了几个部分,具体由Temporal Encoding Model(时序编码模型),Video Components Generation(视频成分产生),3D Convolution Neural Network(3D卷积网络),Aggregation Functions...

    论文名称:T-C3D:TemporalConvolutional3D NetworkforReal-TimeActionRecognition 

    论文地址:https://aaai.org/ocs/index.php/AAAI/AAAI18/paper/view/17205

    代码地址:https://github.com/tc3d

    最近忙于写论文,也没有时间写博客,今天,我给大家带来一篇行为识别文章《T-C3D:TemporalConvolutional3D NetworkforReal-TimeActionRecognition 》,这篇文章是2018年发表在ECCV上的一篇经典文章,文章出自于北京邮电大学。T3D网络在baseline数据集UCF-101和HMDB-51数据集上精度分别达到了91.8%和62.8%。这篇文章的贡献如下:

    • 提出了一个基于3D-CNN的实时动作识别架构,来学习多种粒度的视频表示。学习的特征不仅能够模拟短视频片段之间随时间变化,而且能够模拟整个视频的时间动态;
    • 提出了一种具有聚合函数的时间编码技术来模拟整个视频的特征,这大大提高了识别性能;
    • 只使用RGB帧作为CNN的输入来实时处理动作识别,同时取得了与现有方法相当的性能。

    在开始文章讲解之前,我想简单介绍一些当下行为识别和语义分割的研究热点。其实行为识别和语义分割都属于分类任务,其区别在于分类的关注点不同,但是在随着这两个方向的不断发展,出现了很多要解决的问题,比如语义分割中的FCN网络存在对小目标分割丢失的问题或大目标分割不全的问题。对于行为识别,对于短动作的行为识别,目前的方法已经达取得的很好的结果,但是对于长时序的动作,目前方法还存在问题。其实对于分割和行为识别面临问题属于同一类问题,解决该问题的思路是:局部特征提取,最后进行局部特征融合形成全局的特征。典型网络代表:语义分割PSPNet,行为识别T-C3D。本段话纯属个人理解,如有问题请留言。

    按照我写博客的一贯作风,我首先介绍文章的创作灵感,之后当下的一些研究状况,紧接着是研究方法(文章的灵魂),最后是实验部分。

    本文创作的的目的是为了解决行为识别网络不实时问题和长时序动作识别问题。那么什么是实时呢?在行为识别领域,具体实时是指端到端的训练,而对于双流网络,由于其结合的光流信息,需要额外时间计算光流图,导致网络不能端到端训练。对于

                                                                                        图1 长短时序动作

    长时序动作,为了直观理解,看图1,“弹钢琴”和“射箭”可以很容易地通过静态画面或连续画面之间的小动作的外观信息来识别,然而,有时短剪辑不足以区分类似的类别(跳高和跳远),这时候需要考虑全局的时序特征来进行判别。同时该网络也可以在提取局部时序特征时候,几个卷积共享参数,所以可以大大减低参数量,这个后续用网络结构图来进行解释。

    接下来介绍一下行为识别的研究领域最新情况和面临的问题。面临的挑战具体有,视频尺度的变化,杂乱的背景,视点的变化,相机的移动等对网络判别行为有很大的影响,这也是行为识别精度上不去的原因之一,同时,和静态图片识别相比,行为识别是一个序列问题,动作要通过多帧结合来进行有效的识别。在过去的十年中,基于视频的行为识别一直在研究中,开始是基于手工设计的方式来获取视频局部的时空特征,然而,手工特征方式面临设计繁琐,存在大量冗余的特征,具体代表方法有IDT,HOG3D,SIFT-3D。之后随着深度学习的发展,利用卷积来自动提取时空特征成为了主流,这也是现阶段发展的主要方向,具体代表网络有C3D,双流网络。

    现在我们介绍本文的重点网络结构,具体如图2,输入为整个视频,分成多个片段作为网络的输入,之后每个片段通多3D CNN来提取局部的时空特征,这些3D CNN共享权重,之后将多个片段进行融合行为对整个视频的表示,最后通过softmax进行行为判别。为了详细阐述这个结构,文章引入了几个部分,具体由Temporal Encoding Model(时序编码模型),Video Components Generation(视频成分产生),3D Convolution Neural Network(3D卷积网络),Aggregation Functions(聚合函数)。接下来对每个部分进行详细介绍:

                                                                              图2 T-C3D网络结构

    Temporal Encoding Model

    为了刻画视频的整体特征,引入了Temporal Encoding Model。形式上,给定一个视频V,在时间维上把它统一划分为S部分{P1,P2,P3,…,Ps},然后从Pi中选择一系列帧组成片段Ci。接下来,通过将每个片段经过3D-CNN的作用,获得S个特征图。将S个clips通过聚合函数作用得到视频级特征。最后,根据视频级特征得出最终的类别分数。不同于以往的工作,T-C3D通过视频级而非帧级预测来优化和更新其参数。具体公式如图3,W表示3D CNN的权重,F:表示激活函数,Q:表示聚合函数,H:表示预测函数,用来产生每个类别的概率得分。关于分段损失函数如图4,其中 G = Q(F(C1; W); F(C2; W); ...;F(Cs; W)) ,模型参数导数计算如图5,用于参数更新。

                                                                         图3 视频最终的类别得分

                                                                                      图4 损失函数

                                                                                      图5 权重导数

    Video Components Generation

    与静止图像不同,视频是动态的,并且具有不同的序列。为了利用良好的方式对整个视频进行建模,作者首先在时间维度上将视频统一划分为几个部分。然后用两种常用的抽样方案从每个部分抽取多个帧,构成一个clip。第一种方案将前一步生成的视频片段统一划分为一定数量的fragments,并从每个fragments中随机选择一帧构成最终的片段。第二种方法从fragments中随机选择一定数量的连续帧来构造最终片段。实质上,第一采样方法随机选择均匀分布在整个视频中的非连续帧来表示整个视频。第二种方法从整个视频中均匀地选择S个片段,每个片段由一定数量的连续帧组成。后续实验部分给出了两种不同的下采样方法的分类精度。

    3D Convolution Neural Network

    首先,受深度残差CNN所获得的惊人的图像分类精度的启发,文章采用了一种带有残差块的深度3D-CNN网络。更特别的是,根据ConvNet架构搜索的工作,采用了17个卷积层和一个完全连接层的3D ResNet。实验表明,在给定的多帧图像中,深度残差的3D-CNN可以提取出更丰富、更强的时空特征层次。其次,对CNN的参数进行预训练在大规模数据集上,已被证明对各种视觉任务非常关键,例如目标检测、图像分类、语义分割等。对于3D-CNN,先前的工作如LTC已经表明,在Sprots-1M上预先训练的3D模型比从头训练的模型具有更高的分类精度。本文首先按照C3D中的策略,对Sports-1M模型进行了预训练,虽然Sports-1M有超过100万个视频,但由于没有人工标注,因此含有大量的噪声。最近,Kay(Kay等人。2017)等人提出了一个大规模、干净的数据集,称为Kinetics,涵盖400个人类行为类别,每个行为至少有400个视频clips。为了尽可能地激活3D-CNN中的神经元,作者采用时间编码的方法对3D-CNN进行了Kinetics数据集上训练,实验表明,Kinetics预训练显著提高了训练效果。

    Aggregation Functions

    聚合函数是T-C3D框架中非常重要的组件。文章详细描述和深入分析四个聚合函数,包括平均池、最大池、加权池和注意力池。接下来我进行一一阐述,这很重要。

    • 平均池:平均池的基本假设是利用所有片段的激活进行动作识别,并将其平均响应作为整体视频预测。从这个角度来看,平均池能够联合描述视频片段序列并从整个视频中获得视觉特征。然而,一些视频可能包含与动作无关的噪声序列,在这种情况下,对这些噪声片段进行平均无法准确地建模动作特征,可能导致识别性能的下降。
    • 最大池:max pooling的基本直觉是为每个动作类别选择最具辨别力的clip,并以这种最强的响应来表示整个视频,直观地说,它专注于单个clip,而不考虑其他剪辑的激活。在某些情况下,单个clip的辨别力不足以捕获整个视频信息。在某种程度上,T-C3D退化到了以前的工作,即在使用最大池时,用每个视频一个clip来训练网络。因此,这种聚合功能驱动T-C3D仅用一个片段来表示整个视频,这违背了T-C3D对整个视频建模的假设。
    • 加权池:此聚合函数的目标是生成一组线性权重,以便在每个clip的输出之间执行元素加权线性融合。实验中,网络权值W和融合权值ω同时优化。该聚合函数根据动作总是由多个阶段组成,这些不同的阶段在识别动作类时可能有不同的影响而产生,同时该聚合函数结合了最大池和均匀池的优点,能够同时减少相关片段的序和噪声片段的不良影响。具体是采用了以S×1为核的卷积层来实现该功能。具体函数定义为如图6.
    • 注意力池:此聚合函数的目标与加权池方法相同。它借用了一种端到端可训练记忆网络的记忆注意机制。直觉是利用一个神经模型通过一个可辩别的处理/注意方案读取外部记忆。具体作者将每个片段的输出视为记忆,将特征权重视为记忆处理程序。形式上,让Fs作为第s个片段的经过3D-CNN的特征图,然后聚合模块通过点积用核q对其进行过滤,生成相应的权值序列。具体如图7.

                                                                                     图6 加权池作用机理

                                                                                    图7 注意力池作用机理

    最后是实验部分,这部分主要是说明T-C3D最优性和探索实验。图8是T-C3D和一些主流方法的对比。图9帧两种采样方式对比,前面有阐述。图10不同聚合方式对比。图11不同训练方式比较,其中多尺度表示对输入进行裁剪和采用镜像(图像增强)。

                                                                                        图8 和一些主流模型对比

                                                                                          图9 不同采样方式对比

                                                                                        图10 不同聚合函数对比

                                                                                  图11 对于T-C3D不同训练方式比较

    展开全文
  • 一、 概述 TCN是18年提出的时序卷积神经网络模型。 时序问题建模,通常采用RNN循环神经网络及其相关变种,比如LSTM、GRU等,这里将卷积神经网络通过膨胀卷积达到抓取长时依赖信息的效果,TCN在一些任务上甚至能超过...

     

    一、 概述

    TCN是18年提出的时序卷积神经网络模型。

    时序问题建模,通常采用RNN循环神经网络及其相关变种,比如LSTM、GRU等,这里将卷积神经网络通过膨胀卷积达到抓取长时依赖信息的效果,TCN在一些任务上甚至能超过RNN相关模型。    

    参考论文:An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling

    Github:https://github.com/LOCUSLAB/tcn

    二、原理

    2.1 因果卷积

    先来介绍下因果卷积(Causal Convolution)

    preview

    对于上一时刻的值,只依赖下一层时刻及其之前的值。因果卷积不能看到未来的数据,是单向的结构,有了前面的因才有后面的果。但是这种模型只能捕捉固定前面几个时刻的值,如果想要捕获更长距离的信息,则需要增加网络层数,于是便有了膨胀卷积的思想。

    2.2 膨胀卷积

    膨胀卷积(Dilated Convlution), 有的地方也称扩张卷积。

    膨胀卷积允许卷积时的输入存在间隔采样,采样率受图中的d控制。 最下面一层的d=1,表示输入时每个点都采样,中间层d=2,表示输入时每2个点采样一个作为输入。一般来讲,越高的层级使用的d的大小越大。所以,膨胀卷积使得有效窗口的大小随着层数呈指数型增长。这样卷积网络用比较少的层,就可以获得很大的感受野。

    2.3 残差链接(Residual Connections)

    残差链接使得网络可以跨层传递信息,避免了层数过多信息丢失的问题。文章构建爱你了一个残差块来代替一层的卷积。如上图,一个残差块包含两层卷积和非线性映射,每层中还加入了WeightNorm和Dropout来正则化网络。

     

    三、 实验

    四、 优缺点

    优点 :

        (1)并行性。当给定一个句子时,TCN可以将句子并行的处理,而不需要像RNN那样顺序的处理。

        (2)灵活的感受野。TCN的感受野的大小受层数、卷积核大小、扩张系数等决定。可以根据不同的任务不同的特性灵活定制。

        (3)稳定的梯度。RNN经常存在梯度消失和梯度爆炸的问题,这主要是由不同时间段上共用参数导致的,和传统卷积神经网络一样,TCN不太存在梯度消失和爆炸问题。

        (4)内存更低。RNN在使用时需要将每步的信息都保存下来,这会占据大量的内存,TCN在一层里面卷积核是共享的,内存使用更低。

    缺点:

        (1)TCN 在迁移学习方面可能没有那么强的适应能力。这是因为在不同的领域,模型预测所需要的历史信息量可能是不同的。因此,在将一个模型从一个对记忆信息需求量少的问题迁移到一个需要更长记忆的问题上时,TCN 可能会表现得很差,因为其感受野不够大。

        (2)论文中描述的TCN还是一种单向的结构,在语音识别和语音合成等任务上,纯单向的结构还是相当有用的。但是在文本中大多使用双向的结构,当然将TCN也很容易扩展成双向的结构,不使用因果卷积,使用传统的卷积结构即可。

        (3)TCN毕竟是卷积神经网络的变种,虽然使用扩展卷积可以扩大感受野,但是仍然受到限制,相比于Transformer那种可以任意长度的相关信息都可以抓取到的特性还是差了点。TCN在文本中的应用还有待检验。

     

    五、 参考链接:

    TCN-时间卷积网络 https://blog.csdn.net/qq_27586341/article/details/90751794

    TCN 时间卷积网络 https://zhuanlan.zhihu.com/p/51246745?utm_source=wechat_session&utm_medium=social&s_r=0  

    展开全文
  • 1.Human Action Recognition using Factorized Spatio-...把时序数据的三维卷积分解成先2维空间卷积 (spatial convolutional layer), 再1维的时间卷积(temporal convolutional layers)。 视频片段切割:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,881
精华内容 2,352
关键字:

时序卷积网络