5-12《Convolutional Neural Networks for Sentence Classification》论文阅读
1.模型
上图中输入部分,两层分别表示两个通道,一层是固定的词向量表示,一层是可以微调的词向量;
输入被表示为,➕表示连接操作:
对每个h词块都有如下卷积操作,h应该是卷积步长大小,W表示一个卷积核,针对每个卷积核都会进行以下操作,来产生卷积结果(一系列ci组成c)
经过一个卷积核的卷积操作之后,可以得到:
对上面的c做最大池化,选出最大的c,最大的c就对应最重要的特征。
原文中提到:“We have described the process by which one feature is extracted from one filter”。这个one feature是针对倒数第二层来说的,有多少个卷积核这层就有多少个特征,那么最后再经过一层全连接层。当然,使用的卷积核可以有不同的窗口大小。
2.正则化
使用了dropout,它可以防止神经元之间互相产生依赖关系,这个dropout是放在了倒数第二层进行的。对于倒数第二层:
其中,r就是概率为p的0/1向量:
参数还设置了L2正则化。l2-norms of the weight vectors。
3.实验
3.1超参数
filter windows (h) of 3, 4, 5 with 100 feature maps each,也就是说卷积核一共有300个?每100个的核大小分别为3、4、5?
dropout=0.5. L2正则化参数为3. bsz=50.
预训练的word2vec使用的是300维的。
3.2模型变化
CNN-rand: 所有的词向量都是随机初始化的,在训练过程中训练
CNN-static:词向量由word2vec初始化,并且不可改变
CNN-non-static:词向量由word2vec初始化,并且微调
CNN-multichannel:有两套词向量,应该都是由word2vec初始化,并且一个可以微调,另一个不可改变。
在这里微调:“gradients are back-propagated only through one of the channels.”。微调的意思也就是把其中一个词向量当作可以训练的参数,每次都会计算梯度,然后更新。
4.结论
实验结果我就不截图了。
我认为有意思的:
1.微调之后词向量更有效:
2.dropout能够提高2%-4%。
2020-5-25更新————————————
1.torch版的实现
从这个实现中我们可以学习,其中kernel_sizes为[1,2,3],kernel_num为100. 假设如下:
import torch import torch.nn as nn import torch.nn.functional as F m = nn.Conv2d(1, 100, (3,100))#(输入通道、输出通道,kernel_size) m4=nn.Conv2d(1, 100, (4,100)) m5=nn.Conv2d(1, 100, (5,100)) input = torch.randn(32,1, 50, 100)#(bsz,通道数,seqlen,emb_dim) output = m(input) o4=m4(input) o5=m5(input) print(output.size()) print(o4.size()) print(o5.size()) ##mp=nn.MaxPool1d(48) ##print(mp(output).size()) print(F.max_pool1d(output.squeeze(3),48).size())#这里squeeze掉最后一个维度 #输出: torch.Size([32, 100, 48, 1])#输出通道变为了100. torch.Size([32, 100, 47, 1]) torch.Size([32, 100, 46, 1]) torch.Size([32, 100, 1])#最大池化的输出就相当于每个句子都变为了一个100维的向量, #其中每一个元素都来自一个卷积核。
这样的话我就明白了这个过程了!基本没有问题了。