详解文本分类之DeepCNN的理论与实践

导读

最近在梳理文本分类的各个神经网络算法,特地一个来总结下。下面目录中多通道卷积已经讲过了,下面是链接,没看的可以瞅瞅。我会一个一个的讲解各个算法的理论与实践。目录暂定为:

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

之后的以后再补充。今天我们该将第二个,深度卷积神经网络(DeepCNN)。

DeepCNN

DeepCNN即是深度卷积神经网络,就是有大于1层的卷积网络,也可以说是多层卷积网络(Multi_Layer_CNN,咳咳,我就是这么命名滴!)我们来直接上图,看看具体长得啥样子:

我大概描述下这个过程,比如sent_len=10,embed_dim=100,也就是输入的矩阵为(10*100),假设kernel num=n,用了上下padding,kernel size=(3*100),那么卷积之后输出的矩阵为(n*10),接着再将该矩阵放入下个卷积中,放之前我们先对这个矩阵做个转置,你肯定要问为什么?俺来告诉你我自己的认识,有两点:

  • 硬性要求:这个矩阵第一个维度为10是句子长度产生的,所以是变量,我们习惯将该维度的大小控制为定量,比如第一个输入的值就是(sent_len,embed_dim),embed_dim就为定量,不变。所以转置即可。
  • 理论要求:(n*10)中的n处于的维度的数据表示的是上个数据kernel对这个数据的10个数据第一次计算,第二次计算... 第10次计算,也就可以表示为通过kernel对上个数据的每个词和它的上下文进行了新的特征提取。n则表示用n个kernel对上个句子提取了n次。则最终的矩阵为(n*10),我们要转成和输入的格式一样,将第二维度依然放上一个词的表示。所以转置即可。

n 可以设置100,200等。

然后对最终的结果进行pooling,cat,然后进过线性层映射到分类上,进过softmax上进行预测输出即可。

上述仅仅说的是两层CNN的搭建,当然你可以搭建很多层啦。

实践

下面看下具体的pytotch代码如何实现

类Multi_Layer_CNN的初始化

def __init__(self, opts, vocab, label_vocab):
        super(Multi_Layer_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)
        if opts.pre_embed_path != '':
            embedding = Embedding.load_predtrained_emb_zero(self.pre_embed_path, self.string2id)
            self.embeddings.weight.data.copy_(embedding)
        else:
            nn.init.uniform_(self.embeddings.weight.data, -self.embed_uniform_init, self.embed_uniform_init)

        # 2 convs
        self.convs1 = nn.ModuleList(
            [nn.Conv2d(1, self.embed_dim, (K, self.embed_dim), stride=self.stride, padding=(K // 2, 0)) for K in self.kernel_size])
        self.convs2 = nn.ModuleList(
            [nn.Conv2d(1, self.kernel_num, (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)

数据流动

def forward(self, input):

        out = self.embeddings(input)
        out = self.embed_dropout(out)  # torch.Size([64, 39, 100])

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

        out = l
        l = []
        for conv, last_out in zip(self.convs2, out):
            l.append(F.relu(conv(last_out.unsqueeze(1))).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

数据对比

可以看出多层(深层)CNN还是在有提升的。

github地址:

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

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

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

IELTS a bit

stain n. 污点;污染

stake n. 投资,投放的本钱

utilize v. 使用;利用

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

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吉浦迅科技

深度学习GeForce GTX 1080/Titan X(Maxwell)/ Titan X (Pascal)比较

【新智元导读】深度学习计算该买哪款GPU,选择哪个平台?这篇文章为你提供对比指南。 购买用于运行深度学习算法的硬件时,我们常常找不到任何有用的基准,唯一的选择是...

2.4K50
来自专栏ATYUN订阅号

正则化贪心森林(RGF)的入门简介,含案例研究

作为曾参与机器学习竞赛的数据科学家,我一直在寻找“非主流”的算法。使用这些算法可能不会成为竞争的赢家。但是他们有独特的预测方式。这些算法可以在集成模型中使用,以...

53460
来自专栏IT派

用TensorFlow和TensorBoard从零开始构建ConvNet(CNN)

摘要: Tensorflow作为当下最流行的深度学习框架,实现ConvNet(CNN)自然是轻而易举,但是本文创造性的使用的TensorBoard来图形化展示...

68950
来自专栏Coding迪斯尼

RNN,具有记忆功能神经网络的理解与实现

我们当前掌握的网络类型,统称为feed forward网络。这种网络的特点是,当我们把很多条数据输入网络进行训练时,网络没有“记忆性”,也就是网络认为前一条输入...

13020
来自专栏一名叫大蕉的程序员

尝试克服一下小伙伴对神经网络的恐惧No.26

我是小蕉。 研表究明,这的网官的demo,代码确实的是己打自的。 这两天仔细研究了一下神经网络,简单的结构其实没想象中那么恐怖,只是我们自己吓自己,今天希望能把...

21060
来自专栏悦思悦读

数据挖掘_R_Python_ML(2): Linear Regression vs SVR

在上一篇“数据挖掘: R, Python,Machine Learning,一起学起来!”中,我们介绍了用R进行线性回归的例子。 这次我们来看看,同样一份简单的...

45890
来自专栏杨熹的专栏

LightGBM 如何调参

1.2K40
来自专栏Coding迪斯尼

用python实现数字图片识别神经网络--实现网络训练功能

20830
来自专栏PPV课数据科学社区

K-means 在 Python 中的实现

K-means算法简介 K-means是机器学习中一个比较常用的算法,属于无监督学习算法,其常被用于数据的聚类,只需为它指定簇的数量即可自动将数据聚合到多类中,...

37690
来自专栏Coding迪斯尼

依赖反向传播改进神经网络数据处理的精确度

13540

扫码关注云+社区

领取腾讯云代金券