精华内容
参与话题
问答
  • 使用textCNN进行文本分类的原理

    万次阅读 2018-06-27 20:56:39
    CNN在计算机视觉领域取得了很好的结果,同时它可以应用在文本分类上面。 文本分类的关键在于准确提炼文档或者句子的中心思想,而提炼中心思想的方法是抽取文档或句子的关键词作为特征,基于这些特征去训练分类器并...

    CNN在计算机视觉领域取得了很好的结果,同时它可以应用在文本分类上面。
    文本分类的关键在于准确提炼文档或者句子的中心思想,而提炼中心思想的方法是抽取文档或句子的关键词作为特征,基于这些特征去训练分类器并分类。因为CNN的卷积和池化过程就是一个抽取特征的过程,当我们可以准确抽取关键词的特征时,就能准确的提炼出文档或句子的中心思想。
    卷积神经网络首次应用于文本分类可以说是在2014年Yoon Kim 在 “Convolutional Neural Networks for Sentence Classification” 一文中提出(虽然第一个用的并不是他,但是在这篇文章中提出了4种Model Variations,并有详细的调参),本文也是基于对这篇文章的理解。接下来将介绍text-CNN模型。

    text-CNN模型

    这里写图片描述
    论文使用的模型主要包括五层,第一层是embedding layer,第二层是convolutional layer,第三层是max-pooling layer,第四层是fully connected layer,最后一层是softmax layer.
    下图具体展示了如何使用cnn进行句子分类。
    这里写图片描述

    输入层

    首先输入一个一维的由7个单词构成的句子,为了使其可以进行卷积,首先需要将其转化为二维矩阵表示,通常使用word2vec、glove等word embedding实现。d=5表示每个词转化为5维的向量,矩阵的形状是[sentence_matrix × 5],即[7 × 5]。

    卷积层

    在处理图像数据时,CNN使用的卷积核的宽度和高度的一样的,但是在text-CNN中,卷积核的宽度是与词向量的维度一致。这是因为我们输入的每一行向量代表一个词,在抽取特征的过程中,词做为文本的最小粒度,如果我们使用卷积核的宽度小于词向量的维度就已经不是以词作为最小粒度了。而高度和CNN一样,可以自行设置(通常取值2,3,4,5)。由于我们的输入是一个句子,句子中相邻的词之间关联性很高,因此,当我们用卷积核进行卷积时,不仅考虑了词义而且考虑了词序及其上下文。(类似于skip-gram和CBOW模型的思想)。
    详细讲解卷积的过程:卷积层输入的是一个表示句子的矩阵,维度为n*d,即每句话共有n个词,每个词有一个d维的词向量表示。假设Xi:i+j表示Xi到Xi+j个词,使用一个宽度为d,高度为h的卷积核W与Xi:i+h-1(h个词)进行卷积操作后再使用激活函数激活得到相应的特征ci,则卷积操作可以表示为:(使用点乘来表示卷积操作)
    这里写图片描述
    因此经过卷积操作之后,可以得到一个n-h+1维的向量c形如:
    这里写图片描述
    以上是一个卷积核与输入句子的卷积操作,同样的,我们也可以使用更多高度不同的卷积核,且每个高度的卷积核多个,得到更多不同特征。
    如上图,这里有(2,3,4)三种size,每种size有两个filter,一共有6个filter。然后开始卷积,从图中可以看出,stride是1,对于高是4的filter,最后生成4维的向量,(7-4)/1+1=4。对于高是3的filter,最后生成5维的向量,(7-3)/1+1=5。

    窄卷积 vs 宽卷积

    在矩阵的中部使用卷积核滤波没有问题,在矩阵的边缘,如对于左侧和顶部没有相邻元素的元素,该如何滤波呢?解决的办法是采用补零法(zero-padding)。所有落在矩阵范围之外的元素值都默认为0。这样就可以对输入矩阵的每一个元素做滤波了,输出一个同样大小或是更大的矩阵。补零法又被称为是宽卷积,不使用补零的方法则被称为窄卷积。1D的例子如图所示:
    这里写图片描述
    滤波器长度为5,输入长度为7。当滤波器长度相对输入向量的长度较大时,你会发现宽卷积很有用,或者说很有必要。在上图中,窄卷积输出的长度是 (7-5)+1=3,宽卷积输出的长度是(7+2*4-5)+1=11。

    步长

    在文献中我们常常见到的步长是1,但选择更大的步长会让模型更接近于递归神经网络,其结构就像是一棵树。

    池化层

    池化的特点之一就是它输出一个固定大小的矩阵,还能降低输出结果的维度,(理想情况下)却能保留显著的特征。
    因为在卷积层过程中我们使用了不同高度的卷积核,使得我们通过卷积层后得到的向量维度会不一致,所以在池化层中,我们使用1-Max-pooling对每个特征向量池化成一个值,即抽取每个特征向量的最大值表示该特征,而且认为这个最大值表示的是最重要的特征。当我们对所有特征向量进行1-Max-Pooling之后,还需要将每个值给拼接起来。得到池化层最终的特征向量。在池化层到全连接层之前可以加上dropout防止过拟合。
    如上图,每个filter最后得到两个特征。将所有特征合并后,使用softmax进行分类。图中没有用到chanel,下文的实验将会使用两个通道,static和non-static,有相关的具体解释。
    ####NLP中CNN常见的Pooling方法

    1. Max Pooling Over Time
      MaxPooling Over Time是NLP中CNN模型中最常见的一种下采样操作。意思是对于某个Filter抽取到若干特征值,只取其中得分最大的那个值作为Pooling层保留值,其它特征值全部抛弃,值最大代表只保留这些特征中最强的,而抛弃其它弱的此类特征。
      这里写图片描述
      如上文所述,CNN中采用Max Pooling操作有几个好处:首先,这个操作可以保证特征的位置与旋转不变性,对于图像处理来说这种位置与旋转不变性是很好的特性,但是对于NLP来说,这个特性其实并不一定是好事,因为在很多NLP的应用场合,特征的出现位置信息是很重要的,比如主语出现位置一般在句子头,宾语一般出现在句子尾等等,这些位置信息其实有时候对于分类任务来说还是很重要的,但是Max Pooling 基本把这些信息抛掉了。其次,MaxPooling能减少模型参数数量,有利于减少模型过拟合问题。再者,对于NLP任务来说,Max Pooling可以把变长的输入X整理成固定长度的输入。
      但是,CNN模型采取MaxPooling Over Time也有一些值得注意的缺点:首先就如上所述,特征的位置信息在这一步骤完全丢失。在卷积层其实是保留了特征的位置信息的,但是通过取唯一的最大值,现在在Pooling层只知道这个最大值是多少,但是其出现位置信息并没有保留;另外一个明显的缺点是:有时候有些强特征会出现多次,比如我们常见的TF.IDF公式,TF就是指某个特征出现的次数,出现次数越多说明这个特征越强,但是因为Max Pooling只保留一个最大值,所以即使某个特征出现多次,现在也只能看到一次,就是说同一特征的强度信息丢失了。这是Max Pooling Over Time典型的两个缺点。

    2. K-Max Pooling
      K-MaxPooling的意思是:原先的Max Pooling Over Time从Convolution层一系列特征值中只取最强的那个值,那么我们思路可以扩展一下,K-Max Pooling可以取所有特征值中得分在Top –K的值,并保留这些特征值原始的先后顺序(下图是2-max Pooling的示意图),就是说通过多保留一些特征信息供后续阶段使用。
      这里写图片描述
      很明显,K-Max Pooling可以表达同一类特征出现多次的情形,即可以表达某类特征的强度;另外,因为这些Top K特征值的相对顺序得以保留,所以应该说其保留了部分位置信息,但是这种位置信息只是特征间的相对顺序,而非绝对位置信息。

    3.Chunk-Max Pooling
    Chunk-MaxPooling的思想是:把某个Filter对应的Convolution层的所有特征向量进行分段,切割成若干段后,在每个分段里面各自取得一个最大特征值,比如将某个Filter的特征向量切成3个Chunk,那么就在每个Chunk里面取一个最大值,于是获得3个特征值。(如下图所示,不同颜色代表不同分段)
    这里写图片描述
    K-Max Pooling是一种全局取Top K特征的操作方式,而Chunk-Max Pooling则是先分段,在分段内包含特征数据里面取最大值,所以其实是一种局部Top K的特征抽取方式。
    至于这个Chunk怎么划分,可以有不同的做法,比如可以事先设定好段落个数,这是一种静态划分Chunk的思路;也可以根据输入的不同动态地划分Chunk间的边界位置,可以称之为动态Chunk-Max方法(非正式称谓)。
    Chunk-Max Pooling很明显也是保留了多个局部Max特征值的相对顺序信息,尽管并没有保留绝对位置信息,但是因为是先划分Chunk再分别取Max值的,所以保留了比较粗粒度的模糊的位置信息;当然,如果多次出现强特征,则也可以捕获特征强度。

    全连接层

    全连接层跟其他模型一样,假设有两层全连接层,第一层可以加上relu作为激活函数,对于多分类来说,第二层则使用softmax激活函数得到属于每个类的概率,并选择categorical_crossentropy 作为激活函数。如果处理的数据集为二分类问题,如情感分析的正负面时,第二层也可以使用sigmoid作为激活函数,然后损失函数使用对数损失函数binary_crossentropy
    如上图,激活函数为softmax得到2个类别的概率。

    通道

    我们需要了解的最后一个概念是通道。通道即是输入数据的不同“视角”。比如说,做图像识别时一般会用到RGB通道(红绿蓝)。你可以对每个通道做卷积运算,赋予相同或不同的权值。你也同样可以把NLP想象成有许多个通道:把不同类的词向量表征(例如word2vec和GloVe)看做是独立的通道,或是把不同语言版本的同一句话看作是一个通道。
    在词向量构造方面可以有以下不同的方式:

    • CNN-rand: 随机初始化每个单词的词向量通过后续的训练去调整。
    • CNN-static: 使用预先训练好的词向量,如word2vec训练出来的词向量,在训练过程中不再调整该词向量。
    • CNN-non-static: 使用预先训练好的词向量,并在训练过程进一步进行调整。
    • CNN-multichannel: 将static与non-static作为两通道的词向量。

    论文中采用了单通道和多通道两种方式。
    ##总结
    搭建一个CNN模型结构需要选择许多个超参数,上文中已经提到了一些:输入表征(word2vec, GloVe, one-hot),卷积滤波器的数量和尺寸,池化策略(最大值、平均值),以及激活函数(ReLU, tanh)。文献Zhang, Y., & Wallace, B. (2015). A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification,通过多次重复实验,比较了不同超参数对CNN模型结构在性能和稳定性方面的影响。如果你想自己实现一个CNN用于文本分类,可以借鉴该论文的结果。其主要的结论有最大池化效果总是好于平均池化;选择理想的滤波器尺寸很重要,但也根据任务而定需;正则化在NLP任务中的作用并不明显。需要注意的一点是该研究所用文本集里的文本长度都相近,因此若是要处理不同长度的文本,上述结论可能不具有指导意义。

    参考:
    论文《Convolutional Neural Networks for Sentence Classification》
    使用Keras进行深度学习:(三)使用text-CNN处理自然语言(下)(论文的解读和Keras实现,非常有用)
    基于tensorflow的cnn文本分类(论文解读和tensorflow实现)
    Understanding Convolutional Neural Networks for NLP(详细解读,非常有用)
    卷积神经网络在自然语言处理的应用(上文的翻译)
    自然语言处理中CNN模型几种常见的Max Pooling操作(详细)

    展开全文
  • TextCNN文本分类(keras实现)

    万次阅读 多人点赞 2019-03-26 19:23:46
    目录 前言: 一、论文笔记 二、Keras文本预处理 1、读取数据集 ...三、基于keras的TextCNN模型的构建、训练与测试 1、基础版CNN(模仿LeNet-5) 2、简单版TextCNN 3、使用Word2Vec词向量...

    目录

    前言:

    一、论文笔记

    二、Keras文本预处理

    1、读取数据集

    2、将文字转换成数字特征

    3、将每条文本转换为数字列表

    4、将每条文本设置为相同长度

    5、将每个词编码转换为词向量

    6、Keras文本预处理代码实现

    三、基于keras的TextCNN模型的构建、训练与测试

    1、基础版CNN(模仿LeNet-5)

    2、简单版TextCNN

    3、使用Word2Vec词向量的TextCNN

    四、绘制TextCNN模型结构图

    1、环境配置

    2、绘制模型图

    五、keras模型的保存与加载


    前言:

    深度学习模型在计算机视觉语音识别方面取得了卓越的成就,在 NLP 领域也是可以的。将卷积神经网络CNN应用到文本分类任务,利用多个不同size的kernel来提取句子中的关键信息(类似 n-gram 的关键信息,从而能够更好地捕捉局部相关性。

    文本分类是自然语言处理领域最活跃的研究方向之一,目前文本分类在工业界的应用场景非常普遍,从新闻的分类、商品评论信息的情感分类到微博信息打标签辅助推荐系统,了解文本分类技术是NLP初学者比较好的切入点,较简单且应用场景高频。

    一、论文笔记

    1、Yoon Kim在2014年 “Convolutional Neural Networks for Sentence Classification” 论文中提出TextCNN(利用卷积神经网络对文本进行分类的算法)(该论文翻译)。

    上图很好地诠释了模型的框架。假设我们有一些句子需要对其进行分类。句子中每个词是由n维词向量组成的,也就是说输入矩阵大小为m*n,其中m为句子长度。CNN需要对输入样本进行卷积操作,对于文本数据,filter不再横向滑动,仅仅是向下移动,有点类似于N-gram在提取词与词间的局部相关性。图中共有三种步长策略,分别是2,3,4,每个步长都有两个filter(实际训练时filter数量会很多)。在不同词窗上应用不同filter,最终得到6个卷积后的向量。然后对每一个向量进行最大化池化操作并拼接各个池化值,最终得到这个句子的特征表示,将这个句子向量丢给分类器进行分类,至此完成整个流程。

    (1)嵌入层(Embedding Layer)

    通过一个隐藏层, 将 one-hot 编码的词投影到一个低维空间中,本质上是特征提取器,在指定维度中编码语义特征。 这样, 语义相近的词, 它们的欧氏距离或余弦距离也比较近。(作者使用的单词向量是预训练的,方法为fasttext得到的单词向量,当然也可以使用word2vec和GloVe方法训练得到的单词向量)。

    (2)卷积层(Convolution Laye)

    在处理图像数据时,CNN使用的卷积核的宽度和高度的一样的,但是在text-CNN中,卷积核的宽度是与词向量的维度一致!这是因为我们输入的每一行向量代表一个词,在抽取特征的过程中,词做为文本的最小粒度。而高度和CNN一样,可以自行设置(通常取值2,3,4,5),高度就类似于n-gram了。由于我们的输入是一个句子,句子中相邻的词之间关联性很高,因此,当我们用卷积核进行卷积时,不仅考虑了词义而且考虑了词序及其上下文(类似于skip-gram和CBOW模型的思想)。

    (3)池化层(Pooling Layer)

    因为在卷积层过程中我们使用了不同高度的卷积核,使得我们通过卷积层后得到的向量维度会不一致,所以在池化层中,我们使用1-Max-pooling对每个特征向量池化成一个值,即抽取每个特征向量的最大值表示该特征,而且认为这个最大值表示的是最重要的特征。当我们对所有特征向量进行1-Max-Pooling之后,还需要将每个值给拼接起来。得到池化层最终的特征向量。在池化层到全连接层之前可以加上dropout防止过拟合。

    (4)全连接层(Fully connected layer)

    全连接层跟其他模型一样,假设有两层全连接层,第一层可以加上’relu’作为激活函数,第二层则使用softmax激活函数得到属于每个类的概率。

    (5)TextCNN的小变种

    在词向量构造方面可以有以下不同的方式: CNN-rand: 随机初始化每个单词的词向量通过后续的训练去调整。 CNN-static: 使用预先训练好的词向量,如word2vec训练出来的词向量,在训练过程中不再调整该词向量。 CNN-non-static: 使用预先训练好的词向量,并在训练过程进一步进行调整。 CNN-multichannel: 将static与non-static作为两通道的词向量。

    (6)参数与超参数

    • sequence_length (Q: 对于CNN, 输入与输出都是固定的,可每个句子长短不一, 怎么处理? A: 需要做定长处理, 比如定为n, 超过的截断, 不足的补0. 注意补充的0对后面的结果没有影响,因为后面的max-pooling只会输出最大值,补零的项会被过滤掉)
    • num_classes (多分类, 分为几类)
    • vocabulary_size (语料库的词典大小, 记为|D|)
    • embedding_size (将词向量的维度, 由原始的 |D| 降维到 embedding_size)
    • filter_size_arr (多个不同size的filter)

    2、2015年“A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification”论文详细地阐述了关于TextCNN模型的调参心得。

    (1)TextCNN详细过程:

    • Embedding:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点。
    • Convolution:然后经过 kernel_sizes=(2,3,4) 的一维卷积层,每个kernel_size 有两个输出 channel。
    • MaxPolling:第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示。
    • FullConnection and Softmax:最后接一层全连接的 softmax 层,输出每个类别的概率。

    (2)论文调参结论:

    • 使用预训练的word2vec 、 GloVe初始化效果会更好。一般不直接使用One-hot。
    • 卷积核的大小影响较大,一般取1~10,对于句子较长的文本,则应选择大一些。
    • 卷积核的数量也有较大的影响,一般取100~600 ,同时一般使用Dropout(0~0.5)。
    • 激活函数一般选用ReLU 和 tanh。
    • 池化使用1-max pooling。
    • 随着feature map数量增加,性能减少时,试着尝试大于0.5的Dropout。
    • 评估模型性能时,记得使用交叉验证。

    二、Keras文本预处理

    1、读取数据集

    2、将文字转换成数字特征

    使用Tokenizer将文字转换成数字特征

    使用Keras的Tokenizer模块实现转换。当我们创建了一个Tokenizer对象后,使用该对象的fit_on_texts()函数,可以将输入的文本中的每个词编号,编号是根据词频的,词频越大,编号越小。使用word_index属性可以看到每次词对应的编码。

    3、将每条文本转换为数字列表

    将数据集中的每条文本转换为数字列表,使用每个词的编号进行编号

    使用该对象的texts_to_sequences()函数,将每条文本转变成一个向量。 

    4、将每条文本设置为相同长度

    使用pad_sequences()让每句数字影评长度相同

    由于每句话的长度不唯一,需要将每句话的长度设置一个固定值。将超过固定值的部分截掉,不足的在最前面用0填充。

    5、将每个词编码转换为词向量

    使用Embedding层将每个词编码转换为词向量

    Embedding层基于上文所得的词编码,对每个词进行one-hot编码,每个词都会是一个vocabulary_size维的向量;然后通过神经网络的训练迭代更新得到一个合适的权重矩阵(具体实现过程可以参考skip-gram模型),行大小为vocabulary_size,列大小为词向量的维度,将本来以one-hot编码的词向量映射到低维空间,得到低维词向量。需要声明一点的是Embedding层是作为模型的第一层,在训练模型的同时,得到该语料库的词向量。当然,也可以使用已经预训练好的词向量表示现有语料库中的词。

    文本预处理目的:将每个样本转换为一个数字矩阵,矩阵的每一行表示一个词向量。

    6、Keras文本预处理代码实现

    from sklearn.model_selection import train_test_split
    import pandas as pd
    import jieba
    from keras.preprocessing.text import Tokenizer
    from keras.preprocessing.sequence import pad_sequences
    
    if __name__=='__main__':
        dataset = pd.read_csv('sentiment_analysis/data_train.csv', sep='\t',names=['ID', 'type', 'review', 'label']).astype(str)
        cw = lambda x: list(jieba.cut(x))
        dataset['words'] = dataset['review'].apply(cw)
        tokenizer=Tokenizer()  #创建一个Tokenizer对象
        #fit_on_texts函数可以将输入的文本中的每个词编号,编号是根据词频的,词频越大,编号越小
        tokenizer.fit_on_texts(dataset['words'])
        vocab=tokenizer.word_index #得到每个词的编号
        x_train, x_test, y_train, y_test = train_test_split(dataset['words'], dataset['label'], test_size=0.1)
        # 将每个样本中的每个词转换为数字列表,使用每个词的编号进行编号
        x_train_word_ids=tokenizer.texts_to_sequences(x_train)
        x_test_word_ids = tokenizer.texts_to_sequences(x_test)
        #序列模式
        # 每条样本长度不唯一,将每条样本的长度设置一个固定值
        x_train_padded_seqs=pad_sequences(x_train_word_ids,maxlen=50) #将超过固定值的部分截掉,不足的在最前面用0填充
        x_test_padded_seqs=pad_sequences(x_test_word_ids, maxlen=50)
    

    三、基于keras的TextCNN模型的构建、训练与测试

    1、基础版CNN(模仿LeNet-5)

    LeNet-5是卷积神经网络的作者Yann LeCun用于MNIST识别任务提出的模型。模型很简单,就是卷积池化层的堆叠,最后加上几层全连接层。将其运用在文本分类任务中。

    #构建CNN分类模型(LeNet-5)
    #模型结构:嵌入-卷积池化*2-dropout-BN-全连接-dropout-全连接
    def CNN_model(x_train_padded_seqs, y_train, x_test_padded_seqs, y_test):
        model = Sequential()
        model.add(Embedding(len(vocab) + 1, 300, input_length=50)) #使用Embeeding层将每个词编码转换为词向量
        model.add(Conv1D(256, 5, padding='same'))
        model.add(MaxPooling1D(3, 3, padding='same'))
        model.add(Conv1D(128, 5, padding='same'))
        model.add(MaxPooling1D(3, 3, padding='same'))
        model.add(Conv1D(64, 3, padding='same'))
        model.add(Flatten())
        model.add(Dropout(0.1))
        model.add(BatchNormalization())  # (批)规范化层
        model.add(Dense(256, activation='relu'))
        model.add(Dropout(0.1))
        model.add(Dense(3, activation='softmax'))
        model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
        one_hot_labels = keras.utils.to_categorical(y_train, num_classes=3)  # 将标签转换为one-hot编码
        model.fit(x_train_padded_seqs, one_hot_labels,epochs=5, batch_size=800)
        y_predict = model.predict_classes(x_test_padded_seqs)  # 预测的是类别,结果就是类别号
        y_predict = list(map(str, y_predict))
        print('准确率', metrics.accuracy_score(y_test, y_predict))
        print('平均f1-score:', metrics.f1_score(y_test, y_predict, average='weighted'))

    2、简单版TextCNN

    #构建TextCNN模型
    #模型结构:词嵌入-卷积池化*3-拼接-全连接-dropout-全连接
    def TextCNN_model_1(x_train_padded_seqs,y_train,x_test_padded_seqs,y_test):
        main_input = Input(shape=(50,), dtype='float64')
        # 词嵌入(使用预训练的词向量)
        embedder = Embedding(len(vocab) + 1, 300, input_length=50, trainable=False)
        embed = embedder(main_input)
        # 词窗大小分别为3,4,5
        cnn1 = Conv1D(256, 3, padding='same', strides=1, activation='relu')(embed)
        cnn1 = MaxPooling1D(pool_size=48)(cnn1)
        cnn2 = Conv1D(256, 4, padding='same', strides=1, activation='relu')(embed)
        cnn2 = MaxPooling1D(pool_size=47)(cnn2)
        cnn3 = Conv1D(256, 5, padding='same', strides=1, activation='relu')(embed)
        cnn3 = MaxPooling1D(pool_size=46)(cnn3)
        # 合并三个模型的输出向量
        cnn = concatenate([cnn1, cnn2, cnn3], axis=-1)
        flat = Flatten()(cnn)
        drop = Dropout(0.2)(flat)
        main_output = Dense(3, activation='softmax')(drop)
        model = Model(inputs=main_input, outputs=main_output)
        model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    
        one_hot_labels = keras.utils.to_categorical(y_train, num_classes=3)  # 将标签转换为one-hot编码
        model.fit(x_train_padded_seqs, one_hot_labels, batch_size=800, epochs=10)
        #y_test_onehot = keras.utils.to_categorical(y_test, num_classes=3)  # 将标签转换为one-hot编码
        result = model.predict(x_test_padded_seqs)  # 预测样本属于每个类别的概率
        result_labels = np.argmax(result, axis=1)  # 获得最大概率对应的标签
        y_predict = list(map(str, result_labels))
        print('准确率', metrics.accuracy_score(y_test, y_predict))
        print('平均f1-score:', metrics.f1_score(y_test, y_predict, average='weighted'))

    3、使用Word2Vec词向量的TextCNN

    w2v_model=Word2Vec.load('sentiment_analysis/w2v_model.pkl')
    # 预训练的词向量中没有出现的词用0向量表示
    embedding_matrix = np.zeros((len(vocab) + 1, 300))
    for word, i in vocab.items():
        try:
            embedding_vector = w2v_model[str(word)]
            embedding_matrix[i] = embedding_vector
        except KeyError:
            continue
    
    #构建TextCNN模型
    def TextCNN_model_2(x_train_padded_seqs,y_train,x_test_padded_seqs,y_test,embedding_matrix):
        # 模型结构:词嵌入-卷积池化*3-拼接-全连接-dropout-全连接
        main_input = Input(shape=(50,), dtype='float64')
        # 词嵌入(使用预训练的词向量)
        embedder = Embedding(len(vocab) + 1, 300, input_length=50, weights=[embedding_matrix], trainable=False)
        #embedder = Embedding(len(vocab) + 1, 300, input_length=50, trainable=False)
        embed = embedder(main_input)
        # 词窗大小分别为3,4,5
        cnn1 = Conv1D(256, 3, padding='same', strides=1, activation='relu')(embed)
        cnn1 = MaxPooling1D(pool_size=38)(cnn1)
        cnn2 = Conv1D(256, 4, padding='same', strides=1, activation='relu')(embed)
        cnn2 = MaxPooling1D(pool_size=37)(cnn2)
        cnn3 = Conv1D(256, 5, padding='same', strides=1, activation='relu')(embed)
        cnn3 = MaxPooling1D(pool_size=36)(cnn3)
        # 合并三个模型的输出向量
        cnn = concatenate([cnn1, cnn2, cnn3], axis=-1)
        flat = Flatten()(cnn)
        drop = Dropout(0.2)(flat)
        main_output = Dense(3, activation='softmax')(drop)
        model = Model(inputs=main_input, outputs=main_output)
        model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    
        one_hot_labels = keras.utils.to_categorical(y_train, num_classes=3)  # 将标签转换为one-hot编码
        model.fit(x_train_padded_seqs, one_hot_labels, batch_size=800, epochs=20)
        #y_test_onehot = keras.utils.to_categorical(y_test, num_classes=3)  # 将标签转换为one-hot编码
        result = model.predict(x_test_padded_seqs)  # 预测样本属于每个类别的概率
        result_labels = np.argmax(result, axis=1)  # 获得最大概率对应的标签
        y_predict = list(map(str, result_labels))
        print('准确率', metrics.accuracy_score(y_test, y_predict))
        print('平均f1-score:', metrics.f1_score(y_test, y_predict, average='weighted'))

    四、绘制TextCNN模型结构图

    使用keras的plot_model()画出的TextCNN模型结构图

    1、环境配置

    (1)安装graphviz模块

    首先,命令行pip install graphviz;其次,安装graphviz软件,官网下载:graphviz-2.38.msi ;最后,将安装目录中的graphviz-2.38\release\bin添加进Path环境变量

    (2)安装pydot模块

    命令行pip install pydot

    (3)在运行程序中加入下面两行代码

    import os
    os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'

    2、绘制模型图

    使用plot_model()画出模型图

    from keras.utils import plot_model
        #生成一个模型图,第一个参数为模型,第二个参数为要生成图片的路径及文件名,还可以指定两个参数:
        #show_shapes:指定是否显示输出数据的形状,默认为False
        #show_layer_names:指定是否显示层名称,默认为True
        plot_model(model,to_file='sentiment_analysis/model.png',show_shapes=True,show_layer_names=False)

    模型图如下:

    五、keras模型的保存与加载

    from keras.models import load_model
    
    #模型的保存
    model.save('model.h5')
    
    #模型的加载
    model=load_model('model.h5')

     

    参考学习资料:

    (1)Keras之文本分类实现

    (2)使用Keras进行深度学习

    (3)NLP论文

    (4)卷积神经网络(CNN)在句子建模上的应用

    (5)用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践

    (6)深度学习在文本分类中的应用

    (7)深度学习与文本分类总结第一篇--常用模型总结

    (8)基于 word2vec 和 CNN 的文本分类 :综述 & 实践

     

    交流学习资料共享欢迎入QQ群:955817470

     

    展开全文
  • 卷积神经网络和TextCNN(原理+代码)

    千次阅读 2019-07-06 17:39:48
      卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。 ##概况   卷积神经网络(Convolutional Neural ...

      卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。
    ##概况
      卷积神经网络(Convolutional Neural Networks / CNNs / ConvNets)与普通神经网络非常相似,它们都由具有可学习的权重和偏置常量(biases)的神经元组成。每个神经元都接收一些输入,并做一些点积计算,输出是每个分类的分数(概率),普通神经网络里的一些计算技巧到这里依旧适用。

    1、卷积神经网络(CNN)

    所以哪里不同呢?

    神经网络到卷积神经网络

      神经网络广义上的一般形式如下图,有输入层,输出层以及中间层。并且层与层之间的连线叫做权重(W),作为传递信号。
    这里写图片描述
      我们大概已经了解神经网络对于很多分类问题有了很好的结果,但是这是需要一个前提的,这个前提就是分类的类别相对较少。如果当你面临比较多的分类问题的时候,你还想用神经网络,那么就会出现两个问题:
      (1)深的网络结构,更多的神经元,浪费资源
      (2)过拟合
      针对第一个问题,当你面临多分类的问题是,势必需要架起层次更深的神经网络,这就意味着需要更多的神经元。这里举一个例子,比如Alexnet神经网络,这是一个7层的神经网络,每一层的神经元个数达到4096,我们可以从上面的神经网络的一般形式看出,每两层之间(因为是全连接)的权重(W)就达到4096 X 4096,而这仅仅是两层之间,面对七层的神经网络,权重(W)的量级可想而知。所以如果支撑起这个Alexnet神经网络,就需要有足够的电脑资源,才能使得输入的数据做前项运算、后向传播、迭代、优化。
      针对第二个问题,当神经网络的层次多起来的时候,它的学习能力非常强,也就是有非常强的记忆能力,以至于当你的数据没有达到一定的量级,它可以轻而易举的把你的训练集数据全部记下来,这是做机器学习都不愿遇到的问题,就是过拟合现象。直观的表现就是它可以在你的训练集上表现的非常好,但是在同等条件下,你输入其他的问题,它的回答就不那么好,就是泛化能力很差。

    针对这两个问题,后来就发展了很多的神经网络,其中就包括比较常用的卷积神经网络。

    卷积神经网络之层级结构

    数据输入层 / input layer

    包括三种比较常用的数据处理方式
      1、去均值
      把输入数据各个维度都中心化0
      2、归一化
      幅度归一化到同样的范围
      3、PCA / 白化
      用PCA降维(保证独立性)
      白化是对数据每个特征轴上的幅度归一化

    卷及计算层 / CONV layer

    首先卷积层是卷积神经神经网络的灵魂,非常的重要。
      1、局部关联。每个神经元看做一个filter
      2、窗口滑动,filter对局部数据计算
      在对图像的认识,我们发现一个性质,叫局部关联性。比如一个图像的一个像素点,与之关系最大的是在其周围的像素点,也就是说把图像的主体截下来,它周边的东西也不会对主体造成很大的影响。
    这里写图片描述
      当我们对整个图像进行处理比较困难的时候,我们这时候采取一个办法,就是取一个数据窗口,它要做的事就是从图像的左上角依次滑到右下角,使得整个图像全部滑过一遍,这样就可以把整个图形的信息扫面下来。
      这里需要重点提及的是每层的神经元的功能都是不一样的,比如第一个神经元它在做窗口滑动的时候只提取其中一个特征,二下一个神经元只提取另一个特征,依次下去,最后把这些汇总起来(这和神经网络的区别是,神经网络的神经元是把图片的所有信息提取下来然后再汇总)。并且上面图形里面的神经元与窗口的连线表示权重(W)。
    窗口滑动就需要提出三个概念
      (1)深度(depth)
      (2)步长(stride)
      (3)填充值(zero-padding)
    这里写图片描述
    下面依次介绍这三个的意义:
      深度可以直观的理解为下一层神经元的个数。比如上面图中的卷积层有五个神经元,那么这里卷积层的深度就是5
      步长表示的是窗口每次滑动需要滑几步,人为设定的。步长的设定最好低于你的数据窗口的维数,这样可以更好地提取图形的信息
      填充值是当我们设定的数据窗口在一定的步长上滑动时,无法滑动到下去而补充的值,一般为0
    这里写图片描述
      这个动图形象的介绍了神经元在提取图像特征时所做的内积的过程。Filter W0表示第一个神经元,Filter W1表示第二个神经元。其中W0下有三个矩阵是因为我们的输入对象是一个RGB彩色图片,它有三个颜色通道,需要对它们同时提取信息。

    参数共享

      我们直观的从图片上看,因为数据窗口每次都在滑动,并且面对的信息也不一样,自然而然的认为权重(W)一直在变。但是呢,卷积神经网络在这里做了一个设定,就是使这些W固定不变,也就是参数共享,目的就是减少参数,事实证明,进过机器的学习,并不会影响我们对图像的识别。
    这里写图片描述

    卷积层总结

      1、固定每个神经元连接权重(参数共享),可以看做模板
      2、每个神经元只关注一个特性
      3、需要估算的权重个数减少:AlexNet 1亿 => 3.5万
      4、一组固定的权重和不同窗口内数据做内积:卷积
    这里写图片描述
      这个图片直观的告诉大家,第一个神经元(filter)只提取一个特征(图片的形状),第二个图片也只提取一个特征(图像的纹理)。

    激励层

      我们从卷积层通过运算得到的一些结果,但是要判断这些结果要不要往下继续往下传,或者要以什么样的幅度往下传,这就需要把从卷积层的输出结果做非线性变换
    这里写图片描述
      这个图片说明了从卷积层得到的结果并不是直接往下传的,需要加入激励函数,下面介绍比较常见的几种激励函数

    1、Sigmoid

    这里写图片描述
      图形为:
    这里写图片描述
      sigmod激励函数符合实际,当输入很小时,输出接近于0;当输入很大时,输出值接近1。但sigmod函数存在较大的缺点:

      1、当输入值很小时或很大时,输出曲线基本就是直线了,回想一下反向传播的过程,我们最后用于迭代的梯度,是由中间这些梯度值结果相乘得到的,因此如果中间的局部梯度值非常小,直接会把最终梯度结果拉近0,意味着存在梯度趋向为0

      2、非零中心化,也就是当输入为0时,输出不为0,,因为每一层的输出都要作为下一层的输入,而未0中心化会直接影响梯度下降,我们这么举个例子吧,如果输出的结果均值不为0,举个极端的例子,全部为正的话(例如f=wTx+b中所有x>0),那么反向传播回传到w上的梯度将要么全部为正要么全部为负(取决于f的梯度正负性),这带来的后果是,反向传播得到的梯度用于权重更新的时候,不是平缓地迭代变化,而是类似锯齿状的突变。影响梯度下降的动态性

    2、Tanh(双曲正切)

    这里写图片描述
      图像为:
    这里写图片描述
      与sigmoid相比,输出至的范围变成了0中心化[-1, 1]。但梯度消失现象依然存在。所以在实际应用中,tanh激励函数还是比sigmoid要用的多一些的
    #### ReLU(the Rectified Linear Unit / 修正线性单元)
      函数的基本形式为:f(x)=max(0,x)f\left ( x \right )=max\left ( 0,x \right )
      图像为:
    这里写图片描述
    优点:
      (1)不会出现梯度消失,收敛速度快;
      (2)前向计算量小,只需要计算max(0, x),不像sigmoid中有指数计算;
      (3)反向传播计算快,导数计算简单,无需指数、出发计算;
      (4)有些神经元的值为0,使网络具有saprse性质,可减小过拟合。
    缺点:
      比较脆弱,在训练时容易“die”,反向传播中如果一个参数为0,后面的参数就会不更新。使用合适的学习当然,这和参数设置有关系,所以我们要特别小心,举个实际的例子哈,如果学习速率被设的太高,结果你会发现,训练的过程中可能有高达40%的ReLU单元都挂掉了。所以我们要小心设定初始的学习率等参数,在一定程度上控制这个问题。率会减弱这种情况。

    3、Leaky ReLU

      函数为:f(x)={xx>00.01xothersf\left ( x \right )=\left\{\begin{matrix} x & x>0& \\ 0.01x& others& \end{matrix}\right.
      图像为:
    这里写图片描述
      优点:ReLU有的全都有,并且不会die,是ReLU的改进
      缺点:计算量略大,效果不会很稳定

    4、指数线性单元ELU

      函数为:f(x)={xx>0α(exp(x)1)others f\left ( x \right )=\left\{\begin{matrix} x & x>0& \\ \alpha \left ( exp\left ( x \right ) -1\right )& others& \end{matrix}\right.
      图像为:
    这里写图片描述
      优点:所有ReLU的优点都有,不会挂,输出均值趋于0
      缺点:因为指数存在,计算量略大

    5、Maxout

      函数为:f(x)=max(w1T+b1,w2T+b2)f\left ( x \right )=max\left ( w_{1}^{T}+b_{1}, w_{2}^{T}+b_{2}\right )
      优点:Maxout函数是对ReLU和Leaky ReLU的一般化归纳,这样就拥有了ReLU的所有优点(线性和不饱和),而没有它的缺点
      缺点:它每个神经元的参数数量增加一倍,这就导致了整体参数的数量激增

    6、激励层(实际经验)

      不要用sigmoid!不要用sigmoid!不要用sigmoid!
      首先试RELU,因为快,但要小心点
      如果2失效,请用Leaky ReLU或者Maxout
      某些情况下tanh倒是有不错的结果,但是很少

    池化层

      夹在连续的卷积层中间
      进行下采样,压缩数据和参数的量,减少过拟合
      不需要引入新权重
    这里写图片描述
      我们对图片有个直观的认识,就是将图片放小任然可以认出这是个什么图片内容,所以池化层就利用这一点进一步压缩数据,减少参数的数量,减少过拟合。
    这里介绍两个常用的方法Max pooling 和average pooling,以Max pooling为例
    这里写图片描述
      从图中很明显就可以看出来它是取每个区域的最大值,来得到新的结果,并且参数从25降到了9。所以即达到了图像识别的效果,又使得参数得到了减少,为什么不用呢???

    全连接层(Fully-connected layer)

    全连接层和卷积层可以相互转换:
      * 对于任意一个卷积层,要把它变成全连接层只需要把权重变成一个巨大的矩阵,其中大部分都是0 除了一些特定区块(因为局部感知),而且好多区块的权值还相同(由于权重共享)。
      * 相反地,对于任何一个全连接层也可以变为卷积层。比如,一个K=4096K=4096 的全连接层,输入层大小为 7∗7∗5127∗7∗512,它可以等效为一个 F=7, P=0, S=1, K=4096F=7, P=0, S=1, K=4096 的卷积层。换言之,我们把 filter size 正好设置为整个输入层大小。

    一般CNN结构依次为

      INPUT
      [[CONV -> RELU]*N -> POOL?]*M
      [FC -> RELU]*K
      FC
    问号表示pooling层可有可无,这取决于你的数据量有多大,取决你的当前问题的数据量级支持它不会那么快的过拟合。

    训练算法

      同一般机器学习算法,先定义Loss function,衡量与实际结果之间差距
      找到最小化损失函数的W和b,CNN中的算法是SGD
      SGD需要计算W和b的偏导
      BP算法就是计算偏导用的
      BP算法的核心是求导链式法则
    总结下来就是:
      BP算法利用链式求导法则,逐级相乘直到求解出dw和db
      利用SGD/随机梯度下降,迭代和更新W和b

    优缺点

    优点
      共享卷积核,对高维数据处理无压力
      无需手动选取特征,训练好权重,即得特征
      分类效果好
    缺点
      需要调参,需要大样本量,训练最好要GPU
      物理含义不明确

    CNN在图像处理层面受到了广泛的应用,也收到了很好的效果,日前CNN网络在图像层面发展迅速,基于更高的硬件需求,CNN表现出更好的效果,本问在上文原理的介绍下,对CNN在文本处理领域的运用做一些简单的介绍。

    2、TextCnn

    原文下载
    在这里插入图片描述
    可以发现textCNN的结构与CNN结构一直。

    2.1 词嵌入

    首先句子可以看作是词的序列,序列长度为n,每个词用向量xix_{i}表示,每个词嵌入的维度是k。所以句子表示为:xi:n=x1x2:::xnx_{i:n} = x_{1}\oplus x_{2}\oplus :::\oplus x_{n}xi:i+jx_{i:i+j}是个左闭右闭的区间。

    2.2 卷积

    由于不同的论文对卷积的表达是不同的,所以以上图为例。上图中宽代表词向量,高代表不同的词。

    由于TextCNN采用的卷积是一维卷积,所以卷积核的宽度和词嵌入的维度是一致的。而卷积核的高度h代表的是每次窗口取的词数。所以卷积核ωRhk\omega \in \mathbb{R}^{hk}

    对于每一次滑窗的结果cic_{i}(标量)而言,卷积运算的结果是
    ci=f(ωxi:i+h1)+bc_{i}=f\left ( \omega \cdot x_{i:i+h-1} \right )+b其中bRb\in \mathbb{R},而f是非线性函数,例如tanh或者relu。

    由于卷积运算是对应元素相乘然后相加,所以ω\omegaxi:i+h1x_{i:i+h-1}的维度是一致的。由于ω\omega的维度是hkh*kxi:i+h1x_{i:i+h-1}的维度也是hkh*k,则X的维度是(nh+1)hk\left ( n-h+1 \right )*h*k(和c的维度可以对照得到)。

    由于句子序列长度为n,而卷积核的高度为h,所以总共滑窗n−h+1次。所以卷积汇总结果为c=[c1,c2,...,cnh+1]c=\left [ c_{1},c_{2},...,c_{n-h+1} \right ]

    2.3 池化

    这里的池化采用的是全局最大池化,即c^=max{c}\hat{c}=max\left \{ c \right \}。由于filter一般有多个,假设卷积核个数是m,所以池化后的数据为z=[c1^,c2^,...,cm^]z=\left [ \hat{c_{1}},\hat{c_{2}},...,\hat{c_{m}} \right ]数据维度为1∗m (列向量)。

    2.4 DNN+softmax

    y=ωz+by=\omega * z + b

    展开全文
  • Text-CNN 文本分类

    万次阅读 多人点赞 2017-09-05 09:39:30
    TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 “Convolutional Neural Networks for Sentence Classification” 一文 (见参考[1]) 中提出. 是2014年的算法. 图1-1 参考[1] 中的论文配图 ...

    1.简介

    TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 “Convolutional Neural Networks for Sentence Classification” 一文 (见参考[1]) 中提出. 是2014年的算法.

    网络结构
    图1-1 参考[1] 中的论文配图


    图1-2 网络盗图

    合理性:
    深度学习模型在计算机视觉与语音识别方面取得了卓越的成就. 在 NLP 也是可以的.
    卷积具有局部特征提取的功能, 所以可用 CNN 来提取句子中类似 n-gram 的关键信息.

    2.参数与超参数

    • sequence_length
      Q: 对于CNN, 输入与输出都是固定的,可每个句子长短不一, 怎么处理?
      A: 需要做定长处理, 比如定为n, 超过的截断, 不足的补0. 注意补充的0对后面的结果没有影响,因为后面的max-pooling只会输出最大值,补零的项会被过滤掉.
    • num_classes
      多分类, 分为几类.
    • vocabulary_size
      语料库的词典大小, 记为|D|.
    • embedding_size
      将词向量的维度, 由原始的 |D| 降维到 embedding_size.
    • filter_size_arr
      多个不同size的filter.

    3.Embedding Layer

    通过一个隐藏层, 将 one-hot 编码的词 投影 到一个低维空间中.
    本质上是特征提取器,在指定维度中编码语义特征. 这样, 语义相近的词, 它们的欧氏距离或余弦距离也比较近.

    4.Convolution Layer

    为不同尺寸的 filter 都建立一个卷积层. 所以会有多个 feature map.
    图像是像素点组成的二维数据, 有时还会有RGB三个通道, 所以它们的卷积核至少是二维的.
    从某种程度上讲, word is to text as pixel is to image, 所以这个卷积核的 size 与 stride 会有些不一样.

    • xixi
      xiRkxi∈Rk, 一个长度为n的句子中, 第 i 个词语的词向量, 维度为k.
    • xi:jxi:j
      xi:j=xixi+1...xjxi:j=xi⊕xi+1⊕...⊕xj
      表示在长度为n的句子中, 第 [i,j] 个词语的词向量的拼接.
    • hh
      卷积核所围窗口中单词的个数, 卷积核的尺寸其实就是 hkhk.
    • ww
      wRhkw∈Rhk, 卷积核的权重矩阵.
    • cici
      ci=f(wxi:i+h1+b)ci=f(w⋅xi:i+h−1+b), 卷积核在单词i位置上的输出. bRKb∈RK, 是 bias. ff 是双曲正切之类的激活函数.
    • c=[c1,c2,...,cnh+1]c=[c1,c2,...,cn−h+1]
      filter在句中单词上进行所有可能的滑动, 得到的 feature mapfeature map.

    5.Max-Pooling Layer

    max-pooling只会输出最大值, 对输入中的补0 做过滤.

    6.SoftMax 分类 Layer

    最后接一层全连接的 softmax 层,输出每个类别的概率。

    7.小的变种

    在 word representation 处理上会有一些变种.

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

    一些结果表明,max-pooling 总是优于 average-pooling ,理想的 filter sizes 是重要的,但具体任务具体考量,而用不用正则化似乎在NLP任务中并没有很大的不同。

    8. Text CNN 的tf实现

    参见[4], [6]. 挺详细的。


    图 8-1 Text CNN 网络中的卷积与池化 结构

    需要注意的细节有。
    tf.nn.embedding_lookup() creates the actual embedding operation. The result of the embedding operation is a 3-dimensional tensor of shape [None, sequence_length, embedding_size].

    TensorFlow’s convolutional conv2d operation expects a 4-dimensional tensor with dimensions corresponding to batch, width, height and channel. The result of our embedding doesn’t contain the channel dimension, so we add it manually, leaving us with a layer of shape [None, sequence_length, embedding_size, 1].

    9. 与 LeNet 作比较


    figure LeNet-5 网络结构

    # LeNet5
    conv1_weights = tf.get_variable(
                        "weight", 
                        [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],
                        initializer=tf.truncated_normal_initializer(stddev=0.1))
    tf.nn.conv2d(
                input_tensor, 
                conv1_weights, 
                strides=[1, 1, 1, 1],
                padding='SAME')
    
    tf.nn.max_pool(
                    relu1, 
                    ksize = [1,POOL1_SIZE,POOL1_SIZE,1],
                    strides=[1,POOL1_SIZE,POOL1_SIZE,1],
                    padding="SAME")
    #TextCNN
    conv1_weights = tf.get_variable(
                        "weight", 
                        [FILTER_SIZE, EMBEDDING_SIZE, 1, NUM_FILTERS],
                        initializer=tf.truncated_normal_initializer(stddev=0.1))
    tf.nn.conv2d(
                self.embedded_chars_expanded,
                conv1_weights,
                strides=[1, 1, 1, 1],
                padding="VALID")
    
    tf.nn.max_pool(
                    h,
                    ksize=[1, SEQUENCE_LENGTH - FILTER_SIZE + 1, 1, 1],
                    strides=[1, 1, 1, 1],
                    padding='VALID')

    先来比较卷积
    LeNet 的 filter 是正方形的, 且每一层都只用了同一种尺寸的卷积核. Text-CNN中, filter 是矩形, 矩形的长度有好几种, 一般取 (2,3,4), 而矩形的宽度是定长的, 同 word 的 embedding_size 相同. 每种尺寸都配有 NUM_FILTERS 个数目, 类比于LeNet中的output_depth,所以得到的feature_map是长条状, 宽度为1.
    因为是卷积, 所以stride每个维度都是1.

    再说池化层.
    池化处理, 也叫下采样. 这里依旧可以对比 LeNet 网络.
    LeNet 的 kernel 是正方形, 一般也是2*2等, 所以会把卷积后的feature_map尺寸缩小一半.
    Text-CNN 的 kernel 依旧是长方形, 将整个feature_map 映射到一个点上. 一步到位, 只有一个池化层.

    全连接层
    都是多分类, 这一步的处理比较类似. 将池化后的矩阵 reshape为二维, 用 tf.nn.sparse_softmax_cross_entropy_with_logits() 计算损失.

    10. TextCNN 论文中的网络结构

    windows size 分别取 (3,4,5), 每个尺寸都会有100个filter.

    3.1 Hyperparameters and Training
    For all datasets we use: rectified linear units, filter
    windows (h) of 3, 4, 5 with 100 feature maps each,
    dropout rate (p) of 0.5, l2 constraint (s) of 3, and
    mini-batch size of 50. These values were chosen
    via a grid search on the SST-2 dev set.

    参考

    1. Convolutional Neural Networks for Sentence Classification
    2. Tensorflow版TextCNN主要代码解析
    3. Recurrent Neural Network for Text Classification with Multi-Task Learning
    4. implementing-a-cnn-for-text-classification-in-tensorflow
    5. understanding-convolutional-neural-networks-for-nlp
    6. textcnn实现-github
    展开全文
  • 深度学习:TextCNN

    万次阅读 多人点赞 2018-12-18 20:30:48
    然而研究证明,TextCnn在文本分类问题上有着更加卓越的表现。从直观上理解,TextCNN通过一维卷积来获取句子中n-gram的特征表示。TextCNN对文本浅层特征的抽取能力很强,在短文本领域如搜索、对话领域专注...
  • TextCNN简介与应用

    2020-02-03 20:09:02
    TextCNN常用来做短文本的分类问题,其基本网络结构如下图所示: 从上图不难看出,TextCNN主要包括嵌入层、卷积层、池化层和全联接softmax层: Embedding:这一层是图中最左边的7乘5的句子矩阵,高为句子中单词...
  • TextCNN的TensorFlow实现

    2019-01-24 10:29:49
    TextCNN的核心点在于可以捕获信息的局部相关性,具体到文本分类任务中可以利用CNN来提取句子中类似N-Gram的关键信息。
  • textcnn详解

    2020-09-23 00:06:02
    一. TextCNN是什么 ...与传统图像的CNN网络相比, textCNN 在网络结构上没有任何变化(甚至更加简单了), 从图一可以看出textCNN 其实只有一层卷积,一层max-pooling, 最后将输出外接softmax 来n分类。 ...
  • 大规模文本分类网络TextCNN介绍

    万次阅读 2018-03-15 23:01:25
    TextCNN网络是2014年提出的用来做文本分类的卷积神经网络,由于其结构简单、效果好,在文本分类、推荐等NLP领域应用广泛,我自己在工作中也有探索其在实际当中的应用,今天总结一下。 TextCNN的网络结构 数据...
  • 最近花周末两天时间利用pytorch实现了TextCNN进行了中文文本分类,在此进行记录。 数据获取 中文数据是从https://github.com/brightmart/nlp_chinese_corpus下载的。具体是第3个,百科问答Json版,因为感觉大小适中...
  • Keras实现textCNN文本分类

    万次阅读 热门讨论 2018-07-24 19:22:52
    CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算...
  • TextCNN进行文本分类多标签分类

    千次阅读 2020-03-20 17:32:59
    TextCNN 数据集下载:链接:https://pan.baidu.com/s/14qRe9cxtSS51anKOcpy6dA 提取码:zygc TextCNN是卷积神经网络的一种(其实就是一个简单的神经网络)。 卷积神经网络是指-至少在网络的一层中使用了卷积运算代替...
  • TextCNN文本分类与tensorflow实现

    千次阅读 2019-02-01 09:47:38
    本文将介绍一个有关CNN的模型,用来对文本进行分类,并将它应用在文本分类的热门任务——情感分析上,模型的名称叫TextCNN,模型的论文地址如下: 论文地址:《Convolutional Neural Networks for Sentenc...
  • 我后面写的 textcnn 没有简化,是为了方便理解,而简化版的用了 nn.ModuleList 和 nn.Sequential,代码参考博文TextCNN class TextCNN(nn.Module): def __init__(self, config): super(TextCNN, self).__init__() ...
  • 一、TextCNN 下图是14年这篇文章提出的...卷积神经网络(CNN Convolutional Neural Network)最初在图像领域取得了巨大成功,CNN原理就不讲了,核心点在于可以捕捉局部相关性,具体到文本分类任务中可以利用CNN来提...
  • TextCNN(文本分类)

    2020-01-10 13:44:18
    利用TextCNN文本分类基本流程(以句子分类为例): (1)将句子转成词,利用词建立字典 (2)词转成向量(word2vec,Glove,bert,nn.embedding) (3)句子补0操作变成等长 (4)建TextCNN模型,训练,测试 ...
  • Eclipse Deeplearning4j GitChat课程:https://gitbook.cn/gitchat/column/5bfb6741ae0e5f436e35cd9fEclipse Deeplearning4j 系列博客:...
  • 使用keras_bert来加载构建bert模型
  • NLP领域短文本分类非常的常见,那么我们今天分享一下NLP领域文本主要的应用场景
  • 这次刚好工作中有应用需求,就以NLP的文本分类为切入点,进行相关知识的学习和模型实践。 当前进展: 研究了两周,完成文本预处理、word embedding、TextCnn模型训练、API封装等代码工作,模型效果调优、验证中。...
  • 使用Pytorch进行文本分类——TextCNN

    千次阅读 2019-08-02 16:42:21
    目录网络结构代码实现 网络结构 代码实现 class TextCNN(nn.Module): def __init__(self, config:TCNNConfig, char_size = 5000, pinyin_size=5000): super(TextCNN, self).__init__(...
  •  最近一直在研究textCNN算法,准备写一个系列,每周更新一篇,大致包括以下内容: TextCNN基本原理和优劣势 TextCNN代码详解(附Github链接) TextCNN模型实践迭代经验总结 TextCNN模型部署Tf-Serving实践总结  ...
  • 卷积神经网络+TextCNN文本分类

    千次阅读 2019-03-15 17:40:02
    卷积知识5.6 textCNN: 5.6 textCNNTextCNN的详细过程原理图见下: TextCNN详细过程:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点了。然后经过有 filter_...
  • 史上最小白之TextCNN 中文文本分类实战

    千次阅读 热门讨论 2020-03-07 05:07:45
    本穷小子又买不起GPU服务器,只能使用colab进行学习,经常出现内存不够地情况,所以如果你也跟我一样没有比较好的GPU服务器,那么在做分类任务时,可以尝试选择TextCNN,而且目前在文本分类任务上TextCNN也取得了...
  • 1.导入库 import pandas as pd import numpy as np import tensorflow as tf import jieba import os from tensorflow.contrib import slim 2.读取数据 train_data = pd.read_csv("train.txt", sep='\t', names=['...
  • 原理:核心点在于使用卷积来捕捉局部相关性,具体到文本分类任务中可以利用CNN来提取句子中类似 n-gram 的关键信息。 textcnn详细过程:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比...
  • TextCNN模型 1.下载kaggle数据集,并进行文本预处理: # 导入相应的包 import pandas as pd import warnings import re import matplotlib.pyplot as plt from nltk.stem import WordNetLemmatizer from nltk.corpus ...
  • Keras的另一个实现可以参考:Keras实现textCNN文本分类 模型构建与训练 定义网络结构 定义一个textCNN类, 代码为tensorflow2.x版本。 from tensorflow.keras import Input, Model from tensorflow.keras.layers ...
  • TextCNN-基于卷积神经网络的文本分类

    千次阅读 2019-04-02 17:38:00
    1 简述     在没有监督数据的时候,采用无监督算法的方式可以计算两句话的相似度,即通过一些因子,比如语序、词性、共现词比例等等进行打分,最后通过加权计算的方式得到最终的相似分值,最终结果主要依赖因子...
  • bert获取词向量做textcnn文本分类

    千次阅读 2019-08-13 15:06:59
    BERT其中的一个重要作用是可以生成词向量 下面介绍获取词向量的方法 获取BERT词向量的时候用到了肖涵博士的bert-as-service,具体使用方式如下。 环境要求:python版本>=3.5,tensorflow版本>...

空空如也

1 2 3 4 5 ... 20
收藏数 275,487
精华内容 110,194
关键字:

textcnn