文本分类(一) | (6) 多层双向LSTM

项目Github地址

本篇博客主要介绍基于多层双向LSTM的文本分类算法的原理及实现细节。

目录

1. 分类原理

2. 实现细节


1. 分类原理

 对于输入文本序列,在LSTM的每个时间步输入序列中一个单词的嵌入表示,计算当前时间步的隐藏状态,用于当前时间步的输出以及传递给下一个时间步和下一 个单词的词向量一起作为LSTM单元输入,然后再计算下一个时间步的LSTM隐藏状态,以此重复...直到处理完输入文本序列中的每一个单词,如果输入文本序列的长度为n,那么就要经历n个时间步。

一般取前向和反向LSTM在最后一个时间步的隐藏状态,进行拼接,再接一个全连接层进行分类。由于LSTM训练比较困难,层数一般不超过两层。

2. 实现细节

class MulBiLSTM(BasicModule):#继承自BasicModule 其中封装了保存加载模型的接口,BasicModule继承自nn.Module
    def __init__(self, vocab_size,opt):#opt是config类的实例 里面包括所有模型超参数的配置
        super(MulBiLSTM, self).__init__()

        #嵌入层
        self.embedding = nn.Embedding(vocab_size, opt.embed_size)#词嵌入矩阵 每一行代表词典中一个词对应的词向量;
        # 词嵌入矩阵可以随机初始化连同分类任务一起训练,也可以用预训练词向量初始化(冻结或微调)

        # bidirectional设为True即得到双向循环神经网络
        self.encoder = nn.LSTM(input_size=opt.embed_size,
                               hidden_size=opt.recurrent_hidden_size,
                               num_layers=opt.num_layers,
                               bidirectional=True,
                               dropout=opt.drop_prop
                               )
        self.fc = nn.Linear(4 * opt.recurrent_hidden_size, opt.classes)  # 初始时间步和最终时间步的隐藏状态作为全连接层输入

    def forward(self, inputs):
        # inputs的形状是(批量大小, 词数),因为上述定义的LSTM没有设置参数batch_first=True(默认False),所以需要将序列长度(seq_len)作为第一维,所以将输入转置后再提取词特征
        embeddings = self.embedding(inputs.permute(1,0)) # (seq_len, batch_size,embed_size)

        # rnn.LSTM只传入输入embeddings(第一层的输入),因此只返回最后一层的隐藏层在各时间步的隐藏状态。
        # outputs形状是(seq_len, batch_size, 2 * recurrent_hidden_size)
        outputs, _ = self.encoder(embeddings)  # output, (h, c)
        # 连结初始时间步和最终时间步的隐藏状态作为全连接层输入。它的形状为
        # (batch_size, 4 * recurrent_hidden_size)。
        encoding = torch.cat((outputs[0], outputs[-1]), -1)
        outs = self.fc(encoding)
        #(batch_size,classes)
        return outs
发布了365 篇原创文章 · 获赞 714 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/sdu_hao/article/details/103598133