详解文本分类之多通道CNN的理论与实践

阅读大概需要4分钟

导读

最近在梳理文本分类的各个神经网络算法,特地一个来总结下。接下来将要一个文章一个文章的讲解各个算法的理论与实践。目录暂定为:

  1. 多通道卷积神经网络(multi_channel_CNN)
  2. 深度卷积神经网络(deep_CNN)
  3. 基于字符的卷积神经网络(Char_CNN)
  4. 循环与卷积神经网络并用网络(LSTM_CNN)
  5. 树状循环神经网络(Tree-LSTM)
  6. Transformer(目前常用于NMT)
  7. etc..

之后的以后再补充。今天我们先讲第一个,多通道卷积神经网络。

先前知识补充

先说点基础的,我们最刚开始的分类其实就是embedding层之后直接经过线性层进行降维,将其映射到分类上,图为:

然后因为参数太多,计算太慢,所以产生了pooling池化层,取指定维度的一个参数代表整个维度,从而大大降低了计算量,而且效果还不错。图为:

之后又有人想到没有充分的利用到句子的上下词语的关系,所以就讲图像算法的CNN运用到了NLP上,这个就相当于NLP里的n-gram(unigram,bigram,trigram...)一样,寻找相邻词语组合形成的特征。图为:

有了上面的基础,我们引出multi_channel_CNN就容易多了。

multi_channel_CNN

多通道,就是CNN中的一次性卷积要处理的多少组数据。比如图像中,如果是只有灰度值的图像就只有一个通道,如果是彩色图片的话,就会RGB三个图像(也就是三个通道)。那么NLP中怎么利用这个多通道特征呢?有人就想了NLP中不就一个句子长度 * embed维度组成的一个二维输入吗?是这样的,刚开始我们用的都是单通道的。

但是有人就提出了这样的想法:

初始化两个不同的embedding,将句子用两个embedding表示出来,这样就可以有两个通道了。

时间确实是这样的,但是我们常用的是一个是随机初始化的embedding,另一个是使用预训练embedding(w2v or GloVe ...)。图为:

实践

这个其实和图像是想的差不多了。(pytorch)

class Multi_Channel_CNN 初始化:

def __init__(self, opts, vocab, label_vocab):
        super(Multi_Channel_CNN, self).__init__()

        random.seed(opts.seed)
        torch.manual_seed(opts.seed)
        torch.cuda.manual_seed(opts.seed)

        self.embed_dim = opts.embed_size
        self.word_num = vocab.m_size
        self.pre_embed_path = opts.pre_embed_path
        self.string2id = vocab.string2id
        self.embed_uniform_init = opts.embed_uniform_init
        self.stride = opts.stride
        self.kernel_size = opts.kernel_size
        self.kernel_num = opts.kernel_num
        self.label_num = label_vocab.m_size
        self.embed_dropout = opts.embed_dropout
        self.fc_dropout = opts.fc_dropout

        self.embeddings = nn.Embedding(self.word_num, self.embed_dim)
        self.embeddings_static = nn.Embedding(self.word_num, self.embed_dim)

        if opts.pre_embed_path != '':
            embedding = Embedding.load_predtrained_emb_zero(self.pre_embed_path, self.string2id)
            self.embeddings_static.weight.data.copy_(embedding)
        else:
            nn.init.uniform_(self.embeddings_static.weight.data, -self.embed_uniform_init, self.embed_uniform_init)

        nn.init.uniform_(self.embeddings.weight.data, -self.embed_uniform_init, self.embed_uniform_init)

        # 2 convs
        self.convs = nn.ModuleList(
            [nn.Conv2d(2, self.embed_dim, (K, self.embed_dim), stride=self.stride, padding=(K // 2, 0)) for K in self.kernel_size])

        in_fea = len(self.kernel_size)*self.kernel_num
        self.linear1 = nn.Linear(in_fea, in_fea // 2)
        self.linear2 = nn.Linear(in_fea // 2, self.label_num)
        self.embed_dropout = nn.Dropout(self.embed_dropout)
        self.fc_dropout = nn.Dropout(self.fc_dropout)

这个部分主要将输入的通道数1改为2即可。

数据流通部分:

def forward(self, input):
        static_embed = self.embeddings_static(input)  # torch.Size([64, 39, 100])
        embed = self.embeddings(input)  # torch.Size([64, 39, 100])

        x = torch.stack([static_embed, embed], 1)  # torch.Size([64, 2, 39, 100])

        out = self.embed_dropout(x)

        l = []
        for conv in self.convs:
            l.append(F.relu(conv(out)).squeeze(3))  # torch.Size([64, 100, 39])

        out = l
        l = []
        for i in out:
            l.append(F.max_pool1d(i, kernel_size=i.size(2)).squeeze(2))  # torch.Size([64, 100])

        out = torch.cat(l, 1)  # torch.Size([64, 300])

        out = self.fc_dropout(out)

        out = self.linear1(out)
        out = self.linear2(F.relu(out))

        return out

这里主要就是一个stack函数的应用,将两个embedding放到一个新的维度里。

数据对比

可以明显看出多通道优点还是很突出的。

github地址:

https://github.com/zenRRan/Sentiment-Analysis/blob/master/models/multi_channel_CNN.py

欢迎fork,有问题大家尽管指出!

PS:上述图片均来自于导师张梅山,唐都钰的《Deep Learning in Natural Language Processing》的情感分析篇。

IELTS a bit

rival n. 竞争对手

v. 与...相匹敌

roar n/v. 咆哮,吼叫

robust adj. 强劲的;富有活力的

slippery adj. 滑的;光滑的


原文发布于微信公众号 - 深度学习自然语言处理(zenRRan)

原文发表时间:2018-11-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏新智元

DeepMind重磅:神经算术逻辑单元,Keras实现

【新智元导读】DeepMind最新提出“神经算术逻辑单元”,旨在解决神经网络数值模拟能力不足的问题。与传统架构相比,NALU在训练期间的数值范围内和范围外都得到...

8420
来自专栏漫漫深度学习路

信息熵(entropy)

information entropy 信息熵用来描述信息的不确定性,如果不确定性越高,那么信息熵越大,否则则越低。 自信息(信息量) I(X)称为自信息,I(...

37580
来自专栏新智元

谷歌开源神经网络模型,压缩图片比传统方法提升25%(附论文)

【新智元导读】 谷歌官方博客今天发布了一篇文章,介绍如何使用神经网络压缩图片。在论文中,谷歌证明了神经网络可以获得比现在普遍使用的压缩方法质量更好、大小更小的图...

44140
来自专栏机器学习算法工程师

机器学习之——自动求导

作者:叶虎 小编:张欢 随机梯度下降法(SGD)是训练深度学习模型最常用的优化方法。在前期文章中我们讲了梯度是如何计算的,主要采用BP算法,或者说利用链式法则...

35180
来自专栏人工智能头条

如何使用 RNN 模型实现文本自动生成 |

58520
来自专栏文武兼修ing——机器学习与IC设计

基于Pytorch的CapsNet源码详解CapsNet基本结构代码实现参考

CapsNet基本结构 参考CapsNet的论文,提出的基本结构如下所示: ? capsnet_mnist.jpg 可以看出,CapsNet的基本结构如下所示:...

37870
来自专栏目标检测和深度学习

Hinton向量学院推出神经ODE:超越ResNet 4大性能优势

【导读】Hinton创建的向量学院的研究者提出了一类新的神经网络模型,神经常微分方程(Neural ODE),将神经网络与常微分方程结合在一起,用ODE来做预测...

24130
来自专栏小小挖掘机

论文笔记系列(一)-Seq2Seq与RL的结合综述!

这篇论文是一篇综述性质的文章吧,研究了现有的Seq2Seq模型的应用和不足,以及如何通过不同的强化学习方法解决不足,写的深入具体,mark一下。

23650
来自专栏企鹅号快讯

深度离散哈希算法,可用于图像检索!

-免费加入AI技术专家社群>> 智能感知与计算研究中心李琦博士提出了一种深度离散哈希算法(discrete hashing algorithm),该算法认为学习...

83560
来自专栏人工智能头条

Softmax和交叉熵的深度解析和Python实现

【导读】如果你稍微了解一点深度学习的知识或者看过深度学习的在线课程,你就一定知道最基础的多分类问题。当中,老师一定会告诉你在全连接层后面应该加上 Softmax...

26610

扫码关注云+社区

领取腾讯云代金券