反向传播的缩放

时间:2017-01-14 18:28:50

标签: python matlab machine-learning neural-network backpropagation

我关注NN上的this tutorial和反向传播。

我是python的新手,我正在尝试将代码转换为MATLAB。 有人可以解释下面的代码行(来自教程):

delta3[range(num_examples), y] -= 1

简而言之,如果我没有弄错的话,delta3y是向量,num_examples是整数。

我理解delta3=probs-ythis math exchange entry一样(谢谢你@rayryeng)。为什么以及何时应该减去1?

否则任何人都可以将我引导到一个在线网站我可以简单地运行并遵循代码?在我试图运行的任何地方(包括我的家用电脑),我都遇到了错误:

" NameError:name' sklearn'没有定义" (可能是我缺少的导入)

1 个答案:

答案 0 :(得分:3)

这一行:delta3[range(num_examples), y] -= 1是计算softmax损失函数梯度的一部分。我向您推荐这个很好的链接,它为您提供有关如何制定此损失函数及其背后的直觉的更多信息:http://peterroelants.github.io/posts/neural_network_implementation_intermezzo02/

此外,我将向您介绍数学堆栈交换中的这篇文章,该文章向您展示了如何推导出softmax损失的梯度:https://math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function。将第一个链接视为深度链接,而第二个链接是第一个链接的tl;dr

softmax loss函数的梯度是输出层的梯度,在输出层继续使用反向传播算法之前,需要将其向后传播到层中。

总结我上面链接的帖子,如果计算训练样例的softmax损失的梯度,对于每个类,损失的梯度就是为该类评估的softmax值。您还需要为实际训练示例所属的类减去1的损失值。请注意,类i的示例的渐变等于p_i - y_i,其中p_i是示例{class 1}}的softmax得分,i是使用单热编码方案的分类标签。特别是y_i如果y_i = 0不是示例的真正类,i如果是y_i = 1delta3包含迷你批次中每个示例的softmax损失函数的梯度。具体来说,它是一个2D矩阵,其中总行数等于训练样例的数量,或num_examples,而列数是类的总数。

首先,我们计算每个训练样本和每个类的softmax分数。接下来,对于渐变的每一行,我们确定与示例所属的真实类对应的列位置,并将得分减去1. range(num_examples)将生成从0到{{num_examples - 1的列表1}}和y包含每个示例的真正类标签。因此,对于每对range(num_examples)y,它会访问右侧行和列位置以减去1,以最终确定损失函数的梯度。

现在,在数学堆栈交换帖子以及您的理解中,渐变为delta3 = probs - y。这假定y单热编码矩阵,这意味着yprobs的大小相同,并且y的每一行都有y对于包含设置为1的正确类的列索引,除之外全部为零。因此,如果您正确地考虑它,如果您生成矩阵ind = sub2ind(size(delta3), 1 : num_examples, y + 1); delta3(ind) = delta3(ind) - 1; ,其中每行为除了示例所属的类号之外,列都为零,它等同于简单地访问每行的右列并将得分减去1.

在MATLAB中,您实际上需要创建线性索引以便于此减法。具体来说,您需要使用sub2ind将这些行和列位置转换为线性索引,然后我们可以访问渐变矩阵并将值减1。

因此:

0

在您已链接的Python教程中,类标签被假定为从N-1N,其中1是类的总数。在MATLAB中我们必须小心,我们从1开始索引数组,因此我在上面的代码中添加了y1,以确保标签从0开始而不是indymatrix = full(sparse(1 : num_examples, y + 1, 1, size(delta3, 1), size(delta3, 2)); delta3 = probs - ymatrix; 包含我们需要访问的行和列位置的线性索引,因此我们使用这些索引完成减法。

如果您使用从编辑中获得的知识来表达这一点,那么您可以这样做:

ymatrix

sparse包含我所谈论的矩阵,其中每一行对应一个全零的示例,除了属于该示例所属类的列,即1.您之前可能没见过的内容是sparsefull函数。 sparse允许您创建零矩阵,您可以指定非零的行和列位置以及每个位置所采用的值。在这种情况下,我完全访问每行一个元素,并使用示例的类ID来访问列并将每个位置设置为1.还要记住我添加1作为I&# 39;假设您的班级ID从0开始。因为这是full矩阵,我然后将其转换为sparse,为您提供数字矩阵,而不是以sklearn形式表示。因此,此代码在操作上与我显示的前一代码片段相同。但是,第一种方法更有效,因为您没有创建额外的矩阵来促进梯度计算。您正在修改渐变。

作为旁注,NameErrorscikit-learn Python机器学习包,而pip install sklearn 是指你没有安装实际的包。要安装它,请使用pipeasy_install将Python软件包安装到您的计算机上....因此在您的命令行中,它很简单:

easy_install sklearn

或:

pip

但是,运行上述减法代码不需要scikit-learn。您确实需要NumPy,因此请确保已安装该软件包。

pip install numpy

easy_install

...以及easy_install numpy

{{1}}