赞
踩
本文展示的是使用 Pytorch 构建一个 TextCNN 来实现情感分析。本文的架构是第一章详细介绍 TextCNN(不带公式版),第二章是核心代码部分。
相较于 LSTM 而言,我个人其实是没看过 CNN 的任何公式的,主要是我觉得也没必要,因为从使用的角度上讲,会用就行;从 CNN 的角度上讲,你只需要知道 CNN 提取的是一种聚合关系就行(与 GNN 不同的是,CNN 提取的是欧式数据的聚合关系,GNN 提取的是非欧数据的聚合关系)。
TextCNN [1] 的模型图如下图所示。其中一共包含了有 3 个模块:卷积层,最大池化层,和输出层。
在原论文中,作者采用了多个通道来提取不同词嵌入的特征,然而如果只有一种词嵌入输入的话,可以参考下面这篇论文[2]中的模型图:
我们现在就以上图作为例子,详细介绍下 TextCNN(仅有一种词嵌入输入时)的具体流程(放心,没有任何公式):
5
,这个尺寸大小与嵌入维度
d
d
d 相同,就是说对于 TextCNN 而言,一次卷积要囊括所有词嵌入,这个也很好理解,因为只有
d
d
d 才能够代表整个词语。而对于第一维,分别为 4
、3
、2
,这个就指的是,一次卷积考虑几个词语的依赖关系。假设卷积核大小为
(
4
×
5
)
(4\times5)
(4×5),那么就说明该卷积核一次聚合 4
个词语的依赖关系。(注
:图中从左到右第二个区域是卷积核,第三个区域才是卷积后的输出)filter
),所以一共有 2
个
(
4
×
5
)
(4\times5)
(4×5) 的卷积核、2
个
(
3
×
5
)
(3\times5)
(3×5) 的卷积核、2
个
(
2
×
5
)
(2\times5)
(2×5) 的卷积核。这里就是说,我们用不同数量的滤波器来捕获这个区间内不同的特征,以
(
4
×
5
)
(4\times5)
(4×5) 的卷积核举例,我们用滤波器 A 来捕获这4个词语之间的 A 特征,用滤波器 B 来捕获这4个词语之间的 B 特征。通过上述的解释,我们可以发现,TextCNN 是通过卷积核的尺寸,来控制模型捕获多少个词语之间的上下文关系。
具体的模型代码如下:
import torch import torch.nn as nn import torch.nn.functional as F class Config: def __init__(self): # 训练配置 self.seed = 22 self.batch_size = 64 self.lr = 1e-3 self.weight_decay = 1e-4 self.num_epochs = 100 self.early_stop = 512 self.max_seq_length = 128 self.save_path = '../model_parameters/CNN_SA.bin' # 模型配置 self.filter_sizes = (3, 4, 5) self.num_filters = 100 self.dense_hidden_size = 128 self.dropout = 0.5 self.embed_size = 300 self.num_outputs = 2 class Model(nn.Module): def __init__(self, embed, config): super().__init__() self.embedding = nn.Embedding.from_pretrained(embed, freeze=False) self.convs = nn.ModuleList( [nn.Conv2d(1, config.num_filters, (k, config.embed_size)) for k in config.filter_sizes]) self.dropout = nn.Dropout(config.dropout) self.relu = nn.ReLU() self.ffn = nn.Linear(config.num_filters * len(config.filter_sizes), config.dense_hidden_size) self.classifier = nn.Linear(config.dense_hidden_size, config.num_outputs) def max_pooling(self, x): x = F.max_pool1d(x, x.size(2)).squeeze(2) return x def forward(self, inputs): # shape: (batch_size, max_seq_length, embed_size) embed = self.embedding(inputs) # CNN 接受四维数据输入, # 第一维: batch, # 第二维: 通道数 (Channel), 在图像中指的是 RGB 这样的通道, 在自然语言里面指的是多少种词嵌入, 本项目中仅采用一种词嵌入, 所以就是 1 通道 # 第三维: 高度 (Height), 在图像中指的是图片的高, 在自然语言里面就是序列长度 # 第四维: 宽度 (Weight), 在图像中指的是图片的宽, 在自然语言里面就是嵌入维度 # shape: (batch_size, 1, max_seq_length, embed_size) embed = embed.unsqueeze(1) cnn_outputs = [] for conv in self.convs: # shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1) conv_output = conv(embed) # shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1) relu_output = self.relu(conv_output) # shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1) relu_output = relu_output.squeeze(3) # shape: (batch_size, filter_size) pooling_output = self.max_pooling(relu_output) cnn_outputs.append(pooling_output) # shape: (batch, num_filters * len(num_filters)) cnn_outputs = torch.cat(cnn_outputs, 1) cnn_outputs = self.dropout(cnn_outputs) # shape: (batch, dense_hidden_size) ffn_output = self.relu(self.ffn(cnn_outputs)) # shape: (batch, num_outputs) logits = self.classifier(ffn_output) return logits
在该代码中,我才用的卷积核尺寸是 ( 3 × e m b e d _ s i z e ) (3\times {\rm embed\_size}) (3×embed_size)、 ( 4 × e m b e d _ s i z e ) (4\times {\rm embed\_size}) (4×embed_size)、 ( 5 × e m b e d _ s i z e ) (5\times {\rm embed\_size}) (5×embed_size),每个卷积核共有100个滤波器。同时,分类器一共有两层,一层的尺寸大小为 ( n u m _ f i l t e r s × l e n ( n u m _ f i l t e r s ) , d e n s e _ h i d d e n _ s i z e ) ({\rm num\_filters \times len(num\_filters)}, {\rm dense\_hidden\_size}) (num_filters×len(num_filters),dense_hidden_size),一层的尺寸大小为 ( d e n s e _ h i d d e n _ s i z e , n u m _ o u t p u t s ) ({\rm dense\_hidden\_size}, {\rm num\_outputs}) (dense_hidden_size,num_outputs)。
实验结果如下:
test loss 0.367522 | test accuracy 0.833840 | test precision 0.822838 | test recall 0.850880 | test F1 0.836624
[1] Yoon Kim. Convolutional Neural Networks for Sentence Classification [EB/OL]. https://arxiv.org/pdf/1408.5882.pdf, 2014.
[2] Ye Zhang, Byron C. Wallace. A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification [EB/OL]. https://arxiv.org/pdf/1510.03820.pdf, 2015.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。