我正在关注有关NN和反向传播的本教程。
我是python的新手,正在尝试将代码转换为MATLAB。有人可以请您解释以下代码行(来自本教程):
delta3[range(num_examples), y] -= 1
总之,如果我没有记错的话,delta3
和y
的载体和num_examples
为整数。
我的理解是,delta3=probs-y
就像在这个数学交换条目中一样(谢谢@rayryeng)。为什么以及何时应减去1?
否则,有人可以将我定向到一个我可以运行并遵循代码的在线站点吗?我尝试运行的所有地方(包括家用PC)都出现错误:
“ NameError:未定义名称'sklearn'”(可能是我缺少的导入)
这条线:delta3[range(num_examples), y] -= 1
是计算softmax损失函数的梯度的一部分。我为您提供了一个不错的链接,该链接为您提供了有关如何构造此损失函数以及其背后的直观认识的更多信息:http : //peterroelants.github.io/posts/neural_network_implementation_intermezzo02/。
另外,我还请您参考Mathematics Stack Exchange上的这篇文章,向您展示softmax损失的梯度是如何得出的:https : //math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function。将第一个链接视为深入研究,而第二个链接是tl;dr
第一个链接的。
softmax损失函数的梯度是输出层的梯度,您需要将其向后传播到输出层中,然后再继续输出算法,以继续进行反向传播算法。
总结一下我上面链接的帖子,如果您为一个训练示例计算softmax损失的梯度,那么对于每个类别,损失的梯度就是对该类别评估的softmax值。对于实际训练示例所属的类,您还需要将损失值减去1。请注意,每个类的实例的梯度i
等于p_i - y_i
其中p_i
是类的SOFTMAX得分i
为示例并且y_i
是使用一热编码方案的分类标签。特别是y_i = 0
ifi
不是示例的真实类,y_i = 1
如果是。delta3
迷你批次中包含每个示例的softmax损失函数的梯度。具体来说,它是一个2D矩阵,其中行的总数等于训练示例num_examples
的数目,或者列数是类别的总数。
首先,我们为每个训练示例和每个班级计算softmax分数。接下来,对于渐变的每一行,我们确定与示例所属的真实类对应的列位置,然后将分数减去1。range(num_examples)
这将0
最多生成一个列表,num_examples - 1
并y
包含每个示例的真实类标签。因此,对于每个对range(num_examples)
和y
,此访问权行和列位置减去1通过最终确定损失函数的梯度。
现在在“数学堆栈交换”中以及您的理解中,梯度为delta3 = probs - y
。假定它y
是一个一热编码矩阵,这意味着它y
的大小probs
与y
它的每一行相同,并且所有行都为零,但包含包含设置为1的正确类的列索引除外。因此,如果考虑正确, ,如果您生成了一个矩阵y
,其中除了示例所属的类编号之外,每一行的列都为零,这等效于简单地访问每一行的右列并将分数减去1。
在MATLAB中,您实际上需要创建线性索引才能促进这种相减。具体来说,您需要使用sub2ind
将这些行和列位置转换为线性索引,然后才能访问渐变矩阵并将值减去1。
因此:
ind = sub2ind(size(delta3), 1 : num_examples, y + 1);
delta3(ind) = delta3(ind) - 1;
在您已链接的Python教程中,假定类标签从0
到N-1
哪里N
是类总数。我们开始索引阵列开始,你必须在MATLAB小心1
,所以我已经加入1
到y
在上面的代码,以确保您的标签在开始1
代替0
。ind
包含我们需要访问的行和列位置的线性索引,因此我们使用这些索引完成了减法。
如果要使用从编辑中获得的知识来表述这一点,则可以这样做:
ymatrix = full(sparse(1 : num_examples, y + 1, 1, size(delta3, 1), size(delta3, 2));
delta3 = probs - ymatrix;
ymatrix
包含我所讨论的矩阵,其中每一行对应一个全为零的示例,除了与该示例所属的类相关的列(即1)以外,您可能从未见过sparse
andfull
函数。sparse
允许您创建零矩阵,并且可以指定非零的行和列位置以及这些位置中的每一个取值。在这种情况下,我正好每行访问一个元素,并使用该示例的类ID来访问列,并将每个位置设置为1。还要记住,假设我的类是1 ID从0开始。因为这是一个sparse
矩阵,所以我将其转换为full
一个数字矩阵,而不是用sparse
形成。因此,此代码在操作上与我显示的先前代码段等效。但是,由于您不创建额外的矩阵来方便进行梯度计算,因此第一种方法效率更高。您正在修改渐变。
附带说明一下,sklearn
它是scikit-learn Python机器学习软件包,它NameError
是指您没有安装实际的软件包。要安装它,请使用pip
或easy_install
将Python软件包安装到您的计算机...。因此在您的命令行中,它很简单:
pip install sklearn
要么:
easy_install sklearn
但是,运行上面的减法代码不需要scikit-learn。尽管您确实需要NumPy,所以请确保已安装该软件包。
对于pip
:
pip install numpy
...以及easy_install
:
easy_install numpy
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句