python - 属性错误: 'tuple' object has no attribute 'size'

标签 python deep-learning pytorch recurrent-neural-network gated-recurrent-unit

更新:回顾这个问题后,大部分代码都是不必要的。综上所述,Pytorch RNN 的隐藏层需要是 torch 张量。当我发布问题时,隐藏层是一个元组。

下面是我的数据加载器。

from torch.utils.data import TensorDataset, DataLoader

def batch_data(log_returns, sequence_length, batch_size):
    """
    Batch the neural network data using DataLoader
    :param log_returns: asset's daily log returns
    :param sequence_length: The sequence length of each batch
    :param batch_size: The size of each batch; the number of sequences in a batch
    :return: DataLoader with batched data
    """
    
    # total number of batches we can make
    n_batches = len(log_returns)//batch_size
    
    # Keep only enough characters to make full batches
    log_returns = log_returns[:n_batches * batch_size]
    
    y_len = len(log_returns) - sequence_length
    
    x, y = [], []
    for idx in range(0, y_len):
        idx_end = sequence_length + idx
        x_batch = log_returns[idx:idx_end]
        x.append(x_batch)
        # only making predictions after the last word in the batch
        batch_y = log_returns[idx_end]    
        y.append(batch_y)    
    
    # create tensor datasets
    x_tensor = torch.from_numpy(np.asarray(x))
    y_tensor = torch.from_numpy(np.asarray(y))
    
    # make x_tensor 3-d instead of 2-d
    x_tensor = x_tensor.unsqueeze(-1)
    
    data = TensorDataset(x_tensor, y_tensor)
    
    data_loader = DataLoader(data, shuffle=False, batch_size=batch_size)
    
    # return a dataloader
    return data_loader
    def init_hidden(self, batch_size):
        ''' Initializes hidden state '''
        # Create two new tensors with sizes n_layers x batch_size x n_hidden,
        # initialized to zero, for hidden state and cell state of LSTM
        weight = next(self.parameters()).data
        
        if (train_on_gpu):
            hidden = (weight.new(self.n_layers, batch_size, self.n_hidden).zero_().cuda(),
                      weight.new(self.n_layers, batch_size, self.n_hidden).zero_().cuda())
        else:
            hidden = (weight.new(self.n_layers, batch_size, self.n_hidden).zero_(),
                      weight.new(self.n_layers, batch_size, self.n_hidden).zero_())
        
        return hidden

我不知道出了什么问题。当我尝试开始训练模型时,我收到错误消息:

AttributeError: 'tuple' object has no attribute 'size'

最佳答案

问题来自于 hidden (在 forward 定义中)不是 Torch.Tensor 。因此,r_output, hidden = self.gru(nn_input, hidden)引发一个相当令人困惑的错误,而没有明确说明参数中的错误。尽管您可以看到它是在 nn.RNN 内引发的名为 check_hidden_size() 的函数...

一开始我很困惑,以为 nn.RNN 的第二个参数:h0是一个包含 (hidden_state, cell_state) 的元组。该调用返回的第二个元素也是如此: hn 。事实并非如此h0hn都是Torch.Tensor s。有趣的是,您可以解压堆叠张量:

>>> z = torch.stack([torch.Tensor([1,2,3]), torch.Tensor([4,5,6])])
>>> a, b = z
>>> a, b
(tensor([1., 2., 3.]), tensor([4., 5., 6.]))

您应该提供一个张量作为 nn.GRU 的第二个参数__call__ .


编辑 - 进一步检查您的代码后,我发现您正在转换 hidden再次回到元组...在单元格 [14] 中,您有 hidden = tuple([each.data for each in hidden]) 。这基本上覆盖了您在 init_hidden 中所做的修改与 torch.stack .

退一步看看 source code RNNBase 是 RNN 模块的基类。如果未将隐藏状态赋予转发,则默认为:

if hx is None:
    num_directions = 2 if self.bidirectional else 1
    hx = torch.zeros(self.num_layers * num_directions,
                     max_batch_size, self.hidden_size,
                     dtype=input.dtype, device=input.device)

这本质上与您正在尝试实现的 init 完全相同。当然,您只想重置每个时期的隐藏状态(我不明白为什么......)。无论如何,一个基本的替代方案是设置 hiddenNone在纪元开始时,按原样传递到 self.forward_back_prop然后到rnn ,然后到self.rnn这将依次为您默认初始化它。然后覆盖hidden以及 RNN 前向调用返回的隐藏状态。

总而言之,我只保留了代码的相关部分。删除init_hidden来自 AssetGRU 的函数并进行这些修改:

def forward_back_prop(rnn, optimizer, criterion, inp, target, hidden):
    ...
    if hidden is not None:
        hidden = hidden.detach()
    ...
    output, hidden = rnn(inp, hidden)  
    ...
    return loss.item(), hidden


def train_rnn(rnn, batch_size, optimizer, criterion, n_epochs, show_every_n_batches):
    ...
    for epoch_i in range(1, n_epochs + 1):
        
        hidden = None
        
        for batch_i, (inputs, labels) in enumerate(train_loader, 1):
            loss, hidden = forward_back_prop(rnn, optimizer, criterion, 
                                             inputs, labels, hidden)
            ...

    ...

关于python - 属性错误: 'tuple' object has no attribute 'size' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65543423/

相关文章:

python - pandas groupby 计数、总和和平均值

python - 理解这个 python 函数的复杂性

python - 为什么 conv2d 在不同的批量大小下会产生不同的结果

python - Pytorch XOR 实现舍入问题?

python - 使用 Boto3 批量删除 Cloudwatch 日志组 - delete_log_group

python正则表达式问题

python - 如何修复 : horovod. run.common.util.network.NoValidAddressesFound

tensorflow - 如何在张量板中绘制图像网格?

machine-learning - 如何将多个文本特征用于 NLP 分类器?

python - 如何从 gpu 内存地址创建 PyCUDA GPUArray?