我目前正在从头开始编写自己的RNN,几乎只使用numpy。我基本上卡住了,因为我检查了每个单独层的所有渐变,我在这里进行了所有单元测试:https://github.com/OneRaynyDay/BibleNet/blob/master/Unit%20tests.ipynb https://github.com/OneRaynyDay/BibleNet/blob/master/Gradient%20Solver%20Unit%20Test.ipynb
但是,当我使用相对合理的权重初始化和单元测试梯度优化器()进行反向传播时,我可以看到图形绝对不是我想要的。我传入了一个相对简单的语料库,基本上这篇文章来自这里:http://www.dailycal.org/2016/10/18/students-gather-hear-faculty-speak-trump-teach/不到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] is the sequence
input (a,b,c) -> (b,c,d) output (uses zeros as initial hidden layer)
We skip over to d: input (d,e,f) -> (e,f,g) output (uses previous hidden state of c)