2020-12-24

零基础入门NLP——新闻分类

基于TextCNN的文本表示

一、TextCNN介绍
TextCNN利用CNN进行文本特征抽取,不同大小的卷积核分别抽取n-gram特征,卷积计算出的特征图经过MaxPooling保留最大的特征值,然后拼接成一个向量作为文本表示。
这里基于TextCNN原始论文的设定,分别采用100个大小为2,3,4的卷积核,最后得到的文本向量大小为100*3=300维。
TextCNN的结构如图所示
在这里插入图片描述
二、向量大小变换
(1)首先我们的单词经过Embedding后的维度是(batch_size,sen_len,embed_size),在图中是最左侧的矩阵,其中:

  • batch_size是批次大小,通常为了提高计算效率,将数据分成num_batch个批次,每个批次的大小是batch_size,也就是每次输入batch_size个数据

  • sen_len是句子长度(单词数量)

  • embed_size是词向量维度
    (2)然后,使用不同大小的卷积核提取n-gram特征。

  • 卷积操作nn.Conv2d要求输入必须对应(B,H,C,W),因此我们认为输入是(batch_size, 1, sen_len, embed_size),增加的1是输入通道数input_channel;

  • 这里卷积核大小filter_sizes是[2, 3, 4],在写代码时,nn.Conv2d()的参数kernel_size指的就是卷积核大小,但是要写成(filter_size, input_size),因为我们使用的卷积核分别是[2, input_size], [3, input_size], [4, input_size],input_size与embed_size都是输入向量的维度

  • 得到的特征图大小(nn.Conv2d计算后)是(batch_size, out_channel, filter_height, 1),filter_height的计算公式是sen_len - filter_size + 1,步长为1,因为卷积核和向量矩阵的宽度相等,所以卷积核是向下滑动的,得到的特征图就是一个个列向量(看图)
    (3)之后,经过MaxPooling保留最大特征值。

  • 池化的大小为(filter_height, 1),filter_height是我们计算出的特征图的高度,1是因为特征图的宽度是1,也就是经过池化后,每个列向量都变成一个值(看图),所以池化后的特征图大小为(batch_size,out_channel,1,1)

  • 一般我们删除无用的维度,即变成(batch_size,out_channel)
    (4)再拼接成一个向量作为文本的表示,也可以输入至输出层,进行分类。

向量的维度变换如图所示:
在这里插入图片描述
TextCNN模型的代码如下:

# TextCNN
import torch
import torch.nn as nn
import torch.nn.functional as F

class TextCNN(nn.Module):
    def __init__(self, sen_len, input_size, batch_embed):
        super(TextCNN, self).__init__()
        # 模型搭建
        self.filter_sizes = [2,3,4]
        self.out_channel = 100
        self.convs = nn.ModuleList([nn.Conv2d(1, self.out_channel, (filter_size, input_size), bias = True)
                                   for filter_size in self.filter_sizes])
        
        #前向传播
        pooled_outputs = []
        for i in range(len(self.filter_sizes)):
            filter_height = sen_len - self.filter_sizes[i]+1
            conv = self.convs[i](batch_embed)
            hidden = F.relu(conv)
            #batch_size * out_channel * filter_height * 1
            
            mp = nn.MaxPool2d((filter_height, 1)) # (filter_height, filter_width)
            # batch_size * out_channel * 1 * 1
            pooled = mp(hidden).reshape(sen_sum, slef.out_channel)
            
            pooled_outputs.append(pooled)

以上就是我个人对TextCNN的认识,欢迎大家交流指正。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值