赞
踩
对于文本分类问题,常见的方法无非就是抽取文本的特征,比如使用doc2evc或者LDA模型将文本转换成一个固定维度的特征向量,然后在基于抽取的特征训练一个分类器。
从直观上理解,TextCNN通过一维卷积来获取句子中n-gram的特征表示。
TextCNN对文本浅层特征的抽取能力很强,在短文本领域如搜索、对话领域专注于意图分类时效果很好,应用广泛,且速度快,一般是首选;对长文本领域,TextCNN主要靠filter窗口抽取特征,在长距离建模方面能力受限,且对语序不敏感。
TextCNN特征:这里的特征就是词向量,有静态(static)和非静态(non-static)方式。static方式采用比如word2vec预训练的词向量,训练过程不更新词向量,实质上属于迁移学习了,特别是数据量比较小的情况下,采用静态的词向量往往效果不错。non-static则是在训练过程中更新词向量。推荐的方式是 non-static 中的 fine-tunning方式,它是以预训练(pre-train)的word2vec向量初始化词向量,训练过程中调整词向量,能加速收敛,当然如果有充足的训练数据和资源,直接随机初始化词向量效果也是可以的。
对数据做一些处理:
模型输入是一个用预训练好的词向量(Word2Vector或者glove)方法得到的一个Embedding layer。
对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器 filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。
卷积过程中的参数:
卷积的两种机制:
注意:
图像是二维数据;
文本是一维数据,因此在TextCNN卷积用的是一维卷积(在word-level上是一维卷积;虽然文本经过词向量表达后是二维数据,但是在embedding-level上的二维卷积没有意义)。一维卷积带来的问题是需要通过设计不同 kernel_size 的 filter 获取不同宽度的视野。(为什么没意义?)比如 “今天” 对应的向量[0, 0, 0, 0, 1], 按窗口大小为 1* 2 从左到右滑动得到[0,0], [0,0], [0,0], [0, 1]这四个向量, 对应的都是"今天"这个词汇, 这种滑动没有帮助。
plot_model可以画出模型结构图?
在论文中,多channels相比于单channels并没有提升模型的分类能力。
池化操作的本质是降采样。
添加池化层的作用:
(1)第一层为输入层。输入层是一个
n
∗
k
n*k
n∗k 的矩阵,其中
n
n
n 为一个句子中的单词数,
k
k
k 是每个词对应的词向量的维度。也就是说,输入层的每一行就是一个单词所对应的
k
k
k 维的词向量。另外,这里为了使向量长度一致对原句子进行了padding操作。我们这里使用
x
i
∈
R
k
x_i\isin{\R^k}
xi∈Rk 表示句子中第
i
i
i 个单词的
k
k
k 维词嵌入。
每个词向量可以是预先在其他语料库中训练好的,也可以作为未知的参数由网络训练得到。这两种方法各有优势,预先训练的词嵌入可以利用其他语料库得到更多的先验知识,而由当前网络训练的词向量能够更好地抓住与当前任务相关联的特征。因此,图中的输入层实际采用了双通道的形式,即有两个 的输入矩阵,其中一个用预训练好的词嵌入表达,并且在训练过程中不再发生变化;另外一个也由同样的方式初始化,但是会作为参数,随着网络的训练过程发生改变。
(2)第二层为卷积层,第三层为池化层。首先,我们要注意到卷积操作在计算机视觉(CV)和NLP中的不同之处。在CV中,卷积核往往都是正方形的,比如3*3的卷积核,然后卷积核在整张image上沿高和宽按步长移动进行卷积操作。与CV中不同的是,在NLP中输入层的"image"是一个由词向量拼成的词矩阵,且卷积核的宽和该词矩阵的宽相同,该宽度即为词向量大小,且卷积核只会在高度方向移动。因此,每次卷积核滑动过的位置都是完整的单词,不会将几个单词的一部分"vector"进行卷积,词矩阵的行表示离散的符号(也就是单词),这就保证了word作为语言中最小粒度的合理性(当然,如果研究的粒度是character-level而不是word-level,需要另外的方式处理)。
然后,我们详述这个卷积、池化过程。由于卷积核和word embedding的宽度一致,一个卷积核对于一个sentence,卷积后得到的结果是一个vector,其shape=(sentence_len - filter_window_size + 1, 1),那么,在经过max-pooling操作后得到的就是一个Scalar。我们会使用多个filter_window_size(原因是,这样不同的kernel可以获取不同范围内词的关系,获得的是纵向的差异信息,即类似于n-gram,也就是在一个句子中不同范围的词出现会带来什么信息。比如可以使用3,4,5个词数分别作为卷积核的大小),每个filter_window_size又有num_filters个卷积核(原因是卷积神经网络学习的是卷积核中的参数,每个filter都有自己的关注点,这样多个卷积核就能学习到多个不同的信息。使用多个相同size的filter是为了从同一个窗口学习相互之间互补的特征。比如可以设置size为3的filter有64个卷积核)。一个卷积核经过卷积操作只能得到一个scalar,将相同filter_window_size卷积出来的num_filter个scalar组合在一起,组成这个filter_window_size下的feature_vector。最后再将所有filter_window_size下的feature_vector也组合成一个single vector,作为最后一层softmax的输入。
形式化的说明如下:在输入为 n ∗ k n*k n∗k 的矩阵上,使用一个kernel w ∈ R h k w\isin{\R^hk} w∈Rhk 与一个窗口****(window) x i : i + h − 1 x_{i:i+h-1} xi:i+h−1 进行卷积操作,产生一个特征 c i c_i ci ,即: c i = f ( w ∗ x i : i + h − 1 + b ) c_i=f(w*x_{i:i+h-1}+b) ci=f(w∗xi:i+h−1+b) 其中 w ∈ R h k w\isin{\R^hk} w∈Rhk 代表由输入矩阵的第 i i i 行到第 i + h − 1 i+h-1 i+h−1 行所组成的一个大小为 h ∗ k h*k h∗k 的窗口,由 x i , x i + 1 , . . . , x i + h − 1 x_i,x_{i+1},...,x_{i+h-1} xi,xi+1,...,xi+h−1 拼接而成。 h h h 表示窗口中的单词数, w w w 为 h ∗ k h*k h∗k 维的权重矩阵(因此一个filter需要学习的参数个数是 h k hk hk 个), b b b 为偏置参数, f f f 为非线性函数。 w w w 和 x i : i + h − 1 x_{i:i+h-1} xi:i+h−1 进行点积运算(dot product,逐元素相乘得到的结果再求和)。过滤器应用到一个句子上,从上往下一次移动一步( i = 1... n − h + 1 i=1...n-h+1 i=1...n−h+1 ),如在 x 1 : h x_{1:h} x1:h 上经卷积操作得到 c 1 c_1 c1 ,在 x 2 : h x_{2:h} x2:h 上经卷积操作得到 c 2 c_2 c2 …,然后将它们拼接起来得到的 c = c i , c 2 , . . . , c n − h + 1 c=c_i,c_2,...,c_{n-h+1} c=ci,c2,...,cn−h+1 就是我们的feature map。每一次卷积操作相当于一次特征向量的提取,通过定义不同的窗口,就可以提取出不同的特征向量,构成卷积层的输出。
最后是池化层。也可以选用K-Max池化(选出每个特征向量中最大的K个特征),或者平均池化(将特征向量中的每一维取平均)等,达到的效果都是将不同长度的句子通过池化得到一个定长的向量表示。加粗样式
在整个过程中,通过训练得到的参数包括:filter们的权值矩阵 w w w 们,激活函数中的偏置项 b b b ,softmax函数中的权重矩阵,若词向量也加入训练进来的话,则包括该word embeddings。
(3)得到文本句子的向量表示之后,后面的网络结构就和具体的任务相关了。本例中展示的是一个文本分类的场景,因此最后接入了一个全连接层,并使用Softmax激活函数输出每个类别的概率。
默认的TextCNN模型超参数一般都是这种配置。
下面的超参数都对模型表现有影响:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。