如何对不同大小的层进行反向传播?

我正在开发我的第一个神经网络,使用的是著名的MNIST手写数字数据库。我希望这个神经网络能够根据给定的图像识别从0到9的数字。

我的神经网络由三层组成:输入层(784个神经元,每个神经元对应数字的一个像素)、隐藏层(30个神经元,当然也可以是100个或50个,但我目前不太关注超参数调整)和输出层(10个神经元,每个神经元代表每个数字的激活状态)。这给我带来了两个权重矩阵:一个是30×784,另一个是10×30。

我了解并理解反向传播、优化及其背后的数学公式的理论,这本身不是问题。我可以优化第二权重矩阵的权重,成本确实随着时间的推移而减少。但由于矩阵结构,我无法继续向后传播。

我知道需要找到成本相对于权重的导数:

d(cost) / d(w) = d(cost) / d(f(z)) * d(f(z)) / d(z) * d(z) / d(w)

(其中f是激活函数,z是神经元的点积加上偏置)

所以我在最右边的层,有一个包含10个元素的输出数组。d(cost) / d(f(z))是观察值与预测值的差。我可以将它乘以d(f(z)) / d(z),也就是最右层f'(z),这也是一个包含10个元素的单维向量,现在已经计算出d(cost) / d(z)。然后,d(z)/d(w)只是该层的输入,即前一层的输出,是一个30个元素的向量。我发现可以转置d(cost) / d(z),这样T( d(cost) / d(z) ) * d(z) / d(w)给我一个(10, 30)的矩阵,这有意义,因为它与最右侧权重矩阵的维度匹配。

但之后我就卡住了。d(cost) / d(f(z))的维度是(1, 10),d(f(z)) / d(z)的维度是(1, 30),d(z) / d(w)的维度是(1, 784)。我不知道如何得出结果。

这是我目前编写的代码。不完整的部分是_propagate_back方法。我暂时不考虑偏置,因为我只是被权重卡住,首先我想解决这个问题。

(代码部分保持不变)

这是mnist_loader的代码,以防有人想要复制这个例子:

(代码部分保持不变)

回答:

一旦你有了d(cost) / d(z),我认为你实际上应该将它乘以权重矩阵:只有这样你才能将错误d(cost) / d(z)向后传播到新层(并得到有意义的矩阵形状)。

这是我如何更改你的反向传播函数:

(代码部分保持不变)

两点说明:

  • hidden_err = np.dot(d_cost_d_z, output_layer.weights)是我将d(cost) / d(z)乘以权重矩阵的地方
  • 我用np.dot函数(Numpy中的矩阵乘法)替换了一些*运算符(如果我没记错的话,这是Numpy中的Hadamard乘积)的使用

我不是专家,所以我希望我没有犯什么可怕的错误…无论如何,我的回答主要是基于Michael Nielsen的《Neural Networks and Deep Learning》这本书的这一章节

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注