首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PyTorch中是否存在干净和可扩展的LSTM实现?

在PyTorch中是否存在干净和可扩展的LSTM实现?
EN

Stack Overflow用户
提问于 2018-05-04 06:08:01
回答 2查看 7.1K关注 0票数 11

我想自己创建一个LSTM类,但是我不想从头开始重写经典的LSTM函数。

深入研究PyTorch的代码,我只发现至少涉及3-4个具有继承的类的脏实现:

  1. https://github.com/pytorch/pytorch/blob/98c24fae6b6400a7d1e13610b20aa05f86f77070/torch/nn/modules/rnn.py#L323
  2. https://github.com/pytorch/pytorch/blob/98c24fae6b6400a7d1e13610b20aa05f86f77070/torch/nn/modules/rnn.py#L12
  3. 函数/rnn.py#L 297

一个干净的PyTorch实现是否存在于某个地方?任何联系都会有帮助。

例如,我知道LSTM的干净实现存在于TensorFlow中,但我需要派生出PyTorch one。

作为一个明确的例子,我正在搜索的是一个像一样干净的实现,但是在PyTorch

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-04 13:24:43

我发现最好的实现就是在这里

变种/lstm.py

它甚至实现了四种不同的反复式辍学,这是非常有用的!

如果你把辍学的部分拿走,你就会得到

代码语言:javascript
复制
import math
import torch as th
import torch.nn as nn

class LSTM(nn.Module):

    def __init__(self, input_size, hidden_size, bias=True):
        super(LSTM, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.bias = bias
        self.i2h = nn.Linear(input_size, 4 * hidden_size, bias=bias)
        self.h2h = nn.Linear(hidden_size, 4 * hidden_size, bias=bias)
        self.reset_parameters()

    def reset_parameters(self):
        std = 1.0 / math.sqrt(self.hidden_size)
        for w in self.parameters():
            w.data.uniform_(-std, std)

    def forward(self, x, hidden):
        h, c = hidden
        h = h.view(h.size(1), -1)
        c = c.view(c.size(1), -1)
        x = x.view(x.size(1), -1)

        # Linear mappings
        preact = self.i2h(x) + self.h2h(h)

        # activations
        gates = preact[:, :3 * self.hidden_size].sigmoid()
        g_t = preact[:, 3 * self.hidden_size:].tanh()
        i_t = gates[:, :self.hidden_size]
        f_t = gates[:, self.hidden_size:2 * self.hidden_size]
        o_t = gates[:, -self.hidden_size:]

        c_t = th.mul(c, f_t) + th.mul(i_t, g_t)

        h_t = th.mul(o_t, c_t.tanh())

        h_t = h_t.view(1, h_t.size(0), -1)
        c_t = c_t.view(1, c_t.size(0), -1)
        return h_t, (h_t, c_t)

PS:存储库包含更多的LSTM和其他RNN变体:

https://github.com/pytorch/benchmark/tree/master/rnns/benchmarks

看看它,也许你想到的分机已经在那里了!

编辑:

正如注释中提到的,您可以将上面的LSTM单元格包装为处理顺序输出:

代码语言:javascript
复制
import math
import torch as th
import torch.nn as nn


class LSTMCell(nn.Module):

    def __init__(self, input_size, hidden_size, bias=True):
        # As before

    def reset_parameters(self):
        # As before

    def forward(self, x, hidden):

        if hidden is None:
            hidden = self._init_hidden(x)

        # Rest as before

    @staticmethod
    def _init_hidden(input_):
        h = th.zeros_like(input_.view(1, input_.size(1), -1))
        c = th.zeros_like(input_.view(1, input_.size(1), -1))
        return h, c


class LSTM(nn.Module):

    def __init__(self, input_size, hidden_size, bias=True):
        super().__init__()
        self.lstm_cell = LSTMCell(input_size, hidden_size, bias)

    def forward(self, input_, hidden=None):
        # input_ is of dimensionalty (1, time, input_size, ...)

        outputs = []
        for x in torch.unbind(input_, dim=1):
            hidden = self.lstm_cell(x, hidden)
            outputs.append(hidden[0].clone())

        return torch.stack(outputs, dim=1)

我没有测试代码,因为我使用的是convLSTM实现。如果有什么不对劲,请告诉我。

更新:固定链接。

票数 16
EN

Stack Overflow用户

发布于 2019-11-01 10:54:54

我做了一个简单而通用的框架来定制LSTMs:https://github.com/daehwannam/pytorch-rnn-util

您可以通过设计LSTM单元并将它们提供给LSTMFrame来实现自定义LSTM。自定义LSTM的一个例子是包中的LayerNormLSTM

代码语言:javascript
复制
# snippet from rnn_util/seq.py
class LayerNormLSTM(LSTMFrame):
    def __init__(self, input_size, hidden_size, num_layers=1, dropout=0, r_dropout=0, bidirectional=False, layer_norm_enabled=True):
        r_dropout_layer = nn.Dropout(r_dropout)
        rnn_cells = tuple(
            tuple(
                LayerNormLSTMCell(
                    input_size if layer_idx == 0 else hidden_size * (2 if bidirectional else 1),
                    hidden_size,
                    dropout=r_dropout_layer,
                    layer_norm_enabled=layer_norm_enabled)
                for _ in range(2 if bidirectional else 1))
            for layer_idx in range(num_layers))

        super().__init__(rnn_cells, dropout, bidirectional)

LayerNormLSTM有PyTorch标准LSTM的关键选项和附加选项,r_dropoutlayer_norm_enabled

代码语言:javascript
复制
# example.py
import torch
import rnn_util


bidirectional = True
num_directions = 2 if bidirectional else 1

rnn = rnn_util.LayerNormLSTM(10, 20, 2, dropout=0.3, r_dropout=0.25,
                             bidirectional=bidirectional, layer_norm_enabled=True)
# rnn = torch.nn.LSTM(10, 20, 2, bidirectional=bidirectional)

input = torch.randn(5, 3, 10)
h0 = torch.randn(2 * num_directions, 3, 20)
c0 = torch.randn(2 * num_directions, 3, 20)
output, (hn, cn) = rnn(input, (h0, c0))

print(output.size())
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50168224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档