Debugging 调试RNN

Debugging 调试RNN,debugging,machine-learning,neural-network,deep-learning,recurrent-neural-network,Debugging,Machine Learning,Neural Network,Deep Learning,Recurrent Neural Network,我目前正在从头开始编写自己的RNN,几乎只使用numpy。我基本上被卡住了,因为我检查了每个层的所有梯度,我在这里有所有的单元测试: 然而,当我使用相对合理的权重初始化和经过单元测试的梯度优化器()在我的网络上进行反向传播时,我可以看到该图肯定不是我想要的。我通过了一个相对简单的语料库,这基本上就是本文:不到1000个单词,应该很容易过度拟合。但是,成本函数看起来是这样的: 这绝对不是什么趋同的东西。它跳上跳下,就像它没有真正学到任何东西一样。在调试方面我应该做些什么 我不能为这个示例提供MV

我目前正在从头开始编写自己的RNN,几乎只使用numpy。我基本上被卡住了,因为我检查了每个层的所有梯度,我在这里有所有的单元测试:

然而,当我使用相对合理的权重初始化和经过单元测试的梯度优化器()在我的网络上进行反向传播时,我可以看到该图肯定不是我想要的。我通过了一个相对简单的语料库,这基本上就是本文:不到1000个单词,应该很容易过度拟合。但是,成本函数看起来是这样的: 这绝对不是什么趋同的东西。它跳上跳下,就像它没有真正学到任何东西一样。在调试方面我应该做些什么

我不能为这个示例提供MVCE,因为这是一个功能测试错误,它集成了我创建的库的所有部分。因此,MVCE就是整个项目。尽管如此,还是可以从github克隆它

可疑地点 我觉得这个错误是因为我的神经网络结构可能我处理连续迭代的方式不正确。以下是放大的代码:

        # Save typing 
        c = lambda arg: self.constants[arg]
        p = lambda arg: self.params[arg]

        # Step 1: Word embedding forward:
        words_chosen = word_embedding_forward(p("words"), x)

        # Step 2: rnn forward:
        h = rnn_forward(words_chosen, p("W_xh"), p("W_hh"), p("b_rnn"), h0)

        # Step 3: affine forward:
        affine = rnn_affine_forward(h, p("W_hy"), p("b_affine"))

        # step 4: softmax forward and backward:
        loss, dout = rnn_softmax(affine, y) 

        # step 3: affine backward:
        dh, dW_hy, db_affine = rnn_affine_backward(h, p("W_hy"), p("b_affine"), dout)

        # step 2: rnn backward:
        dW_hh, dW_xh, dx, db_rnn, dh0 = rnn_backward(words_chosen, p("W_xh"), p("W_hh"), p("b_rnn"), h0, h, dh)

        # step 1: Word embedding backward:
        dwords = word_embedding_backward(dx, p("words"), x)

        # Returns the loss and all the derivatives along with the fields.
        return (loss, [[p("words"), dwords], 
               [p("W_xh"), dW_xh], 
               [p("W_hh"), dW_hh],
               [p("W_hy"), dW_hy],
               [p("b_affine"), db_affine],
               [p("b_rnn"), db_rnn],
               [h0, dh0]], h[:,-1,:])
另一个怀疑是我没有正确处理隐藏状态。我从上一个示例中获取一个隐藏状态,并将该隐藏层状态直接连接到下一个示例中

下面是一个例子:
[a,b,c,d,e,f,g]是顺序

输入(a,b,c)->(b,c,d)输出(使用零作为初始隐藏层)


我们跳到d:input(d,e,f)->(e,f,g)output(使用以前的隐藏状态c)

您是否检查了随时间变化的梯度规范?使用Vanilla RNN,你很容易进入爆炸/消失梯度。嗨-不,我没有,但问题是,即使时间序列大小为2,爆炸/消失梯度也不明显,这种情况也会发生。(事实上,这里的图表是时间步长2)你检查过你的梯度标准吗?使用Vanilla RNN,你很容易进入爆炸/消失梯度。嗨-不,我没有,但问题是,即使时间序列大小为2,爆炸/消失梯度也不明显,这种情况也会发生。(事实上,这里的图表是时间步长2)