如何在pytorch中用RNNCell编写RNN?

Posted

技术标签:

【中文标题】如何在pytorch中用RNNCell编写RNN?【英文标题】:How to write a RNN with RNNCell in pytorch? 【发布时间】:2020-10-19 20:19:41 【问题描述】:

我正在尝试将代码从 this simple Vanilla RNN 重写为 pytorch 中的 RNNCell 格式。这是完整的代码

import torch
import torch.nn as nn
from torch.autograd import Variable

torch.manual_seed(777)


class SimpleRNN(nn.Module):
    def __init__(self,inputs,hiddens,n_class):
        super().__init__()
        self.rnn = nn.RNNCell(inputs,hiddens)
        self.linear = nn.Linear(hiddens,n_class)
        self.hiddens = hiddens
    def forward(self,x):
        hx = torch.zeros((x.shape[1],hiddens))
        rnn_out = []
        for i in x:
            hx = self.rnn(i,hx)
            rnn_out.append(hx)
        linear_out =  self.linear(rnn_out.view(-1, hiddens))
        return linear_out


# hyperparameters
seq_len = 6      # |hihell| == 6, equivalent to time step
input_size = 5   # one-hot size
batch_size = 1   # one sentence per batch
num_layers = 1   # one-layer rnn
num_classes = 5  # predicting 5 distinct character
hidden_size = 4  # output from the RNN


# create an index to character mapping
idx2char = ['h', 'i', 'e', 'l', 'o']

# Teach hihell -> ihello
x_data = [[0, 1, 0, 2, 3, 3]]    # hihell
x_one_hot = [[[1, 0, 0, 0, 0],   # h 0
              [0, 1, 0, 0, 0],   # i 1
              [1, 0, 0, 0, 0],   # h 0
              [0, 0, 1, 0, 0],   # e 2
              [0, 0, 0, 1, 0],   # l 3
              [0, 0, 0, 1, 0]]]  # l 3

x_one_hot = torch.Tensor(x_one_hot)
y_data = torch.Tensor([1, 0, 2, 3, 3, 4])  # ihello

rnn = SimpleRNN(input_size,hidden_size,num_classes)

# train the model
num_epochs = 15
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(rnn.parameters(), lr = 0.1)
for epoch in range(1, num_epochs + 1):
    optimizer.zero_grad()
    outputs = rnn(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    # check the current predicted string
    # max gives the maximum value and its
    # corresponding index, we will only
    # be needing the index
    _, idx = outputs.max(dim = 1)
    idx = idx.data.numpy()
    result_str = [idx2char[c] for c in idx]
    print('epoch: , loss: :1.3f'.format(epoch, loss.item()))
    print('Predicted string: ', ''.join(result_str))

我正在尝试模仿教程中的原始 RNN + 全连接 类对象,并重用它的许多代码。我计算了rnn_out 并将其值附加到 python 列表中

        rnn_out = []
        for i in x:
            hx = rnn(i,hx)
            rnn_out.append(hx)

因为它是一个 python 列表,我无法进一步执行代码,它会导致这个错误

AttributeError: 'list' 对象没有属性 'view'

我应该如何使用 RNNCell 编写 RNN?

【问题讨论】:

【参考方案1】:

我不确定您的其余代码是否正常,但为了修复此错误,您可以通过在 for 循环结束后添加以下行将您的 rnn_out 列表转换为火炬张量:

rnn_out = torch.stack(rnn_out)

【讨论】:

以上是关于如何在pytorch中用RNNCell编写RNN?的主要内容,如果未能解决你的问题,请参考以下文章

『PyTorch』第十弹_循环神经网络

《PyTorch深度学习实践10》——循环神经网络-基础篇(Basic-Recurrent Neural Network)

TensorFlow:从 RNN 获取所有状态

ValueError: Attempt to reuse RNNCell <tensorflow.contrib.rnn.python.ops.core_rnn_cell_impl.BasicL

深度学习理论 循环神经网络 RNN

Tensorflow运用RNN注意事项