Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >教你几招搞定 LSTMs 的独门绝技(附代码)

教你几招搞定 LSTMs 的独门绝技(附代码)

作者头像
AI研习社
发布于 2018-07-26 08:27:01
发布于 2018-07-26 08:27:01
3.3K02
代码可运行
举报
文章被收录于专栏:AI研习社AI研习社
运行总次数:2
代码可运行

本文为雷锋字幕组编译的技术博客,原标题 Taming LSTMs: Variable-sized mini-batches and why PyTorch is good for your health ,作者为 William Falcon 。 翻译 | 赵朋飞 马力群 涂世文 整理 | MY

如果你用过 PyTorch 进行深度学习研究和实验的话,你可能经历过欣喜愉悦、能量爆棚的体验,甚至有点像是走在阳光下,感觉生活竟然如此美好 。但是直到你试着用 PyTorch 实现可变大小的 mini-batch RNNs 的时候,瞬间一切又回到了解放前。

不怕,我们还是有希望的。读完这篇文章,你又会找回那种感觉,你和 PyTorch 步入阳光中,此时你的循环神经网络模型的准确率又创新高,而这种准确率你只在 Arxiv 上读到过。真让人觉得兴奋!

我们将告诉你几个独门绝技:

1.如何在 PyTorch 中采用 mini-batch 中的可变大小序列实现 LSTM 。

2. PyTorch 中 pack_padded_sequence 和 pad_packed_sequence 的原理和作用。

3.在基于时间维度的反向传播算法中屏蔽(Mask Out)用于填充的符号。

TIPS: 文本填充,使所有文本长度相等,pack_padded_sequence , 运行LSTM,使用 pad_packed_sequence,扁平化所有输出和标签, 屏蔽填充输出, 计算交叉熵损失函数(Cross-Entropy)。

为何知其难而为之?

当然是速度和性能啦。

将可变长度元素同时输入到 LSTM 曾经可是一个艰巨的技术挑战,不过像 PyTorch 这样的框架已经基本解决了( Tensorflow 也有一个很好的解决方案,但它看起来非常非常复杂)。

此外,文档也没有很清楚的解释,用例也很老旧。正确的做法是使用来自多个示样本的梯度,而不是仅仅来自一个样本。这将加快训练速度,提高梯度下降的准确性 。

尽管 RNNs 很难并行化,因为每一步都依赖于上一步,但是使用 mini-batch 在速度上将会使其得到很大的提升。

序列标注

先来尝试一个简单的序列标注问题,在这里我们会创建一个 LSTM/GRU 模型 对贾斯汀·比伯的歌词做词性标注。譬如:“is it too late now to say sorry?” (移除 ’to’ 和 ’?’ )。

数据格式化

在实际情况中你会做大量的格式化处理,但在这里由于篇幅限制我们不会这样做。为简单起见,让我们用不同长度的序列来制作这组人造数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sent_1_x = ['is', 'it', 'too', 'late', 'now', 'say', 'sorry']
sent_1_y = ['VB', 'PRP', 'RB', 'RB', 'RB', 'VB', 'JJ']
sent_2_x = ['ooh', 'ooh']
sent_2_y = ['NNP', 'NNP']
sent_3_x = ['sorry', 'yeah']
sent_3_y = ['JJ', 'NNP']
X = [sent_1_x, sent_2_x, sent_3_x]
Y = [sent_1_y, sent_2_y, sent_3_y]

当我们将每个句子输入到嵌入层(Embedding Layer)的时候,每个单词(word)将会映射(mapping)到一个索引(index),所以我们需要将他们转换成整数列表(list)。

索引一个词嵌入矩阵(Embedding Matrix)

这里我们将这些句子映射到相应的词汇表(V)索引

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# map sentences to vocab
vocab = {'<PAD>': 0, 'is': 1, 'it': 2, 'too': 3, 'late': 4, 'now': 5, 'say': 6, 'sorry': 7, 'ooh': 8, 'yeah': 9} 
# fancy nested list comprehension
X =  [[vocab[word] for word in sentence] for sentence in X]
# X now looks like:  
# [[1, 2, 3, 4, 5, 6, 7], [8, 8], [7, 9]]

对于分类标签也是一样的(在我们的例子中是 POS 标记),这些不会嵌入 。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tags = {'<PAD>': 0, 'VB': 1, 'PRP': 2, 'RB': 3, 'JJ': 4, 'NNP': 5}
# fancy nested list comprehension
Y =  [[tags[tag] for tag in sentence] for sentence in Y]
# Y now looks like:
# [[1, 2, 3, 3, 3, 1, 4], [5, 5], [4, 5]]

技巧 1:利用填充(Padding)使 mini-batch 中所有的序列具有相同的长度。

在模型里有着不同长度的是什么?当然不会是我们的每批数据!

利用 PyTorch 处理时,在填充之前,我们需要保存每个序列的长度。我们需要利用这些信息去掩盖(mask out)损失函数,使其不对填充元素进行计算。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
X = [[0, 1, 2, 3, 4, 5, 6], 
    [7, 7], 
    [6, 8]]
# get the length of each sentence
X_lengths = [len(sentence) for sentence in X]
# create an empty matrix with padding tokens
pad_token = vocab['<PAD>']
longest_sent = max(X_lengths)
batch_size = len(X)
padded_X = np.ones((batch_size, longest_sent)) * pad_token
# copy over the actual sequences
for i, x_len in enumerate(X_lengths):
  sequence = X[i]
  padded_X[i, 0:x_len] = sequence[:x_len]
# padded_X looks like:
array([[ 1.,  2.,  3.,  4.,  5.,  6.,  7.],
       [ 8.,  8.,  0.,  0.,  0.,  0.,  0.],
       [ 7.,  9.,  0.,  0.,  0.,  0.,  0.]])

我们用同样的方法处理标签 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
Y = [[1, 2, 3, 3, 3, 1, 4], 
    [5, 5], 
    [4, 5]]
# get the length of each sentence
Y_lengths = [len(sentence) for sentence in Y]
# create an empty matrix with padding tokens
pad_token = tags['<PAD>']
longest_sent = max(Y_lengths)
batch_size = len(Y)
padded_Y = np.ones((batch_size, longest_sent)) * pad_token
# copy over the actual sequences
for i, y_len in enumerate(Y_lengths):
  sequence = Y[i]
  padded_Y[i, 0:y_len] = sequence[:y_len]
# padded_Y looks like:
array([[ 1.,  2.,  3.,  3.,  3.,  1.,  4.],
       [ 5.,  5.,  0.,  0.,  0.,  0.,  0.],
       [ 4.,  5.,  0.,  0.,  0.,  0.,  0.]])

数据处理总结:

我们将这些元素转换成索引序列并通过加入 0 元素对每个序列进行填充(Zero Padding),这样每批数据就可以拥有相同的长度。

现在我们的数据的形式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# X 
array([[ 1.,  2.,  3.,  4.,  5.,  6.,  7.],
       [ 8.,  8.,  0.,  0.,  0.,  0.,  0.],
       [ 7.,  9.,  0.,  0.,  0.,  0.,  0.]])
# Y 
array([[ 1.,  2.,  3.,  3.,  3.,  1.,  4.],
       [ 5.,  5.,  0.,  0.,  0.,  0.,  0.],
       [ 4.,  5.,  0.,  0.,  0.,  0.,  0.]])

构建模型

借助 PyTorch 我们可以搭建一个非常简单的 LSTM 网络。模型的层结构如下:

1. 词嵌入层(Embedding Layer)

2. LSTM 层

3. 线性全连接层

4. Softmax 层

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.nn import functional as F

"""
Blog post:
Taming LSTMs: Variable-sized mini-batches and why PyTorch is good for your health:
https://medium.com/@_willfalcon/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e
"""


class BieberLSTM(nn.Module):
    def __init__(self, nb_layers, nb_lstm_units=100, embedding_dim=3, batch_size=3):
        self.vocab = {'<PAD>': 0, 'is': 1, 'it': 2, 'too': 3, 'late': 4, 'now': 5, 'say': 6, 'sorry': 7, 'ooh': 8,
                      'yeah': 9}
        self.tags = {'<PAD>': 0, 'VB': 1, 'PRP': 2, 'RB': 3, 'JJ': 4, 'NNP': 5}

        self.nb_layers = nb_layers
        self.nb_lstm_units = nb_lstm_units
        self.embedding_dim = embedding_dim
        self.batch_size = batch_size

        # don't count the padding tag for the classifier output
        self.nb_tags = len(self.tags) - 1

        # when the model is bidirectional we double the output dimension
        self.lstm

        # build actual NN
        self.__build_model()

    def __build_model(self):
        # build embedding layer first
        nb_vocab_words = len(self.vocab)

        # whenever the embedding sees the padding index it'll make the whole vector zeros
        padding_idx = self.vocab['<PAD>']
        self.word_embedding = nn.Embedding(
            num_embeddings=nb_vocab_words,
            embedding_dim=self.embedding_dim,
            padding_idx=padding_idx
        )

        # design LSTM
        self.lstm = nn.LSTM(
            input_size=self.embedding_dim,
            hidden_size=self.nb_lstm_units,
            num_layers=self.nb_lstm_layers,
            batch_first=True,
        )

        # output layer which projects back to tag space
        self.hidden_to_tag = nn.Linear(self.nb_lstm_units, self.nb_tags)

    def init_hidden(self):
        # the weights are of the form (nb_layers, batch_size, nb_lstm_units)
        hidden_a = torch.randn(self.hparams.nb_lstm_layers, self.batch_size, self.nb_lstm_units)
        hidden_b = torch.randn(self.hparams.nb_lstm_layers, self.batch_size, self.nb_lstm_units)

        if self.hparams.on_gpu:
            hidden_a = hidden_a.cuda()
            hidden_b = hidden_b.cuda()

        hidden_a = Variable(hidden_a)
        hidden_b = Variable(hidden_b)

        return (hidden_a, hidden_b)

技巧2:使用 PyTorch 中的 pack_padded_sequence 和 pad_packed_sequence API

再次重申一下,现在我们输入的一批数据中的每组数据均已被填充为相同长度。

在前向传播中,我们将:

1. 对序列进行词嵌入(Word Embedding)操作

2. 使用 pack_padded_sequence 来确保 LSTM 模型不会处理用于填充的元素。

3. 在 LSTM 上运行 packed_batch

4. 使用 pad_packed_sequence 解包(unpack)pack_padded_sequence 操作后的序列

5. 对 LSTM 的输出进行变换,从而可以被输入到线性全连接层中

6. 再通过对序列计算 log_softmax

7. 最后将数据维度转换回来,最终的数据维度为 (batch_size, seq_len, nb_tags)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"""
Blog post:
Taming LSTMs: Variable-sized mini-batches and why PyTorch is good for your health:
https://medium.com/@_willfalcon/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e
"""

    def forward(self, X, X_lengths):
        # reset the LSTM hidden state. Must be done before you run a new batch. Otherwise the LSTM will treat
        # a new batch as a continuation of a sequence
        self.hidden = self.init_hidden()

        batch_size, seq_len, _ = X.size()

        # ---------------------
        # 1. embed the input
        # Dim transformation: (batch_size, seq_len, 1) -> (batch_size, seq_len, embedding_dim)
        X = self.word_embedding(X)

        # ---------------------
        # 2. Run through RNN
        # TRICK 2 ********************************
        # Dim transformation: (batch_size, seq_len, embedding_dim) -> (batch_size, seq_len, nb_lstm_units)

        # pack_padded_sequence so that padded items in the sequence won't be shown to the LSTM
        X = torch.nn.utils.rnn.pack_padded_sequence(x, X_lengths, batch_first=True)

        # now run through LSTM
        X, self.hidden = self.lstm(X, self.hidden)

        # undo the packing operation
        X, _ = torch.nn.utils.rnn.pad_packed_sequence(X, batch_first=True)

        # ---------------------
        # 3. Project to tag space
        # Dim transformation: (batch_size, seq_len, nb_lstm_units) -> (batch_size * seq_len, nb_lstm_units)

        # this one is a bit tricky as well. First we need to reshape the data so it goes into the linear layer
        X = X.contiguous()
        X = X.view(-1, X.shape[2])

        # run through actual linear layer
        X = self.hidden_to_tag(X)

        # ---------------------
        # 4. Create softmax activations bc we're doing classification
        # Dim transformation: (batch_size * seq_len, nb_lstm_units) -> (batch_size, seq_len, nb_tags)
        X = F.log_softmax(X, dim=1)

        # I like to reshape for mental sanity so we're back to (batch_size, seq_len, nb_tags)
        X = X.view(batch_size, seq_len, self.nb_tags)

        Y_hat = X
        return Y_hat

技巧 3 : 屏蔽(Mask Out )我们并不想在损失函数中处理的网络输出

屏蔽(Mask Out) 那些填充的激活函数

最终,我们准备要计算损失函数了。这里的重点在于我们并不想让用于填充的元素影响到最终的输出。

小提醒:最好的方法是将所有的网络输出和标签展平。然后计算其所在序列的损失值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"""
Blog post:
Taming LSTMs: Variable-sized mini-batches and why PyTorch is good for your health:
https://medium.com/@_willfalcon/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e
"""

    def loss(self, Y_hat, Y, X_lengths):
        # TRICK 3 ********************************
        # before we calculate the negative log likelihood, we need to mask out the activations
        # this means we don't want to take into account padded items in the output vector
        # simplest way to think about this is to flatten ALL sequences into a REALLY long sequence
        # and calculate the loss on that.

        # flatten all the labels
        Y = Y.view(-1)

        # flatten all predictions
        Y_hat = Y_hat.view(-1, self.nb_tags)

        # create a mask by filtering out all tokens that ARE NOT the padding token
        tag_pad_token = self.tags['<PAD>']
        mask = (Y > tag_pad_token).float()

        # count how many tokens we have
        nb_tokens = int(torch.sum(mask).data[0])

        # pick the values for the label and zero out the rest with the mask
        Y_hat = Y_hat[range(Y_hat.shape[0]), Y] * mask

        # compute cross entropy loss which ignores all <PAD> tokens
        ce_loss = -torch.sum(Y_hat) / nb_tokens

        return ce_loss

哇哦~ 就是这么简单不是吗?现在使用 mini-batches 你可以更快地训练你的模型了!

当然这还仅仅是个非常简单的 LSTM 原型。你还可以做这样一些事情来增加模型的复杂度,以此提升模型的效果:

1. 利用 Glove Embeddings 进行初始化。

2. 使用 GRU Cell 代替 LSTM 部分结构

3. 采用双向机制(别忘了修改 init_hidden 函数)

4. 通过用卷积神经网络生成编码向量并加入词向量中来使用字符级特征

5. 添加 Dropout 层

6. 增加神经网络的层数

7. 当然,也可以使用基于 Python 的超参数优化库(test-tube,链接:https://github.com/williamFalcon/test_tube) 来寻找最优超参数。

总结一下:

这便是在 PyTorch 中解决 LSTM 变长批输入的最佳实践。

1. 将序列从长到短进行排序

2. 通过序列填充使得输入序列长度保持一致

3. 使用 pack_padded_sequence 确保 LSTM 不会额外处理序列中的填充项(Facebook 的 Pytorch 团队真应该考虑为这个绕口的 API 换个名字 !)

4. 使用 pad_packed_sequence 对步骤 3的操作进行还原

5. 将输出和标记展平为一个长的向量

6. 屏蔽(Mask Out) 你不想要的输出

7. 计算其 Cross-Entropy (交叉熵)

完整代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.nn import functional as F

"""
Blog post:
Taming LSTMs: Variable-sized mini-batches and why PyTorch is good for your health:
https://medium.com/@_willfalcon/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e
"""


class BieberLSTM(nn.Module):
    def __init__(self, nb_layers, nb_lstm_units=100, embedding_dim=3, batch_size=3):
        self.vocab = {'<PAD>': 0, 'is': 1, 'it': 2, 'too': 3, 'late': 4, 'now': 5, 'say': 6, 'sorry': 7, 'ooh': 8,
                      'yeah': 9}
        self.tags = {'<PAD>': 0, 'VB': 1, 'PRP': 2, 'RB': 3, 'JJ': 4, 'NNP': 5}

        self.nb_layers = nb_layers
        self.nb_lstm_units = nb_lstm_units
        self.embedding_dim = embedding_dim
        self.batch_size = batch_size

        # don't count the padding tag for the classifier output
        self.nb_tags = len(self.tags) - 1

        # when the model is bidirectional we double the output dimension
        self.lstm

        # build actual NN
        self.__build_model()

    def __build_model(self):
        # build embedding layer first
        nb_vocab_words = len(self.vocab)

        # whenever the embedding sees the padding index it'll make the whole vector zeros
        padding_idx = self.vocab['<PAD>']
        self.word_embedding = nn.Embedding(
            num_embeddings=nb_vocab_words,
            embedding_dim=self.embedding_dim,
            padding_idx=padding_idx
        )

        # design LSTM
        self.lstm = nn.LSTM(
            input_size=self.embedding_dim,
            hidden_size=self.nb_lstm_units,
            num_layers=self.nb_lstm_layers,
            batch_first=True,
        )

        # output layer which projects back to tag space
        self.hidden_to_tag = nn.Linear(self.nb_lstm_units, self.nb_tags)

    def init_hidden(self):
        # the weights are of the form (nb_layers, batch_size, nb_lstm_units)
        hidden_a = torch.randn(self.hparams.nb_lstm_layers, self.batch_size, self.nb_lstm_units)
        hidden_b = torch.randn(self.hparams.nb_lstm_layers, self.batch_size, self.nb_lstm_units)

        if self.hparams.on_gpu:
            hidden_a = hidden_a.cuda()
            hidden_b = hidden_b.cuda()

        hidden_a = Variable(hidden_a)
        hidden_b = Variable(hidden_b)

        return (hidden_a, hidden_b)

    def forward(self, X, X_lengths):
        # reset the LSTM hidden state. Must be done before you run a new batch. Otherwise the LSTM will treat
        # a new batch as a continuation of a sequence
        self.hidden = self.init_hidden()

        batch_size, seq_len, _ = X.size()

        # ---------------------
        # 1. embed the input
        # Dim transformation: (batch_size, seq_len, 1) -> (batch_size, seq_len, embedding_dim)
        X = self.word_embedding(X)

        # ---------------------
        # 2. Run through RNN
        # TRICK 2 ********************************
        # Dim transformation: (batch_size, seq_len, embedding_dim) -> (batch_size, seq_len, nb_lstm_units)

        # pack_padded_sequence so that padded items in the sequence won't be shown to the LSTM
        X = torch.nn.utils.rnn.pack_padded_sequence(x, X_lengths, batch_first=True)

        # now run through LSTM
        X, self.hidden = self.lstm(X, self.hidden)

        # undo the packing operation
        X, _ = torch.nn.utils.rnn.pad_packed_sequence(X, batch_first=True)

        # ---------------------
        # 3. Project to tag space
        # Dim transformation: (batch_size, seq_len, nb_lstm_units) -> (batch_size * seq_len, nb_lstm_units)

        # this one is a bit tricky as well. First we need to reshape the data so it goes into the linear layer
        X = X.contiguous()
        X = X.view(-1, X.shape[2])

        # run through actual linear layer
        X = self.hidden_to_tag(X)

        # ---------------------
        # 4. Create softmax activations bc we're doing classification
        # Dim transformation: (batch_size * seq_len, nb_lstm_units) -> (batch_size, seq_len, nb_tags)
        X = F.log_softmax(X, dim=1)

        # I like to reshape for mental sanity so we're back to (batch_size, seq_len, nb_tags)
        X = X.view(batch_size, seq_len, self.nb_tags)

        Y_hat = X
        return Y_hat

    def loss(self, Y_hat, Y, X_lengths):
        # TRICK 3 ********************************
        # before we calculate the negative log likelihood, we need to mask out the activations
        # this means we don't want to take into account padded items in the output vector
        # simplest way to think about this is to flatten ALL sequences into a REALLY long sequence
        # and calculate the loss on that.

        # flatten all the labels
        Y = Y.view(-1)

        # flatten all predictions
        Y_hat = Y_hat.view(-1, self.nb_tags)

        # create a mask by filtering out all tokens that ARE NOT the padding token
        tag_pad_token = self.tags['<PAD>']
        mask = (Y > tag_pad_token).float()

        # count how many tokens we have
        nb_tokens = int(torch.sum(mask).data[0])

        # pick the values for the label and zero out the rest with the mask
        Y_hat = Y_hat[range(Y_hat.shape[0]), Y] * mask

        # compute cross entropy loss which ignores all <PAD> tokens
        ce_loss = -torch.sum(Y_hat) / nb_tokens

        return ce_loss

原文链接:

https://towardsdatascience.com/taming-lstms-variable-sized-mini-batches-and-why-pytorch-is-good-for-your-health-61d35642972e

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
tf39:tensorflow之seq2seq
seq2seq还是很赞的,既能做翻译、又能做image captioning,还能做多标签。
MachineLP
2019/05/26
4510
[深度学习] RNN对于变长序列的处理方法, 为什么RNN需要mask
文本数据在处理的时候,由于各样本的长度并不一样,有的句子长有的句子短。抛开动态图、静态图模型的差异,由于需要进行矩阵运算,句长需要是等长的才可以,这就需要padding操作。padding一般是用最长的句子长度为最大长度,然后其他样本补0到最大长度,这样样本就是等长的了。
全栈程序员站长
2022/09/27
2.6K0
[深度学习] RNN对于变长序列的处理方法, 为什么RNN需要mask
如何从零开始用PyTorch实现Chatbot?(附完整代码)
作者 | 李理,环信人工智能研发中心vp,十多年自然语言处理和人工智能研发经验。主持研发过多款智能硬件的问答和对话系统,负责环信中文语义分析开放平台和环信智能机器人的设计与研发。
AI科技大本营
2019/03/12
2.5K0
如何从零开始用PyTorch实现Chatbot?(附完整代码)
TensorFlow实现Attention机制原理介绍论文阅读代码实现
原理介绍 图片1 图片2 图片3 更多资料: https://distill.pub/2016/augmented-rnns/#attentional-interfaces https://
致Great
2018/06/13
8.8K0
LSTM时间序列预测
你可能经常会遇到这样的问题,给你一个数据集,要你预测下一个时刻的值是多少?如下图所示,这种数据往往并没有规律可言,也不可能用一个简单的n阶模型去拟合。老实说,以前我遇到这种问题都是直接上灰色模型,但是用的多了就感觉会有点问题。其它还有一些模型比方说ARAM、ARIRM我没有试过。这篇文章主要讲解用LSTM如何进行时间序列预测
mathor
2020/02/28
3.6K0
LSTM时间序列预测
熬了一晚上,我从零实现了Transformer模型,把代码讲给你听
来源丨https://zhuanlan.zhihu.com/p/411311520
Python数据科学
2021/10/19
2.5K0
pytorch学习笔记(二十一): 使用 pack_padded_sequence
下面附上一张 pack_padded_sequence 原理图(其实只是将三维的输入去掉PAD的部分搞成了二维的。在RNN前向的时候,根据batch_sizes参数取对应的时间步计算。)
ke1th
2019/05/26
5.1K0
【入门】PyTorch文本分类
文本分类是NLP领域的较为容易的入门问题,本文记录文本分类任务的基本流程,大部分操作使用了torch和torchtext两个库。
zenRRan
2020/02/18
1.9K0
seq2seq模型之raw_rnn
本文是seq2seq模型的第二篇,主要是通过raw_rnn来实现seq2seq模型。 github地址是:https://github.com/zhuanxuhit/nd101 原文地址:https://github.com/ematvey/tensorflow-seq2seq-tutorials/blob/master/2-seq2seq-advanced.ipynb
zhuanxu
2018/08/23
1.2K0
seq2seq模型之raw_rnn
使用PyTorch建立你的第一个文本分类模型
我总是使用最先进的架构来在一些比赛提交模型结果。得益于PyTorch、Keras和TensorFlow等深度学习框架,实现最先进的体系结构变得非常容易。这些框架提供了一种简单的方法来实现复杂的模型体系结构和算法,而只需要很少的概念知识和代码技能。简而言之,它们是数据科学社区的一座金矿!
磐创AI
2020/03/04
2.2K0
NLP——用RNN解决POS Tagging问题
这一节总体上是一个对我们这一门课的一次proj的总结,这一次proj是一次深度学习(deep learning)模型的完整模型搭建,也是一个对于深度学习初学者来说极为具有挑战性的一次proj,因为会遇到各种各样意想不到的问题。因此这一篇文章也是一次完整的,从读取数据到跑出模型的全过程。
学弱猹
2021/10/27
1.7K0
基于深度学习的自然语言处理(Deep Learning-based Natural Language Processing)
自然语言处理(Natural Language Processing,NLP)是人工智能领域中一个重要的研究方向。随着深度学习技术的快速发展,基于深度学习的自然语言处理方法逐渐成为主流。本文将介绍深度学习算法在自然语言处理中的应用,并探讨其在不同任务中的优势和挑战。
大盘鸡拌面
2023/09/28
8620
动手学深度学习(十三) NLP机器翻译
机器翻译(MT):将一段文本从一种语言自动翻译为另一种语言,用神经网络解决这个问题通常称为神经机器翻译(NMT)。 主要特征:输出是单词序列而不是单个单词。 输出序列的长度可能与源序列的长度不同。
致Great
2020/02/25
9090
动手学深度学习(十三)  NLP机器翻译
深入解析情感分析技术:从篇章到属性
情感分析,也被称为情绪分析或意见挖掘,是自然语言处理(NLP)的一个分支,旨在识别和提取文本中的主观信息,如情感、情绪或意见。
TechLead
2023/10/21
8050
深入解析情感分析技术:从篇章到属性
LSTM
Chris Olah's LSTM post Edwin Chen's LSTM post Andrej Karpathy's lecture on RNNs and LSTMs from CS231n
小飞侠xp
2018/10/10
3.5K2
带有coverage机制的PGN模型架构
在生成摘要时,我们可能会遇到重复生成某些词或短语的问题。coverage机制就是为了解决这个问题而设计的,它通过记录已经关注过的源文本部分,来避免重复关注和生成。
@小森
2025/01/23
1150
带有coverage机制的PGN模型架构
无所不能的Embedding4 - Doc2vec第二弹[skip-thought & tf-Seq2Seq源码解析]
前一章Doc2Vec里提到,其实Doc2Vec只是通过加入Doc_id捕捉了文本的主题信息,并没有真正考虑语序以及上下文语义,n-gram只能在局部解决这一问题,那么还有别的解决方案么?依旧是通用文本向量,skip-thought尝试应用encoder-decoder来学习包含上下文信息和语序的句子向量。魔改后的实现可以看这里( ´▽`) github-DSXiangLi-Embedding-skip_thought
风雨中的小七
2020/11/24
7900
无所不能的Embedding4 - Doc2vec第二弹[skip-thought & tf-Seq2Seq源码解析]
挑战Transformer的新架构Mamba解析以及Pytorch复现
Mamba一直在人工智能界掀起波澜,被吹捧为Transformer的潜在竞争对手。到底是什么让Mamba在拥挤的序列建中脱颖而出?
deephub
2024/01/09
5.9K0
挑战Transformer的新架构Mamba解析以及Pytorch复现
【深度学习实验】循环神经网络(三):门控制——自定义循环神经网络LSTM(长短期记忆网络)模型
LSTM(长短期记忆网络)是一种循环神经网络(RNN)的变体,用于处理序列数据。它具有记忆单元和门控机制,可以有效地捕捉长期依赖关系。
Qomolangma
2024/07/30
1.3K0
【深度学习实验】循环神经网络(三):门控制——自定义循环神经网络LSTM(长短期记忆网络)模型
BERT的PyTorch实现
本文主要介绍一下如何使用 PyTorch 复现BERT。请先花上 10 分钟阅读我的这篇文章 BERT详解(附带ELMo、GPT介绍),再来看本文,方能达到醍醐灌顶,事半功倍的效果
mathor
2020/07/27
9130
推荐阅读
相关推荐
tf39:tensorflow之seq2seq
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验