hanbt / learn_dl

Deep learning algorithms source code for beginners
Apache License 2.0
1.19k stars 988 forks source link

fc.py中backward函数权重梯度及偏置梯度计算是否存在笔误? #23

Open Super-Louis opened 6 years ago

Super-Louis commented 6 years ago
self.delta = self.activator.backward(self.input) * np.dot(self.W.T, delta_array)
self.W_grad = np.dot(delta_array, self.input.T) 
self.b_grad = delta_array

np.dot(self.W.T, delta_array)中的权重应为下层的权重,不是当前层的权重; delta_array为从下一层传递过来的误差项,权重梯度及偏置梯度应根据当前层的误差项进行计算。

self.W_grad = np.dot(self.delta, self.input.T) 
self.b_grad = self.delta
FlyingCat-fa commented 6 years ago

你没搞懂全连接层的结构,此三层结构中只有两个全连接层。比如第一个全连接层l,连接输入层和隐藏层,则其输入是节点1~3的输出ai,i为1~3,输出是节点4~7的输出ai,i为4~7,权重为输入到隐藏层的连接权重,其误差项应为输入节点的误差项,该层下一层l+1的误差项应为该层(l层)输入乘以权重后的这个值的误差,也就是激活器的输入的误差

ghoulich commented 5 years ago

反向传播是用下一层的误差项来推算本层的误差,从右至左逐层推算,所以 self.W_grad = np.dot(delta_array, self.input.T) self.b_grad = delta_array 这两行代码没有问题,但是上一行代码 self.delta = self.activator.backward(self.input) np.dot(self.W.T, delta_array) 我觉得是有问题的,本层的误差应该用本层的输出和下一层的误差来计算,但是这行代码却用本层的输入来计算,这个和公式-8是冲突的,我觉得正确的应该是 self.delta = self.activator.backward(self.output) np.dot(self.W.T, delta_array) 还是得修改一下源码试试看!

samchild commented 5 years ago

反向传播是用下一层的误差项来推算本层的误差,从右至左逐层推算,所以 self.W_grad = np.dot(delta_array, self.input.T) self.b_grad = delta_array 这两行代码没有问题,但是上一行代码 self.delta = self.activator.backward(self.input) np.dot(self.W.T, delta_array) 我觉得是有问题的,本层的误差应该用本层的输出和下一层的误差来计算,但是这行代码却用本层的输入来计算,这个和公式-8是冲突的,我觉得正确的应该是 self.delta = self.activator.backward(self.output) np.dot(self.W.T, delta_array) 还是得修改一下源码试试看!

你的 self.delta = self.activator.backward(self.output) np.dot(self.W.T, delta_array)这一句,还是没有使用下一层的权重呀?正确的是会不会是 self.delta = self.activator.backward(self.output) np.dot(self.NextLayer.W.T, delta_array)(self.NextLayer.W这个只是示意下一层的权重) @hanbt @ghoulich

janlely commented 4 years ago

反向传播是用下一层的误差项来推算本层的误差,从右至左逐层推算,所以 self.W_grad = np.dot(delta_array, self.input.T) self.b_grad = delta_array 这两行代码没有问题,但是上一行代码 self.delta = self.activator.backward(self.input) np.dot(self.W.T, delta_array) 我觉得是有问题的,本层的误差应该用本层的输出和下一层的误差来计算,但是这行代码却用本层的输入来计算,这个和公式-8是冲突的,我觉得正确的应该是 self.delta = self.activator.backward(self.output) np.dot(self.W.T, delta_array) 还是得修改一下源码试试看!

式4中a_j是节点j的输出值,是第一层的其中一个输出,实际就是第二层的其中一个输入,所以这块代码应该没问题,但这个网络用来训练mnist数据集好像不行,跑了两轮就直接退出了,错误率太高,不收敛。打印每次的梯度,发现值都很小(< 0.2)

dyustc commented 4 years ago

反向传播是用下一层的误差项来推算本层的误差,从右至左逐层推算,所以 self.W_grad = np.dot(delta_array, self.input.T) self.b_grad = delta_array 这两行代码没有问题,但是上一行代码 self.delta = self.activator.backward(self.input) np.dot(self.W.T, delta_array) 我觉得是有问题的,本层的误差应该用本层的输出和下一层的误差来计算,但是这行代码却用本层的输入来计算,这个和公式-8是冲突的,我觉得正确的应该是 self.delta = self.activator.backward(self.output) np.dot(self.W.T, delta_array) 还是得修改一下源码试试看!

赞同,应该改成self.output, 不过我改完之后,跑的mnist数据集会报错误, 出不了结果, 你改完结果是对的吗

ume-technology commented 3 years ago

最近我回头看反向传播的过程. 在全连接神经网络的反向传播的实现代码部分 (class NetWork): def calc_gradient(self, label): delta = self.layers[-1].activator.backward(self.layers[-1].output) * (label - self.layers[-1].output) for layer in self.layers[::-1]: layer.backward(delta) delta = layer.delta return delta. 结合文章, 我没有看明白求解梯度的这个第一行代码是在计算什么. 按照反向传播的起点来算, 应该是从损失函数开始算起, 但是这个求解梯度的方法并没有从损失值还是计算, 而是从输出层的神经元的激活结果开始算起, 这样子是正确的么? 如果正确, 还请帮我解释一下, 万分感谢各位的帮助. @FatCockHu, @samchild , @ghoulich

shironeko1337 commented 2 weeks ago

最近我回头看反向传播的过程. 在全连接神经网络的反向传播的实现代码部分 (class NetWork): def calc_gradient(self, label): delta = self.layers[-1].activator.backward(self.layers[-1].output) * (label - self.layers[-1].output) for layer in self.layers[::-1]: layer.backward(delta) delta = layer.delta return delta. 结合文章, 我没有看明白求解梯度的这个第一行代码是在计算什么. 按照反向传播的起点来算, 应该是从损失函数开始算起, 但是这个求解梯度的方法并没有从损失值还是计算, 而是从输出层的神经元的激活结果开始算起, 这样子是正确的么? 如果正确, 还请帮我解释一下, 万分感谢各位的帮助. @FatCockHu, @samchild , @ghoulich

损失函数的结果不需要计算,只需要计算损失函数对于最后输出的偏导,也就是 self.layers[-1].activator.backward(self.layers[-1].output) 这里

yepaoxixi commented 2 weeks ago

你发过来的邮件怎么都是乱码啊,什么都看不到,再发一次吧。

shironeko1337 commented 2 weeks ago

[image: image.png] does that make sense?

On Wed, Aug 14, 2024 at 1:16 AM yanfeng @.***> wrote:

你发过来的邮件怎么都是乱码啊,什么都看不到,再发一次吧。

— Reply to this email directly, view it on GitHub https://github.com/hanbt/learn_dl/issues/23#issuecomment-2288125774, or unsubscribe https://github.com/notifications/unsubscribe-auth/BIMIGZYHF7KEVPWGTSQOQMLZRMG63AVCNFSM6AAAAABMPZ6UXGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOBYGEZDKNZXGQ . You are receiving this because you commented.Message ID: @.***>