代码之家  ›  专栏  ›  技术社区  ›  ndrwnaguib Nikkolai Fernandez

在具有不同隐藏尺寸的Pytorch LSTM模型上附加一个循环层

  •  0
  • ndrwnaguib Nikkolai Fernandez  · 技术社区  · 6 年前

    我正在开发一个使用pytorch进行序列分析的bi-lstm模型。我正在使用的 torch.nn.LSTM . 使用该模块,只需传递一个参数,就可以有多个层 num_layers 为层数(例如, num_layers=2 )但是他们都会有相同的 hidden_size 哪个是 部分地 对我来说很好,我只想所有的都一样 隐藏\大小 但是 最后一层大小不同。基本示例如下:

    rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
    inp = torch.randn(5, 3, 10)
    h0 = torch.randn(2, 3, 20)
    c0 = torch.randn(2, 3, 20)
    output, (hn, cn) = rnn(inp, (h0, c0))
    

    输出尺寸为( 5, 3, 20 )

    一种解决方案 (但对我不利) 正在实现输出所需维度并从第一个模型获取输入的额外模型,例如:

    rnn_two = nn.LSTM(input_size=20, hidden_size=2)
    output2, _ = rnn_two(output)
    

    但是,我不想这样做,因为我 并行化 模型使用 DataParallel 所以我需要所有的东西都是一个包裹。我希望能找到类似喀拉斯的东西,例如:

    rnn.add(LSTM, hidden_size=2)
    

    我查过了 LSTM source code 但找不到我需要的。

    有什么建议吗?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Mikhail Berlinkov    6 年前

    如果我没弄错的话,可以这样做:

    import torch.nn as nn
    import torch.nn.functional as F
    
    class RnnWith2HiddenSizesModel(nn.Module):
        def __init__(self):
            super(RnnWith2HiddenSizesModel, self).__init__()
            self.rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
            self.rnn_two = nn.LSTM(input_size=20, hidden_size=2)
    
        def forward(self, inp, hc):
            output, _ = self.rnn(inp, hc)
            output2, _ = self.rnn_two(output)
            return output2
    
    
    inp = torch.randn(5, 3, 10)
    h0 = torch.randn(2, 3, 20)
    c0 = torch.randn(2, 3, 20)
    
    rnn = RnnWith2HiddenSizesModel()
    
    output = RnnWith2HiddenSizesModel()(inp, (h0, c0))
    
    
    tensor([[[-0.0305,  0.0327],
         [-0.1534, -0.1193],
         [-0.1393,  0.0474]],
    
        [[-0.0370,  0.0519],
         [-0.2081, -0.0693],
         [-0.1809,  0.0826]],
    
        [[-0.0561,  0.0731],
         [-0.2307, -0.0229],
         [-0.1780,  0.0901]],
    
        [[-0.0612,  0.0891],
         [-0.2378,  0.0164],
         [-0.1760,  0.0929]],
    
        [[-0.0660,  0.1023],
         [-0.2176,  0.0508],
         [-0.1611,  0.1053]]], grad_fn=<CatBackward>)
    
        2
  •  0
  •   ndrwnaguib Nikkolai Fernandez    6 年前

    虽然@mikhail berlinkov的答案是根据需要有效的,但它并不是一般情况(问题中甚至没有要求),对此我想提出第二个解决方案:

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    from functools import reduce
    
    class RNNModel(nn.Module):
        def __init__(self, *models):
            super(RNNModel, self).__init__()
            self.models = models
    
        def forward(self, inp):
            return reduce(lambda arg, model: model(arg, None)[0], self.models, inp)
    

    可称为:

    rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
    rnn_two = nn.LSTM(input_size=20, hidden_size=2)
    inp = torch.randn(5, 3, 10)
    
    rnn_model = RNNModel(rnn, rnn_two)
    
    output = rnn_model(inp)
    

    output.shape 等于预期值(即, 5,3,2 )