我已经实现了Softmax,以便用于交叉熵成本函数,但我的问题是,我应该使用Softmax的输出(即概率)来进行反向传播和更新权重吗?
在我看来,这似乎不太正确,因为Softmax返回的是概率,而不是神经元的实际值。
另一个选项是使用Softmax的导数的输出。能有人解释一下吗?
回答:
你应该使用这些值本身来计算导数。
计算输出层误差的方程如下(f
是激活函数,f'
是它的导数):
# outputs[a] 表示第(a)层的输出outputs[n] = f(outputs[n-1] . weights[n] + biases[n]) # 最终输出output_error = (outputs[n] - labels) * f'(outputs[n-1])
请注意,f'
应用于outputs[n-1]
,而不是outputs[n]
,因为outputs[n-1]
是我们函数f(outputs[n-1] . weights[n] + biases[n])
的原始输入。
为了更好地理解导数的用途和工作原理,让我们先看看它的目的(摘自维基百科):
实变量函数的导数衡量了函数(输出)值相对于其参数(输入值)变化的敏感度。
本质上,它衡量了当输入发生微小变化时,输出变化的速度和方向(可以说它衡量了输出如何依赖于输入)。
结合一种测量我们网络误差的方法(成本函数),我们可以获得关于如何调整激活函数的输入(即我们的权重)的最佳方式的信息,以便输出更接近我们期望的标签。
我们将误差乘以导数,我们就得到了一个小更新,这个更新的方向和比例最能优化函数以达到我们的目标。更新应用于权重(它们是激活函数的输入),因此下次激活函数触发时,输出将稍微更接近我们的标签。
关于将导数应用于函数的结果还是其输入,因为我们希望看到我们的函数输出根据其输入的变化情况,导数必须采用函数的原始输入,以便为我们提供关于它们的信息;这就是为什么导数应用于层的输入(在这种情况下,是上一层的输出)。
你也可以尝试下面的实验来理解为什么会这样:
softmax [-1, 0, 1] # [9.003057317038046e-2,0.24472847105479767,0.6652409557748219]softmax' [-1, 0, 1] # [0.19661193324148185,0.25,0.19661193324148185]softmax' (softmax [-1, 0, 1]) # [0.24949408957503114,0.24629379904081422,0.22426006146673663]
如你所见,softmax'
应用于softmax
的结果并不能传达关于原始值的太多信息,因为生成的值彼此太接近,但softmax'
应用于softmax
的原始输入则提供了关于输入比例的信息。
我推荐这篇文章来解释反向传播的方程:http://neuralnetworksanddeeplearning.com/chap2.html