hanbt / learn_dl

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

fc.python backward()是否有错误? #15

Open ChangZihao opened 6 years ago

ChangZihao commented 6 years ago

47 行 本层delta的计算应该是用本层的output的backward()结果乘w上一层delta 是否应该改成self.delta = self.activator.backward(self.output) np.dot( self.W.T, delta_array)

alwaysPKU commented 6 years ago

我也觉得是这样

yuanLink commented 6 years ago

作者这个函数里面得

self.delta = self.activator.backward(self.output) * np.dot( self.W.T, delta_array)

这段代码计算的是前一层的delta,所以用的是input

ArinoWang commented 6 years ago

是这样的,假设你的代码中建立一个Network([5,4,1]),代表第一全连接层输入5、输出4,第二个全连接层,输入4、输出1,而我们一般可能认为他所写的FullConnectedLayer是表示3层,其实不然。所以当进入最后一层算delta时,其实不是在算输出层的delta(即只有一个节点的那一层),而是进入了一个由输入4、输出1组成的全连接层,用self.input就相当于他理论中介绍的隐藏层的那个delta。

shironeko1337 commented 2 weeks ago

首先代码是可以通过的,其次个人觉得这里其实会造成歧义,因为激活函数的偏导是用输出算的,所以backward的输入确实应该是"输出"而不是"输入",问题在于,这到底是上一层的输入输出,还是这一层的

从正确性角度分析,因为self.delta = self.activator.backward()的结果的是下一层的self.delta_array,所以这里的backward()的参数一定是一个shape和下一层self.delta_array相同的矩阵,也就是self.input

如果还有疑问,这里提供两个信息:

最后一层实际上调用了两次激活函数,最后一层的输入是第一次调用激活函数之后的结果 第一层实际上不需要计算误差值delta,因为不需要向前传导

所以如果神经网络的节点数通过[784,300,10]这样的形式定义,其实只有最后一层神经网络需要计算delta,对于最后一层的backward来说,他拿到的delta_array是第二次激活函数调用的delta。如果需要计算delta的层数多于一层,那么很显然因为我们要计算的目标是“上一层权重”的误差,那么肯定用的是上一层的输出,也就是这一层的输入

多数一句,这里的fc.py代码个人感觉还是不够完整,如果对于某些activator来说,计算误差值是需要原始输入的,这里input只是输出