Python numpy:计算softmax函数的导数
我正试图用Python numpy:计算softmax函数的导数,python,numpy,neural-network,backpropagation,softmax,Python,Numpy,Neural Network,Backpropagation,Softmax,我正试图用MNIST在一个简单的三层神经网络中理解backpropagation 输入层具有权重和偏差。标签是MNIST,因此它是10类向量 第二层是线性变换。第三层是softmax激活,以获得作为概率的输出 反向传播计算每一步的导数,并将其称为梯度 上一层将全局或上一个渐变添加到局部渐变。我在计算softmax 一些在线资源对softmax及其衍生物进行了解释,甚至给出了softmax本身的代码示例 def softmax(x): """Compute the softmax of v
MNIST
在一个简单的三层神经网络中理解backpropagation
输入层具有权重
和偏差
。标签是MNIST
,因此它是10
类向量
第二层是线性变换
。第三层是softmax激活
,以获得作为概率的输出
反向传播
计算每一步的导数,并将其称为梯度
上一层将全局
或上一个
渐变添加到局部渐变
。我在计算softmax
一些在线资源对softmax及其衍生物进行了解释,甚至给出了softmax本身的代码示例
def softmax(x):
"""Compute the softmax of vector x."""
exps = np.exp(x)
return exps / np.sum(exps)
当i=j
和i!=j
。这是我想到的一个简单的代码片段,希望验证我的理解:
def softmax(self, x):
"""Compute the softmax of vector x."""
exps = np.exp(x)
return exps / np.sum(exps)
def forward(self):
# self.input is a vector of length 10
# and is the output of
# (w * x) + b
self.value = self.softmax(self.input)
def backward(self):
for i in range(len(self.value)):
for j in range(len(self.input)):
if i == j:
self.gradient[i] = self.value[i] * (1-self.input[i))
else:
self.gradient[i] = -self.value[i]*self.input[j]
然后
self.gradient
是localgradient
,它是一个向量。这是正确的吗?有更好的方法写这个吗?就像我说的,你有n^2
偏导数
如果你计算一下,你会发现dSM[i]/dx[k]
是SM[i]*(dx[i]/dx[k]-SM[i])
,所以你应该:
if i == j:
self.gradient[i,j] = self.value[i] * (1-self.value[i])
else:
self.gradient[i,j] = -self.value[i] * self.value[j]
而不是
if i == j:
self.gradient[i] = self.value[i] * (1-self.input[i])
else:
self.gradient[i] = -self.value[i]*self.input[j]
顺便说一下,这可以像这样更简洁地计算(矢量化):
我假设你有一个带有
W1
,b1
的三层NN,for与从输入层到隐藏层的线性变换相关联,W2
,b2
与从隐藏层到输出层的线性变换相关联Z1
和Z2
是隐藏层和输出层的输入向量a1
和a2
表示隐藏层和输出层的输出a2
是您的预测输出delta3
和delta2
是错误(反向传播),您可以看到损失函数相对于模型参数的梯度
这是3层NN(输入层,只有一个隐藏层和一个输出层)的一般场景。您可以按照上面描述的过程来计算梯度,这应该很容易计算!因为这篇文章的另一个答案已经指出了代码中的问题,所以我不再重复相同的内容。
np.exp
不稳定,因为它有Inf。
因此,您应该减去x
中的最大值
def softmax(x):
"""Compute the softmax of vector x."""
exps = np.exp(x - x.max())
return exps / np.sum(exps)
如果
x
是矩阵,请检查中的softmax函数。这太不清楚了。。。你到底想计算什么梯度?SM是从R^n到R^n的映射,所以你可以定义n^2个偏导数dSM[i]/dx[k]…@JulienBernu我已经更新了这个问题。有什么想法吗?好吧,这就是雅各比?我想我还有另一个想法。@wasi答案中的线性变换是隐藏层吗?我想是的。请注意,大多数人认为最后一个线性变换+ SM仅为一个层。通常,层是一个线性变换,然后是一个非线性(sigmoid、tanh、SM、relu或其他…)在我看到的一些实现中,前向传播中的softmax的输出值也被使用。在您的版本中,情况并非如此,仅使用损失函数梯度的输入。我是否遗漏了什么,或者这是完整的公式?再澄清一件事。如果我们从z2开始,即z1从未存在过,这会使它成为2层NN吗?线性变换发生两次,使其成为3层NN?你能解释方程中各层的名称吗?您的案例中的输入层是z1?有多少隐藏层?它们是什么?太棒了!非常感谢你!上帝保佑你,祝你博士学习好运!我将更新这个库,使之与上述内容相匹配。完成后将编辑问题这里的损失函数是什么?
def softmax(x):
"""Compute the softmax of vector x."""
exps = np.exp(x - x.max())
return exps / np.sum(exps)