CNN 做 文本分类

文章目录

概述

有时候我们想用CNN来做文本分类。文本分类大多是RNN模型来做,但是对于分类任务来说CNN是更加擅长的。所以我们可以用CNN来进行文本的分类。

环境

pytorch=1.8 python=3.8 rtx2080ti

模型

对于一个语料库我们要先用 wordv2vec 预训练一个词向量模型,在早期使用 one-hot 来做,实际上,对于大的语料库来说需要很大的内存开销。所以就可以用word2vec预训练一个词向量模型。然后用他来当cnn的第一层,它不冻结参数,参与模型的训练,进行反向传播。当然pytorch有现成的embedding库,他是随机的权重,与语料库几乎无关的。所以训练起来慢,精度也不高。对于分类任务来说,多阶段的分类精度会更高。所以我们可以先训练一个词向量权重。
接着就用一个3层的cnn来搭建模型。为什么只有3层?因为cnn太容易过拟合了,模型加深会导致模型的误差升高,包括训练误差和验证误差。这就不是过拟合了,因为训练误差也升高了。所以用小一些的模型来做分类不失为一个好选择。当然可以用resnet把模型加深,模型越深,分类的精确度也越高,可以考虑用resnet50 或者 resnet100 来做。其实对于一个二分类来说,三层很够用了。

class TextCNN(nn.Module):
    def __init__(self, vocab, embed_size, kernel_sizes, num_channels, weight):
        super(TextCNN, self).__init__()
        # 将预训练好的word2vec放进来
        self.embedding = nn.Embedding.from_pretrained(torch.from_numpy(weight))
        # 不参与训练的嵌入层
        self.constant_embedding = nn.Embedding(len(vocab), embed_size)
        self.dropout = nn.Dropout(0.5)
        self.decoder = nn.Linear(sum(num_channels), 2)
        # 时序最大池化层没有权重,所以可以共用一个实例
        self.pool = GlobalMaxPool1d()
        self.convs = nn.ModuleList()  # 创建多个一维卷积层
        for c, k in zip(num_channels, kernel_sizes):
            self.convs.append(nn.Conv1d(in_channels=2 * embed_size,
                                        out_channels=c,
                                        kernel_size=k))

    def forward(self, inputs):
        # 将两个形状是(批量大小, 词数, 词向量维度)的嵌入层的输出按词向量连结
        embeddings = self.embedding(inputs)
        embeddings.to(device)
        embeddings_2 = self.constant_embedding(inputs)
        embeddings = torch.cat((
            embeddings,
            embeddings_2), dim=2)  # (batch, seq_len, 2*embed_size)
        # 根据Conv1D要求的输入格式,将词向量维,即一维卷积层的通道维(即词向量那一维),变换到前一维
        embeddings.to(device)
        embeddings = embeddings.permute(0, 2, 1)
        # 对于每个一维卷积层,在时序最大池化后会得到一个形状为(批量大小, 通道大小, 1)的
        # Tensor。使用flatten函数去掉最后一维,然后在通道维上连结
        # embeddings.to(device)
        encoding = torch.cat([self.pool(torch.relu(conv(embeddings))).squeeze(-1) for conv in self.convs], dim=1)
        # 应用丢弃法后使用全连接层得到输出
        outputs = self.decoder(self.dropout(encoding))
        return outputs

主要介绍cnn的搭建。word2vec怎么使用网络上很多。解析中文的分词可以用 jieba库。还有记得做分词的时候把标点符号啥的去掉 可以用正则表达式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值