精华内容
下载资源
问答
  • Python-深度学习-学习笔记(13):keras搭建卷积神经网络(对二维数据进行一维卷积) 卷积神经网络进行图像分类是深度学习关于图像处理的一个应用,卷积神经网络的优点是能够直接与图像像素进行卷积,从图像像素中...

    Python-深度学习-学习笔记(13):keras搭建卷积神经网络(对二维数据进行一维卷积)

    卷积神经网络进行图像分类是深度学习关于图像处理的一个应用,卷积神经网络的优点是能够直接与图像像素进行卷积,从图像像素中提取图像特征,这种处理方式更加接近人类大脑视觉系统的处理方式。另外,卷积神经网络的权值共享属性和pooling层使网络需要训练的参数大大减小,简化了网络模型,提高了训练的效率。

    一、搭建卷积网络步骤

    1、建立模型

    1.1、建立Sequential模型

    Sequential模型是多个神经网络的线性堆叠。类似于一个框架结构,之后将设计好的层及层的参数填到到这个模型中,实现一个整体网络的效果。

    from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
    """
    	建立Sequential模型
    """
    from keras.models import Sequential #在使用前需要先提前导入这个函数
    model = Sequential()
    
    1.2、建立卷积层

    卷积神经网络的卷积层,也叫做特征提取层,包括二个部分。第一部分是真正的卷积层,主要作用是提取输入数据特征。每一个不同的卷积核提取输入数据的特征都不相同,卷积层的卷积核数量越多,就能提取越多输入数据的特征。

    """
        建立卷积层1
        
        参数:
            filters - 建立的滤镜个数
            kernel_size - 滤镜大小
            padding - 填充:当为'same'时,使得图像卷积后的大小保持不变
            input_shape - 输入图形大小
            activation - 设置激活函数
    """
    model.add(Conv2D(filters=16,
                     kernel_size=(5,5),
                     padding = 'same',
                     input_shape = (28,28,1),
                     activation = 'relu'))
    
    
    1.3、建立池化层

    pooling层,也叫下采样层,主要目的是在保留有用信息的基础上减少数据处理量,加快训练网络的速度。通常情况下,卷积神经网络至少包含二层卷积层(这里把真正的卷积层和下采样层统称为卷积层),即卷积层,pooling层,卷积层,pooling层。卷积层数越多,在前一层卷积层基础上能够提取更加抽象的特征。

    """
        建立池化层1
        
        参数:
            pool_size - 池化层大小
            
    """
    model.add(MaxPooling2D(pool_size = (2,2)))
    

    在这之后也可以继续添加卷积层2 -> 池化层2 ……依据你的神经网络需求而定,这里不再做过多赘述。

    1.4、建立平坦层

    由于通过了过滤器,使得数据维度发生改变,而这一步的作用是在输入到神经网络之前,将待处理的数据转换为一维向量,对应到输入层的神经单元上。

    #建立平坦层
    model.add(Flatten())
    
    1.5、建立隐蔽层和输出层

    这一步同建立多层神经网络方法相同,这里不再做过多的解释。
    如何搭建单层或多层神经网络请见上一篇博客。

    https://blog.csdn.net/qq_42826337/article/details/89341800

    #建立隐蔽层
    model.add(Dense(128,activation='relu'))
    model.add(Dropout(0.5))
    
    #建立输出层
    model.add(Dense(10,activation='softmax'))
    

    可以包含多个全连接层,实际上就是多层感知机的隐含层部分。通常情况下后面层的神经节点都和前一层的每一个神经节点连接,同一层的神经元节点之间是没有连接的。每一层的神经元节点分别通过连接线上的权值进行前向传播,加权组合得到下一层神经元节点的输入。

    1.6、查看模型摘要
    print(model.summary())
    

    在这里插入图片描述

    2、开始训练

    2.1、定义训练方式
    """
        定义训练方式
    
        参数:
            loss - 损失函数: 这里采用交叉熵的方式
            optimizer - 优化器: 使用adam优化器可以让训练收敛更快
            metrics - 评估模型:设置为准确率
    
    """
    model.compile(loss='categorical_crossentropy',
                  optimizer='adam',metrics=['accuracy'])
    
    2.2、开始训练
    """
        开始训练
    
        参数:
            x_train4D_normalize - feature数字图像的特征值
            y_trainOneHot - 数字图像的真实标签
            validation_spli - 训练与验证数据比例:80%用作训练数据,20%用作验证数据
            epochs - 训练周期
            batch_size - 每批次的数据项数
            verbose - 显示训练过程
    """
    train_history=model.fit(x=x_train4D_normalize,
                            y=y_trainOneHot,validation_split=0.2,
                            epochs=10,batch_size=300,verbose=2)
    

    在这里插入图片描述

    2.3、画出准确的执行过程
    import matplotlib.pyplot as plt
    def show_train_history(train_history,train,validation):
        """
        显示训练过程
    
        参数:
            train_history - 训练结果存储的参数位置
            train - 训练数据的执行结果
            validation - 验证数据的执行结果
            
    """
        plt.plot(train_history.history[train])
        plt.plot(train_history.history[validation])
        plt.title('Train History')
        plt.ylabel(train)
        plt.xlabel('Epoch')
        plt.legend(['train','validation'],loc = 'upper left')
        plt.show()
    
    show_train_history(train_history,'acc','val_acc') #绘制准确率执行曲线
    show_train_history(train_history,'loss','val_loss') #绘制损失函数执行曲线
    

    在这里插入图片描述
    由于这里的训练集准确率始终大于验证集准确率,所以我们需要通过增加训练周期或是增加隐蔽层数从而提高准确率,使其在不发生过拟合的前提下实现准确率曲线尽可能的接近。同时我们可以发现卷积网络使得代价函数的值降得非常低,这说明卷积可以增加训练的准确性,训练出更接近准确值的参数。

    3、评估模型准确率

    根据训练来分析此模型的准确率。

    scores = model.evaluate(x_test4D_normalize,y_testOneHot)
    scores[1]
    

    4、显示混淆矩阵

    混淆矩阵也称误差矩阵,是一种特定的表格显示方式,可以让我们以可视化的方式了解有监督的学习算法的结果,看出算法模型是否混淆了两个类。

    import pandas as pd
    pd.crosstab(y_test,prediction,
                rownames=['label'],colnames=['predict'])
    

    在这里插入图片描述
    对角线为预测正确的数字,其他非对角线的数字代表将某一个标签预测错误,成为另一个标签。

    二、对二维数据进行一维卷积

    通常情况下我们会遇到一些一维数据,例如经过FFT卷积后得到的信号,或者是一些音频信号等自然语言处理领域,要想卷积这种数据,我们就会用到一维卷积的方法。
    在这里插入图片描述
    如图所示,左侧为我们需要卷积的信号,右侧是过滤器,卷积的方法与二维卷积相似,也是通过相乘 -> 相加 ->平移 ……,从而在提取特征值后压缩原有数据,从而简化网络。

    1、如何搭建一维卷积网络

    上述是对1维数据进行1维卷积的方法,比较简单,这里重点说如何对2维及以上数据进行1维卷积。

    1.1、导入1维卷积函数

    首先我们要倒入1维卷积网络的各种函数包。

    from keras.models import Sequential
    from keras.layers import Dense,Dropout,Flatten,Conv1D,MaxPooling1D
    
    1.2、降维(针对2维数据做1维卷积情况)

    这里要说一点,我们在对数据预处理的时候,如果不是一维数据而是二维的话,一定要先将数据进行降维,例如我之前有个28*28的数据,我们要将其变为28 * 28=784。

    为了表示清楚,这里做个对比。

    (1)二维卷积(不需要对数据进行降维)

    x_train4D = x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
    x_test4D = x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
    x_train4D_normalize = x_train4D / 255
    x_test4D_normalize = x_test4D / 255
    

    (2)一维卷积(需要对数据进行降维)

    x_train3D = x_train.reshape(x_train.shape[0],784,1).astype('float32')
    x_test3D = x_test.reshape(x_test.shape[0],784,1).astype('float32')
    x_train3D_normalize = x_train3D / 255
    x_test3D_normalize = x_test3D / 255
    

    强调一点,(60000,28,28,1)最后的“1”是需要与过滤器进行卷积的通道维度数,也就是说,数据的最后一位是通道数,而不是数据的维数。你不可以将降维后的数据维度写成(60000,1,784),这样就变成了60000个数据,数据大小为1,通道数为784了;你必须写成(60000,784,1),表示60000个数据,大小为784,通道数为1。

    1.3、建立模型

    之后所有的卷积层和池化层都要调用1维卷积的函数,也就是将之前的Conv2D都变为Conv1D。

    这里需要说一点,即使是1维卷积,我们依然需要平坦层,因为在卷积后,通道数也占了一个维度,而整体看来,数据还是一个多维数据,无法作为1维数据传入神经网络的输入层,我这里想了很久,如图:
    在这里插入图片描述
    这是一维卷积网络的模型摘要,我们的输入为784大小的一维数据,下一层的过滤器个数为10等等……
    最后在平坦层上之前,也就是我圈出来的部分,是一个2维数据,所以需要通过平坦层将49*10变为一个490的一维数据,才能传入神经网络的输入层。

    之后的所有模型建立方法都与2维建立相同。


    下面附上对2维数据进行1维卷积的代码事例:

    from keras.datasets import mnist
    from keras.utils import np_utils
    import numpy as np
    from keras.models import Sequential
    from keras.layers import Dense,Dropout,Flatten,Conv1D,MaxPooling1D
    np.random.seed(10)
    
    
    (x_train,y_train),(x_test,y_test) = mnist.load_data()
    #将features转换为三维矩阵
    x_train3D = x_train.reshape(x_train.shape[0],784,1).astype('float32')
    x_test3D = x_test.reshape(x_test.shape[0],784,1).astype('float32')
    #将feature标准化
    x_train3D_normalize = x_train3D / 255
    x_test3D_normalize = x_test3D / 255
    #将label进行one hot转换
    y_trainOneHot = np_utils.to_categorical(y_train)
    y_testOneHot = np_utils.to_categorical(y_test)
    
    
    #建立一个Sequential线性堆叠模型
    model = Sequential()
    model.add(Conv1D(filters=16,
                     kernel_size=25,
                     padding = 'same',
                     input_shape = (784,1),
                     activation = 'relu'))
    model.add(MaxPooling1D(pool_size = 4))
    #建立卷积层2
    model.add(Conv1D(filters=10,
                     kernel_size=25,
                     padding = 'same',
                     activation = 'relu'))
    #建立池化层2
    model.add(MaxPooling1D(pool_size = 4))
    model.add(Dropout(0.25))
    #建立平坦层
    model.add(Flatten())
    #建立隐蔽层
    model.add(Dense(128,activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(10,activation='softmax'))
    print(model.summary())
    
    model.compile(loss='categorical_crossentropy',
                  optimizer='adam',metrics=['accuracy'])
    train_history=model.fit(x=x_train3D_normalize,
                            y=y_trainOneHot,validation_split=0.2,
                            epochs=30,batch_size=300,verbose=2)
    import matplotlib.pyplot as plt
    def show_train_history(train_history,train,validation):
        """
        显示训练过程
    
        参数:
            train_history - 训练结果存储的参数位置
            train - 训练数据的执行结果
            validation - 验证数据的执行结果
            
    """
        plt.plot(train_history.history[train])
        plt.plot(train_history.history[validation])
        plt.title('Train History')
        plt.ylabel(train)
        plt.xlabel('Epoch')
        plt.legend(['train','validation'],loc = 'upper left')
        plt.show()
        
    show_train_history(train_history,'acc','val_acc')
    show_train_history(train_history,'loss','val_loss')
    scores = model.evaluate(x_test3D_normalize,y_testOneHot)
    scores[1]
    
    展开全文
  • 在“卷积神经网络”中我们...其实,我们也可以将文本当作一维图像,从而可以用一维卷积神经网络来捕捉临近词之间的关联。TextCNN简介TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 《 Convolu...

    在“卷积神经网络”中我们探究了如何使用二维卷积神经网络来处理二维图像数据。在之前的语言模型和文本分类任务中,我们将文本数据看作是只有一个维度的时间序列,并很自然地使用循环神经网络来表征这样的数据。其实,我们也可以将文本当作一维图像,从而可以用一维卷积神经网络来捕捉临近词之间的关联。

    TextCNN简介

    TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 《 Convolutional Neural Networks for Sentence Classification 》中提出。

    TextCNN结构图:

    dba46a816608240bedff219b9372ee34.png

    第一层将单词嵌入到低维矢量中。下一层使用多个过滤器大小对嵌入的单词向量执行卷积。例如,一次滑动3,4或5个单词。接下来,将卷积层的结果最大池化为一个长特征向量,添加dropout正则,并使用softmax对结果进行分类。与传统图像的CNN网络相比, textCNN 在网络结构上没有任何变化(甚至更加简单了), 从图中可以看出textCNN 其实只有一层卷积,一层max-pooling, 最后将输出外接softmax 来n分类。

    与图像当中CNN的网络相比,textCNN 最大的不同便是在输入数据的不同:图像是二维数据, 图像的卷积核是从左到右, 从上到下进行滑动来进行特征抽取。自然语言是一维数据, 虽然经过word-embedding 生成了二维向量,但是对词向量做从左到右滑动来进行卷积没有意义. 比如 “今天” 对应的向量[0, 0, 0, 0, 1], 按窗口大小为 1* 2 从左到右滑动得到[0,0], [0,0], [0,0], [0, 1]这四个向量, 对应的都是”今天”这个词汇, 这种滑动没有帮助.

    TextCNN的成功, 不是网络结构的成功, 而是通过引入已经训练好的词向量来在多个数据集上达到了超越benchmark 的表现,进一步证明了构造更好的embedding, 是提升nlp 各项任务的关键能力。

    TextCNN最大优势网络结构简单 ,在模型网络结构如此简单的情况下,通过引入已经训练好的词向量依旧有很不错的效果,在多项数据数据集上超越benchmark。 网络结构简单导致参数数目少, 计算量少, 训练速度快,在单机单卡的v100机器上,训练165万数据, 迭代26万步,半个小时左右可以收敛。

    TextCNN 流程

    Word Embedding 分词构建词向量

    textcnn使用预先训练好的词向量作embedding layer。对于数据集里的所有词,因为每个词都可以表征成一个向量,因此我们可以得到一个嵌入矩阵M, M里的每一行都是词向量。这个M可以是静态(static)的,也就是固定不变。可以是非静态(non-static)的,也就是可以根据反向传播更新。

    如图所示, textCNN 首先将 “今天天气很好,出来玩” 分词成”今天/天气/很好/,/出来/玩, 通过word2vec或者GLOV 等embedding 方式将每个词成映射成一个5维(维数可以自己指定)词向量, 如 “今天” -> [0,0,0,0,1], “天气” ->[0,0,0,1,0], “很好” ->[0,0,1,0,0]等等。

    670afbcf1a76fdec19c9bbc47b35b2d9.png

    这样做的好处主要是将自然语言数值化,方便后续的处理。从这里也可以看出不同的映射方式对最后的结果是会产生巨大的影响, nlp 当中目前最火热的研究方向便是如何将自然语言映射成更好的词向量。我们构建完词向量后,将所有的词向量拼接起来构成一个6*5的二维矩阵,作为最初的输入。

    Convolution 卷积

    输入一个句子,首先对这个句子进行切词,假设有s个单词。对每个词,跟句嵌入矩阵M, 可以得到词向量。假设词向量一共有d维。那么对于这个句子,便可以得到s行d列的矩阵

    edb50766429279d53c745f170b663d5d.png

    。我们可以把矩阵A看成是一幅图像,使用卷积神经网络去提取特征。由于句子中相邻的单词关联性总是很高的,因此可以使用一维卷积。卷积核的宽度就是词向量的维度d,高度是超参数,可以设置。

    假设有一个卷积核,是一个宽度为d,高度为h的矩阵w,那么w有h∗d个参数需要被更新。对于一个句子,经过嵌入层之后可以得到矩阵

    77fbca4be74c10f8b3002b271646f707.png

    16e3e50b4fb482f42e3ed2219196a7d5.png

    表示A的第i行到第j行,那么卷积操作可以用如下公式表示:

    9b730053fc60abd96457247272f6f9ef.png

    叠加上偏置b,在使用激活函数f激活, 得到所需的特征。公式如下:

    52d0c1cb5afa7b01a1f83b03c5be33e6.png

    对一个卷积核,可以得到特征

    4e183fd7b7832860c61532ecab68010f.png

    , 总共个特征。我们可以使用更多高度不同的卷积核,得到更丰富的特征表达。

    df030416357546a8133409b4dee5c3c3.png

    卷积是一种数学算子。我们用一个简单的例子来说明一下

    • 1 将 “今天”/”天气”/”很好”/”,” 对应的4*5 矩阵 与卷积核做一个point wise 的乘法然后求和, 便是卷积操作
    • 2 将窗口向下滑动一格(滑动的距离可以自己设置),”天气”/”很好”/”,”/”出来” 对应的4*5 矩阵 与卷积核(权值不变) 继续做point wise 乘法后求和
    • 3 将窗口向下滑动一格(滑动的距离可以自己设置) “很好”/”,”/”出来”/”玩” 对应的4*5 矩阵 与卷积核(权值不变) 继续做point wise 乘法后求和

    feature_map 便是卷积之后的输出, 通过卷积操作 将输入的6*5 矩阵映射成一个 3*1 的矩阵,这个映射过程和特征抽取的结果很像,于是便将最后的输出称作feature map。一般来说在卷积之后会跟一个激活函数,在这里为了简化说明需要,我们将激活函数设置为f(x) = x

    channel

    abe4a60b3e10ef53dd63ad11c0143d39.png

    在CNN 中常常会提到一个词channel, 图中深红矩阵与浅红矩阵 便构成了两个channel 统称一个卷积核, 从这个图中也可以看出每个channel 不必严格一样, 每个4*5 矩阵与输入矩阵做一次卷积操作得到一个feature map. 在计算机视觉中,由于彩色图像存在 R, G, B 三种颜色, 每个颜色便代表一种channel。根据原论文作者的描述, 一开始引入channel 是希望防止过拟合(通过保证学习到的vectors 不要偏离输入太多)来在小数据集合获得比单channel更好的表现,后来发现其实直接使用正则化效果更好。不过使用多channel 相比与单channel, 每个channel 可以使用不同的word embedding, 比如可以在no-static(梯度可以反向传播) 的channel 来fine tune 词向量,让词向量更加适用于当前的训练。 对于channel在textCNN 是否有用, 从论文的实验结果来看多channels并没有明显提升模型的分类能力, 七个数据集上的五个数据集 单channel 的textCNN 表现都要优于 多channels的textCNN。

    0ec93854f43892ad19f8f327edc37b29.png

    我们在这里也介绍一下论文中四个model 的不同:

    • CNN-rand (单channel), 设计好 embedding_size 这个 Hyperparameter 后, 对不同单词的向量作随机初始化, 后续BP的时候作调整.
    • CNN-static(单channel), 拿 pre-trained vectors from word2vec, FastText or GloVe 直接用, 训练过程中不再调整词向量.
    • CNN-non-static(单channel), pre-trained vectors + fine tuning , 即拿word2vec训练好的词向量初始化, 训练过程中再对它们微调.
    • CNN-multiple channel(多channels), 类比于图像中的RGB通道, 这里也可以用 static 与 non-static 搭两个通道来做.

    Pooling 池化

    不同尺寸的卷积核得到的特征(feature map)大小也是不一样的,因此我们对每个feature map使用池化函数,使它们的维度相同。最常用的就是1-max pooling,提取出feature map照片那个的最大值。这样每一个卷积核得到特征就是一个值,对所有卷积核使用1-max pooling,再级联起来,可以得到最终的特征向量,这个特征向量再输入softmax layer做分类。这个地方可以使用drop out防止过拟合。

    bdae26e4c712a6a2c797ec172fba86de.png

    得到feamap = [1,1,2] 后, 从中选取一个最大值[2] 作为输出, 便是max-pooling。max-pooling 在保持主要特征的情况下, 大大降低了参数的数目, 从图中可以看出 feature map 从 三维变成了一维, 好处有如下两点:

    • 降低了过拟合的风险, feature map = [1, 1, 2] 或者[1, 0, 2] 最后的输出都是[2], 表明开始的输入即使有轻微变形, 也不影响最后的识别。
    • 参数减少, 进一步加速计算。

    pooling 本身无法带来平移不变性(图片有个字母A, 这个字母A 无论出现在图片的哪个位置, 在CNN的网络中都可以识别出来),卷积核的权值共享才能。max-pooling的原理主要是从多个值中取一个最大值,做不到这一点。cnn 能够做到平移不变性,是因为在滑动卷积核的时候,使用的卷积核权值是保持固定的(权值共享), 假设这个卷积核被训练的就能识别字母A, 当这个卷积核在整张图片上滑动的时候,当然可以把整张图片的A都识别出来。

    使用softmax k分类

    c0a49ba1c90c8be95a3ddd0be3e92133.png

    如图所示, 我们将 max-pooling的结果拼接起来, 送入到softmax当中, 得到各个类别比如 label 为1 的概率以及label 为-1的概率。如果是预测的话,到这里整个textCNN的流程遍结束了。如果是训练的话,此时便会根据预测label以及实际label来计算损失函数, 计算出softmax 函数,max-pooling 函数, 激活函数以及卷积核函数 四个函数当中参数需要更新的梯度, 来依次更新这四个函数中的参数,完成一轮训练。

    总结

    以上过程可以用下图直观表示:

    f9d4b300fcb263b574d3f2c4440190b9.png
    • 这里word embedding的维度是5。对于句子 i like this movie very much。可以转换成如上图所示的矩阵
    • 有6个卷积核,尺寸为(2×5)(2×5), (3×5)(3×5), 4×54×5,每个尺寸各2个.
    • AA分别与以上卷积核进行卷积操作,再用激活函数激活。每个卷积核都得到了特征向量(feature maps)
    • 使用1-max pooling提取出每个feature map的最大值,然后在级联得到最终的特征表达。
    • 将特征输入至softmax layer进行分类, 在这层可以进行正则化操作( l2-regulariation)

    使用Keras 搭建卷积神经网络来进行情感分析

    在自然语言领域,卷积的作用在于利用文字的局部特征。一个词的前后几个词必然和这个词本身相关,这组成该词所代表的词群。词群进而会对段落文字的意思进行影响,决定这个段落到底是正向的还是负向的。对比传统方法,利用词包,和TF-IDF 等,其思想有相通之处。但最大的不同点在于,传统方法是人为构造用于分类的特征,而深度学习中的卷积让神经网络去构造特征。以上便是卷积在自然语言处理中有着广泛应用的原因。接下来介绍如何利用Keras 搭建卷积神经网络来处理情感分析的分类问题。

    下面的代码构造了卷积神经网络的结构:

    from keras.layers import Dense, Dropout, Activation, Flattenfrom keras.layers import Conv1D, MaxPooling1Dfrom keras.models import Sequentialfrom keras.layers.embeddings import Embeddingfrom keras.datasets import imdbimport numpy as npfrom keras.preprocessing import sequence (X_train, y_train), (X_test, y_test) = imdb.load_data() max_word = 400X_train = sequence.pad_sequences(X_train, maxlen=max_word)X_test = sequence.pad_sequences(X_test, maxlen=max_word)vocab_size = np.max([np.max(X_train[i]) for i in range(X_train.shape[0])]) + 1  # 这里1 代表空格,其索引被认为是0。 model = Sequential()model.add(Embedding(vocab_size, 64, input_length=max_word))model.add(Conv1D(filters=64, kernel_size=3, padding='same', activation='relu'))model.add(MaxPooling1D(pool_size=2))model.add(Dropout(0.25))model.add(Conv1D(filters=128, kernel_size=3, padding='same', activation='relu'))model.add(MaxPooling1D(pool_size=2))model.add(Dropout(0.25))model.add(Flatten())model.add(Dense(64, activation='relu'))model.add(Dense(32, activation='relu'))model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])print(model.summary()) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=100)scores = model.evaluate(X_test, y_test, verbose=1)print(scores)

    整个模型的结构如下:

    Model: "sequential_1"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================embedding_1 (Embedding)      (None, 400, 64)           5669568   _________________________________________________________________conv1d_1 (Conv1D)            (None, 400, 64)           12352     _________________________________________________________________max_pooling1d_1 (MaxPooling1 (None, 200, 64)           0         _________________________________________________________________dropout_1 (Dropout)          (None, 200, 64)           0         _________________________________________________________________conv1d_2 (Conv1D)            (None, 200, 128)          24704     _________________________________________________________________max_pooling1d_2 (MaxPooling1 (None, 100, 128)          0         _________________________________________________________________dropout_2 (Dropout)          (None, 100, 128)          0         _________________________________________________________________flatten_1 (Flatten)          (None, 12800)             0         _________________________________________________________________dense_1 (Dense)              (None, 64)                819264    _________________________________________________________________dense_2 (Dense)              (None, 32)                2080      _________________________________________________________________dense_3 (Dense)              (None, 1)                 33        =================================================================Total params: 6,528,001Trainable params: 6,528,001Non-trainable params: 0_________________________________________________________________

    TextCNN的超参数调参

    在最简单的仅一层卷积的TextCNN结构中,下面的超参数都对模型表现有影响:

    • 初始化词向量。使用word2vec和golve都可以,不要使用one-hot vectors
    • 卷积核的尺寸。1-10之间,具体情况具体分析,对最终结果影响较大。一般来讲,句子长度越长,卷积核的尺寸越大。另外,可以在寻找到了最佳的单个filter的大小后,尝试在该filter的尺寸值附近寻找其他合适值来进行组合。实践证明这样的组合效果往往比单个最佳filter表现更出色
    • 每种尺寸卷积核的数量。100-600之间,对模型性能影响较大,需要注意的是增加卷积核的数量会增加训练模型的实践。主要考虑的是当增加特征图个数时,训练时间也会加长,因此需要权衡好。当特征图数量增加到将性能降低时,可以加强正则化效果,如将dropout率提高过5
    • 激活函数的选择。使用relu函数
    • drop out rate。0-0.5, 当增加卷积核的数量时,可以尝试增加drop out rate,甚至可以大于0.5
    • 池化的选择。1-max pooling表现最佳
    • 正则项。相对于其他超参数来说,影响较小点
    展开全文
  • 这个系列一开始曾经用二维卷积神经网络对图像数据进行应用,本文主要是使用一维卷积神经网络,对序列数据进行机器学习,可以理解为将原始数据变换为一维的序列段,与二维卷积神经网络一样,这一步运算的作用也是为了...

    f3893dabb083d87288a84699ab315c58.png

    这个系列记录下自己的深度学习练习,本文主要尝试了使用简单的卷积神经网络(CNN)解进行机器学习,因为数据样本贴合度可能不hi很好,实际效果并不是很明显。请读者理解原理就好,本人也是在不断摸索中。

    这个系列一开始曾经用二维卷积神经网络对图像数据进行应用,本文主要是使用一维卷积神经网络,对序列数据进行机器学习,可以理解为将原始数据变换为一维的序列段,与二维卷积神经网络一样,这一步运算的作用也是为了降低以为输入的长度(子采样)

    首先用之前的imdb数据实验效果,数据获取的代码如下,和之前一样:

    #数据处理
    
    

    一维卷积神经网络的架构和之前的二维卷积网络相同,略微有区别的是一维卷积网络的卷积窗口可以更大,因为卷积的特征向量是1维的。

    #建模并训练
    
    from keras.models import Sequential
    from keras.layers import Embedding, MaxPooling1D, Conv1D, GlobalMaxPool1D, Dense
    from keras.optimizers import RMSprop
    
    model = Sequential()
    model.add(Embedding(max_features, 128, input_length=maxlen)) #这是是用来增维,满足Conv层的输入需要。如果后面要接Dense层,最后的参数必须设置
    model.add(Conv1D(32,7, activation='relu')) #第一个参数是由输入数据生成的新维度长度(列),第二个参数是提取出一维序列段的长度
    model.add(MaxPooling1D(5))
    model.add(Conv1D(32,7, activation='relu'))
    model.add(GlobalMaxPool1D())
    model.add(Dense(1))
    
    model.summary()
    
    model.compile(optimizer=RMSprop(lr=1e-4), loss='binary_crossentropy',metrics=['accuracy'])
    history = model.fit(
        x_train, y_train,
        epochs = 10,
        batch_size = 128,
        validation_split = 0.2
    )

    学习结果(代码见之前文章):

    cde311db1148187dd45fd3523aa824f1.png

    可以看到训练的精度结果与LSTM差不多,但是速度明显要快一些。并且需要注意的是,结果有一定的随机性,验证集的结果仅供参考,一切结果肯定以测试集为主。

    结合CNN和RNN来处理长序列

    卷积神经网络是属于对时间顺序不敏感的类型,这点与RNN不同。

    首先先使用单纯的卷积神经网络训练下时间敏感的数据,以耶拿天气为例,数据使用之前的生成器:

    #用Conv1D尝试耶拿天气数据
    
    import pandas
    import numpy as np
    
    data_dir = './jena_climate_2009_2016.csv'
    df = pandas.read_csv(data_dir)
    
    df.drop(['Date Time'], axis=1, inplace=True)
    df_array = df.values
    
    mean = df_array[:200000].mean(axis=0)
    df_array -= mean
    std = df_array[:200000].std(axis=0)
    df_array /= std
    
    def generator(data, lookback, delay, min_index, max_index, shuffle=False, batch_size=128, step=6):
        '''
        data:标准化后的原始数据
        lookback:输入数据包括的过去时间步
        delay:目标应该在未来多少个时间步
        min_index, max_index: 数据的始末索引,用于抽取对应的训练集
        shuffle: 是打乱还是顺序抽取样本
        batch_size:每批量样本数
        step:数据采样周期(时间步)
        '''
        if max_index is None:
            max_index = len(data) - delay - 1
        i = min_index + lookback
        while 1:
            if shuffle:
                rows = np.random.randint(min_index + lookback, max_index, size=batch_size)
            else:
                if i + batch_size >= max_index:
                    i = min_index + lookback
                rows = np.arange(i, min(i+batch_size, max_index))
                i = i + len(rows)
    
            samples = np.zeros((len(rows), lookback//step, data.shape[-1]))
            targets = np.zeros((len(rows),))
            for j, row in enumerate(rows):
                indices = range(rows[j] - lookback, rows[j], step)
                samples[j] = data[indices]
                targets[j] = data[rows[j] + delay][1]
            yield samples, targets
            #返回samples是输入数据的一个批量,targets是对应的目标温度数组
            
    #准备训练生成器,验证生成器和测试生成器
    lookback = 1440 
    steps = 6 #每个steps里6个时间步
    delay = 144
    batch_size = 128
    
    train_gen = generator(df_array, lookback=lookback, delay=delay, min_index=0, max_index=200000, shuffle=True, step=steps)
    val_gen = generator(df_array, lookback=lookback, delay=delay, min_index=200001, max_index=300000, step=steps)
    test_gen = generator(df_array, lookback=lookback, delay=delay, min_index=300001, max_index=None, step=steps)
    
    val_steps = (300000 - 200001 - lookback) // batch_size 
    test_steps = (len(df_array) - 300001 - lookback) // batch_size 
    #建模并训练
    
    from keras.models import Sequential
    from keras.layers import Embedding, MaxPooling1D, Conv1D, GlobalMaxPool1D, Dense
    from keras.optimizers import RMSprop
    
    model = Sequential()
    #model.add(Embedding(max_features, 128, input_length=maxlen)) #这是是用来增维,满足Conv层的输入需要。如果后面要接Dense层,最后的参数必须设置
    model.add(Conv1D(32,5, activation='relu', input_shape=(None, df_array.shape[-1]))) #第一个参数是由输入数据生成的新维度长度(列),第二个参数是提取出一维序列段的长度
    model.add(MaxPooling1D(3))
    model.add(Conv1D(32,5, activation='relu'))
    model.add(MaxPooling1D(3))
    model.add(Conv1D(32,5, activation='relu'))
    model.add(GlobalMaxPool1D())
    model.add(Dense(1))
    
    model.summary()
    
    model.compile(optimizer=RMSprop(lr=1e-4), loss='mae', metrics=['accuracy'])
    history = model.fit_generator(
        train_gen,
        steps_per_epoch = 500,
        epochs = 20,
        validation_data = val_gen,
        validation_steps = val_steps
    )

    学习结果:

    180e0105d3cc288116b687fb9c804cf9.png

    可以看出学习结果非常差,甚至低于基于常识的判断(0.29),所以说卷积网络并不适合对时间敏感的数据集。

    下面尝试下RNN和CNN的结合使用。我自己尝试了下在RNN前面使用CNN作为预处理步骤,因为RNN对于长序列的处理并不好。前面的耶拿数据,我们每次只分析前720或1440时间步的数据,这次的话可以使用增大lookback参数或减小步长来增大数据。

    #准备训练生成器,验证生成器和测试生成器
    lookback = 1440 
    steps = 3 #减少每个steps里的时间步,减一半
    delay = 144
    batch_size = 128
    
    train_gen = generator(df_array, lookback=lookback, delay=delay, min_index=0, max_index=200000, shuffle=True, step=steps)
    val_gen = generator(df_array, lookback=lookback, delay=delay, min_index=200001, max_index=300000, step=steps)
    test_gen = generator(df_array, lookback=lookback, delay=delay, min_index=300001, max_index=None, step=steps)
    
    val_steps = (300000 - 200001 - lookback) // batch_size #为了查看整个验证集,需要从val_gen中抽取多少次
    test_steps = (len(df_array) - 300001 - lookback) // batch_size #为了查看整个测试集,需要从test_gen中抽取多少次

    下面是模型,使用两个Conv1层和一个GRU层

    #组合建模学习
    
    from keras.models import Sequential
    from keras.layers import Embedding, MaxPooling1D, Conv1D, GlobalMaxPool1D, Dense, GRU
    from keras.optimizers import RMSprop
    
    model = Sequential()
    model.add(Conv1D(32,5, activation='relu', input_shape=(None, df_array.shape[-1]))) #第一个参数是由输入数据生成的新维度长度(列),第二个参数是提取出一维序列段的长度
    model.add(MaxPooling1D(3))
    model.add(Conv1D(32,5, activation='relu'))
    #model.add(MaxPooling1D(3))
    model.add(GRU(32, dropout=0.1, recurrent_dropout=0.5))
    #model.add(GlobalMaxPool1D())
    model.add(Dense(1))
    
    model.summary()
    
    model.compile(optimizer=RMSprop(lr=1e-4), loss='mae', metrics=['accuracy'])
    history = model.fit_generator(
        train_gen,
        steps_per_epoch = 500,
        epochs = 20,
        validation_data = val_gen,
        validation_steps = val_steps
    )

    学习结果:

    ce22278c8d2f29c65e339040277e1456.png

    从验证损失看,结果可能比使用正则化的GRU算法稍微差一些,但速度要快很多,且查看了2倍的数据量,在本例中可能不是非常有用,但对于其他数据集效果可能不错。

    这次简单就先到这里吧,虽然结果并不是很理想,可能是数据集不太合适问题,大家明白方法的使用就好。我自己也是在慢慢学习,基本上简单的keras模型构建就是这么多了,其实最麻烦的步骤还是构建数据集。之后可能会再写写keras的函数式API应用。如有不明白的地方可以在评论或私信里讨论学习。

    展开全文
  • CNN图像识别原理卷积神经网络(CNN...卷积神经网络也是类似,它包含了至少层卷积层,由多个卷积核对图像的局部区域进行特征提取,最后进行合成。以经典的LeNet-5模型为例:原始输入数据(图中的input)为二图像...

    5a9b7b0b0aabf80dc436c446536dc7ea.png

    CNN图像识别原理

    卷积神经网络(CNN)的结构模仿了眼睛的视觉神经的工作原理。对于眼睛来说,大量的视觉神经分工协作,各自负责一小部分区域的视觉图像,再将图像的各种局部特征抽象组合到高层的视觉概念,传送到大脑使人类产生视觉。卷积神经网络也是类似,它包含了至少一层卷积层,由多个卷积核对图像的局部区域进行特征提取,最后进行合成。

    以经典的LeNet-5模型为例:

    563202d5b514321c7939957b155151eb.png

    原始输入数据(图中的input)为二维图像,横轴和纵轴分别是图像的高度和宽度的像素点,为了识别该图像,模型依次完成以下步骤:

    • 第一层卷积层(图中的conv1)进行卷积运算。该层由若干卷积核组成,每个卷积核的参数都是通过反向传播算法优化得到的。卷积核的目的是通过扫描整张图片提取不同特征,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等层级。在卷积层之后都会使用非线性激活函数(如RELU,tanh 等)对特征进行非线性变换。
    • 第一层池化层(图中的pool1)进行池化运算。通常在卷积层之后会得到维度很大的特征,池化层可以非常有效地缩小参数矩阵的尺寸,从而减少最后全连层中的参数数量。使用池化层既可以加快计算速度也有防止过拟合的作用。一般池化层将特征切成几个区域,取其最大值或平均值,得到新的、维度较小的特征。池化层其实是在对具有高维特征的图片进行特征降维(subsample)
    • 第二层卷积层和第二层池化层(图中的conv2 和pool2) 进行进一步的特征提取和特征降维,得到更加高层和抽象的特征。
    • 全连接层(图中的hidden4 和full connection) 把卷积核池化得到的特征展平为一维特征,用来进行最后的训练和预测。

    总结而言,卷积层进行特征提取,池化层进行特征降维以防止过拟合。CNN通过上述过程实现了图像识别:

    bdfe7d42aba1d8d004ce53fc135c5c95.png

    通过第一层卷积识别边缘等低级特征,池化后通过第二层卷积识别眼睛、鼻子等小区域器官这样的中级特征,池化,最后通过第三层卷积识别整个面容这样的高级特征,最后通过全连接层整合,识别出最终的图像。

    用卷积神经网络处理序列数据

    从上面我们已经知道卷积神经网络(convnet)在计算机视觉问题上表现出色,原因在于它能够进行卷积运算,从局部输入图块中提取特征,并能够将表示模块化,同时可以高效地利用数据。这些性质让卷积神经网络在计算机视觉领域表现优异,同样也让它对序列处理特别有效。时间可以被看作一个空间维度,就像二维图像的高度或宽度。

    对于某些序列处理问题,比如金融时间序列数据,这种一维卷积神经网络的效果可以媲美RNN[循环神经网络],而且计算代价通常要小很多。最近,一维卷积神经网络[通常与空洞卷积核(dilated kernel)一起使用]已经在音频生成和机器翻译领域取得了巨大成功。除了这些具体的成就,人们还早已知道,对于文本分类和时间序列预测等简单任务,小型的一维卷积神经网络可以替代RNN,而且速度更快。

    理解序列数据的一维卷积

    通常我们遇见的卷积层都是二维卷积,从图像张量中提取二维图块并对每个图块应用相同的变换。按照同样的方法,你也可以使用一维卷积,从序列中提取局部一维序列段(即子序列),见下图:

    f4bdefd52dc461f6a35f95f6015fe596.png
    注:图片来自《Deep Learning with Python》弗朗索瓦·肖莱,Keras之父

    这种一维卷积层可以识别序列中的局部模式。因为对每个序列段执行相同的输入变换,所以在句子中某个位置学到的模式稍后可以在其他位置被识别,这使得一维卷积神经网络具有平移不变性(对于时间平移而言)。

    举个例子,使用大小为 5 的卷积窗口处理字符序列的一维卷积神经网络,应该能够学习长度不大于 5 的单词或单词片段,并且应该能够在输入句子中的任何位置识别这些单词或单词段。因此,字符级的一维卷积神经网络能够学会单词构词法。在金融时序预测中,卷积网络可以提取近期时序特征(局部特征)来预测短期走势,这是浅层机器学习模型不具备的优势。

    序列数据的一维池化

    二维池化运算,比如二维平均池化和二维最大池化,在卷积神经网络中用于对图像张量进行空间下采样。一维也可以做相同的池化运算:从输入中提取一维序列段(即子序列), 然后输出其最大值(最大池化)或平均值(平均池化)。与二维卷积神经网络一样,该运算也是用于降低一维输入的长度(子采样)。

    实现一维卷积神经网络

    BigQuant中的一维卷积神经网络是Conv1D层,其接口类似于Conv2D。它接收的输入是形状为 (samples, time, features)的三维张量,并返回类似形状的三维张量。卷积窗口是时间轴上的一维窗口(时间轴是输入张量的第二个轴)。
    我们来构建一个简单的两层一维卷积神经网络预测股票价格,回测结果图如下,源代码见文末。

    97a6b53af2ed81497ec0c090b4496ab4.png

    策略比较基准

    为比较深度学习模型的预测效果,我们以默认可视化机器学习模板为基准进行比较,默认可视化机器学习模板是StockRanker的浅层机器学习策略。
    因此,本文的训练集时间、预测集时间、特征完全和默认可视化策略模板一致。基准回测结果如下:

    4fe54bc686dec4a828ea63cfa114e569.png

    可以看出基于卷积神经网络的深度学习策略有明显的提升效果,策略年化收益从109%提升到118%,夏普比率也有所提升,这确实是很amazing的一件事情,因为stockranker策略的参数和模型我们是经过大量的测试给出了一个比较通用的版本,这主要得益于深度网络多层表示的强大学习能力,这和我们大脑大量的神经元机制是相似的。当然,本文只是一个demo,更多开发和提升还需依赖每一位developer.

    完整策略可视化

    328dffe3e74fc519e54997488bcc2bef.png

    • 实现平台:BigQuant—人工智能量化投资平台
    • 源码地址:《深度学习因子选股模型-基于卷积神经网络》

    参考文献:

    • 《Deep Learning with Python 》弗朗索瓦·肖莱,Keras之父
    • A Comprehensive Guide to Convolutional Neural Networks

    更多机器学习与量化投资知识尽在BigQuant社区:AI量化投资社区 - BigQuant

    展开全文
  • 一维卷积神经网络在维度S上进行卷积 如下,设置一维卷积网络的输入通道为16维,输出通道为33维,卷积核大小为3,步长为2 # in_channels: 16 # out_channels: 33 # kernel_size: 3 m = nn.Conv1d(16, 33, 3, ...
  • 文章目录卷积神经网络意义案例演示数据准备卷积层、池化层全连接层计算损失值初始化optimizer指定迭代次数,并在session执行graph完整代码如下卷积神经网络意义对于MNIST数据集来说,采用逻辑回归对数据进行辨别似乎...
  • 目的:针对传统机器学习算法对于流量分类的瓶颈问题,提出基于一维卷积神经网络模型的应用程序流量分类算法。 数据集:ICSX VPN-nonVPN 特征:数据预处理工具“USTC-TK2016, 本文选择同文献[12]相同的前784 Byte,...
  • 使用KITTI点云数据进行测试,结果表明:所提三点云多特征卷积神经网络语义分割方法的效果优于SqueezeSeg V2等没有结合点云特征的语义分割方法;与SqueezeSeg V2网络相比,所提方法对车辆、自行车和行人分割的精确率...
  • 文章目录基于一维卷积神经网络的滚动轴承故障识别一、数据预处理二、模型搭建三、使用步骤1.引入库2.读入数据总结 一、数据预处理 采用美国凯斯西储大学(CWRU) 的开放轴承数据库的样本进行实验分析,轴承故障产生的...
  • 在填充锯齿状空洞的卷积通路上构建并行三维卷积神经网络,提取多尺度图像块进行训练,捕获大范围空间信息。利用密集连接的恒等映射特性,将浅层特征叠加到网络末端,在MRI多模态图像中分割出水肿区、增强区、核心区和囊...
  • 原标题:R语言实现CNN(卷积神经网络)模型进行回归数据分析原文链接:http://tecdat.cn/?p=18149当我们将CNN(卷积神经网络)模型用于训练多维...视频:R语言实现CNN(卷积神经网络)模型进行回归数据分析我们使用一维...
  • 据了解rest-net从图像分类大赛上表现优异,那么将rest-net进行降维用于一维数据分类会有怎样表现? 先观察一下Rest-net的结构:由于每个截图有限,所以使用多个图片表现出?????????????????????????????????????????...
  • 我所采用的数据集,是我自己构建的网络流量数据集,借鉴了Wei Wang等人端到端的思想, 但是处理成的数据集却不同于他们的MNIST型数据集,而是采用的npy进行存储。 由于只是用于测试模型搭建,该数据集仅包含了...
  • 卷积神经网络

    2019-05-23 21:09:38
    文章目录卷积神经网络卷积一维卷积二维卷积卷积神经网络典型的卷积神经网络池化Text-CNN原理输入层卷积层池化层全连接层经典示例讲解Text-CNN对imdb数据进行情感分析参考资料 卷积神经网络 目前的卷积神经网络一般...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 313
精华内容 125
关键字:

一维数据进行卷积神经网络