【问题标题】:‘DataParallel’ object has no attribute ‘init_hidden’“DataParallel”对象没有属性“init_hidden”
【发布时间】:2018-10-30 16:56:48
【问题描述】:

我想做的是在我的自定义 RNN 类中使用 DataParallel。

似乎我以错误的方式初始化了 hidden_​​0...

class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, n_layers=1):
        super(RNN, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.n_layers = n_layers

        self.encoder = nn.Embedding(input_size, hidden_size)
        self.gru = nn.GRU(hidden_size, hidden_size, n_layers,batch_first = True)
        self.decoder = nn.Linear(hidden_size, output_size)
        self.init_hidden(batch_size)
    
    
    def forward(self, input):
        input = self.encoder(input)
        output, self.hidden = self.gru(input,self.hidden)
        output = self.decoder(output.contiguous().view(-1,self.hidden_size))
        output = output.contiguous().view(batch_size,num_steps,N_CHARACTERS)
        #print (output.size())10,50,67
    
        return output

    def init_hidden(self,batch_size):
        self.hidden = Variable(T.zeros(self.n_layers, batch_size, self.hidden_size).cuda())

而我是这样称呼网络的:

decoder = T.nn.DataParallel(RNN(N_CHARACTERS, HIDDEN_SIZE, N_CHARACTERS), dim=1).cuda()

然后开始训练:

for epoch in range(EPOCH_):
    hidden = decoder.init_hidden()

但我得到了错误,我不知道如何解决它......

“DataParallel”对象没有属性“init_hidden”

感谢您的帮助!

【问题讨论】:

    标签: deep-learning pytorch


    【解决方案1】:

    当使用DataParallel 时,您的原始模块将位于并行模块的module 属性中:

    for epoch in range(EPOCH_):
        hidden = decoder.module.init_hidden()
    

    【讨论】:

      【解决方案2】:

      我做的一个解决方法是:

      self.model = model 
      # Since if the model is wrapped by the `DataParallel` class, you won't be able to access its attributes
      # unless you write `model.module` which breaks the code compatibility. We use `model_attr_accessor` for attributes
      # accessing only.
      if isinstance(model, DataParallel):
          self.model_attr_accessor = model.module
      else:
          self.model_attr_accessor = model
      

      当我执行self.model(input)(即,当它被DataParallel 包裹时)时,这给了我将模型分布在我的 GPU 上的优势;当我需要访问它的属性时,我只需执行self.model_attr_accessor.<<WHATEVER>>。此外,这种设计为我提供了一种更模块化的方式来访问多个函数的属性,而无需在所有函数中都使用if-statements 来检查它是否被DataParallel 包裹。

      另一方面,如果您编写了model.module.<<WHATEVER>> 并且模型没有被DataParallel 包裹,则会引发错误,指出您的模型没有module 属性。


      但是,更紧凑的实现是创建一个自定义的DataParallel,如下所示:

      class _CustomDataParallel(nn.Module):
          def __init__(self, model):
              super(_CustomDataParallel, self).__init__()
              self.model = nn.DataParallel(model).cuda()
      
          def forward(self, *input):
              return self.model(*input)
      
          def __getattr__(self, name):
              try:
                  return super().__getattr__(name)
              except AttributeError:
                  return getattr(self.model.module, name)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 2012-12-01
        • 2021-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多