开发者社区> 技术小能手> 正文

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

简介:
+关注继续查看

导读

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

多通道卷积神经网络(multi_channel_CNN)

深度卷积神经网络(deep_CNN)

基于字符的卷积神经网络(Char_CNN)

循环与卷积神经网络并用网络(LSTM_CNN)

树状LSTM神经网络(Tree-LSTM)

Transformer(目前常用于NMT)

etc..

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

DeepCNN

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

1fc49a6cfed10a69903eedc9763231df254ecf89

我大概描述下这个过程,比如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

数据对比

00013719aad4cfbfc7d686db2000cc3bfd94a4a6

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

原文发布时间为:2018-11-8

原文作者:zenRRan

本文来自云栖社区合作伙伴“深度学习自然语言处理”,了解相关信息可以关注“深度学习自然语言处理”。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23589 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
22367 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
14282 0
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
19823 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
22543 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
36479 0
+关注
技术小能手
云栖运营小编~
7195
文章
9
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载