循环神经网络的从零开始实现 讨论区


#1

http://zh.diveintodeeplearning.org/chapter_recurrent-neural-networks/rnn-scratch.html


于置顶 #2

#3

这里写错了吧,b应该在函数(…)里。另外教程文档是不是开源的,可否直接contribute?


#4

training的时候,寻行下面的代码

train_loss, num_examples = 0, 0
state = nd.zeros(shape=(batch_size, num_hidden), ctx=ctx)
for data, label in data_iter(batch_size, seq_len, ctx):
    with autograd.record():
        outputs, state = rnn(get_inputs(data), state)
        # reshape label to (batch_size*seq_len, )
        # concate outputs to (batch_size*seq_len, vocab_size)
        label = label.T.reshape((-1,))
        outputs = nd.concat(*outputs, dim=0)
        loss = softmax_cross_entropy(outputs, label)
    loss.backward()

会报错

MXNetError: [20:24:48] src/ndarray/autograd.cc:252: Check failed: !i.entry_.is_none() Cannot differentiate node because it is not in a computational graph. You need to set is_recording to true or use autograd.record() to save computational graphs for backward. If you want to differentiate the same graph twice, you need to pass retain_graph=True to backward.

但是明明已经用了autograd.record()

请问是怎么回事?


#5

重启jupyter notebook kernel以后就可以了。估计是notebook执行的时候,因为某些原因,autograd不能正常工作了。


#6

看着确实不对…欢迎发pull request更正,源码在这里 https://github.com/mli/gluon-tutorials-zh/


#7

我看到英文版的教程中没有讲seq2seq,希望加入!


#8

笔误 Perplexit(PPL) -> Perplexity(PPL), 少个y


#9

麻烦给一个数据下载的链接?


#10

这课的数据集应该已经包含在压缩包里了,另外也可以从这里下载


#11

关于data_iter有一处疑问:

def data_iter(batch_size, seq_len, ctx=None):
    num_examples = (len(time_numerical)-1) // seq_len
    num_batches = num_examples // batch_size
    # 随机化样本
    idx = list(range(num_examples))
    random.shuffle(idx)
    # 返回seq_len个数据
    def _data(pos):
        return time_numerical[pos:pos+seq_len]
    for i in range(num_batches):
        # 每次读取batch_size个随机样本
        examples = idx[i:i+batch_size]
        data = nd.array(
            [_data(j*seq_len) for j in examples], ctx=ctx)
        label = nd.array(
            [_data(j*seq_len+1) for j in examples], ctx=ctx)
        yield data, label

其中examples = idx[i:i+batch_size]中的i是每次加1的
这样一来,相邻两个batch之间有batch_size - 1个数据是重叠的。这是笔误还是有意为之呢?
个人感觉应该每次都令i = i * batch_size然后再取examples = idx[i:i+batch_size]


#12

是写错了。之前似乎看到了这个,以为fix了。


#13

在训练模型的部分有一个疑问,下一个批量的数据和前一个批量数据已经不在一个时序里面了,但是为什么还继续使用了前一个批量数据留下来的state了呢?个人感觉应该在每次内层迭代的时候就重置一次state,但是这里为什么每次外层迭代时才重置state?


#14

你好,

为什么是
num_examples = (len(time_numerical)-1) // seq_len
而不是
num_examples = len(time_numerical) // seq_len
呢?

另外,样本可以重叠吗?即从头开始取,每次取长度为seq_len的字符串为一个样本,偏移1个字符,再取下一个样本,直到文末,样本数变为num_examples = len(time_numerical)-seq_len+1。


#15

你写出seq2seq的代码了吗?我参照Keras的seq2seq示例代码写了一天都写不出来。唉


#16

遇到什么问题了?


#17

你好,seq2seq的Kears代码中的这一段:

# Define an input sequence and process it.
encoder_inputs = Input(shape=(None, num_encoder_tokens))  # 编码器输入 (None × 输入文本one-hot编码维度)
encoder = LSTM(latent_dim, return_state=True)  # LSTM单元个数为隐变量维数
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]  # 只保留编码器状态


# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(None, num_decoder_tokens))  # 编码器输入 (None × 目标文本one-hot编码维度)
# We set up our decoder to return full output sequences,
# and to return internal states as well. We don't use the
# return states in the training model, but we will use them in inference.
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)  # LSTM单元个数为隐变量维数
decoder_outputs, _, _ = decoder_lstm(decoder_inputs,
                                     initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)

# Define the model that will turn
# `encoder_input_data` & `decoder_input_data` into `decoder_target_data`
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

用Gluon写,是不是应该写成:

class Net(Block):
    def __init__(self,**kwargs):
        super(Net,self).__init__(**kwargs)
        self.encoder = LSTM(dim_latent,layout='NTC')
        self.decoder1 = LSTM(dim_latent,layout='NTC')
        self.decoder2 = Dense(len(target_chars), activation='softmax')

    def forward(self, x,y,stat0):
        _, stat = self.encoder(x, stat0)
        output, _ = self.decoder1(y, stat)
        return self.decoder2(output)

但是这样运行不了,不知道什么问题。还请指教!


#18

有个小问题是我们的Dense里没有softmax这个activation,你可以在forward里用F.softmax(self.decoder2(output)),或者用HybridLambda('softmax')这个block来代替


#19

RNN中输入的序列长度对RNN会产生什么影响吗


#20

你指的是预测的输入序列长度,还是训练时全部文本序列长度,还是训练时每次sample的序列长度?