首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反向传播标度

反向传播标度
EN

Stack Overflow用户
提问于 2017-01-14 18:28:50
回答 1查看 751关注 0票数 3

我是跟踪神经网络和反向传播的本教程

我对python很陌生,我正在尝试将代码转换为MATLAB。请您解释以下代码行(来自本教程):

代码语言:javascript
复制
delta3[range(num_examples), y] -= 1

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

我的理解是delta3=probs-y这个数学交换条目一样(谢谢@rayryeng)。为什么和何时我要减去1?

否则,有人能指引我到一个在线网站,我可以简单地运行并遵循代码?我试图运行的每一个地方都会出现错误(包括我的家用PC):

"NameError:没有定义名称'sklearn‘“(可能是我缺少的一个导入)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-16 06:57:18

这条线:delta3[range(num_examples), y] -= 1是计算软件最大损失函数的梯度的一部分。我向您介绍这个很好的链接,它为您提供了更多关于这个丢失函数是如何形成的信息,以及它背后的直觉:intermezzo02 02/

此外,我还请您参考这篇关于数学堆栈交换的文章,该文章向您展示了软件最大损失的梯度是如何导出的:https://math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function。把第一个链接看作是一个深潜,而第二个链接是第一个链接的tl;dr

softmax损失函数的梯度是输出层的梯度,需要向后传播到输出层之前的层中,才能继续反向传播算法。

总结我上面所链接的帖子,如果您为一个训练示例计算softmax损失的梯度,对于每个类,损失的梯度就是为该类评估的softmax值。此外,对于实际培训示例所属的类,还需要减去损失值1。请记住,i类的一个示例的梯度等于p_i - y_i,其中p_i是该示例的i类的softmax分数,而y_i是使用一次热编码方案的分类标签。特别是,如果y_i = 0不是示例的真正类,则为i,如果是的话,则为y_i = 1delta3包含小批处理中每个示例的软最大损失函数的梯度。具体来说,它是一个2D矩阵,其中行总数等于训练示例的数量,或者num_examples,而列数是类的总数。

首先,我们计算了每个训练示例和每一节课的softmax分数。接下来,对于梯度的每一行,我们确定与该示例所属的真类对应的列位置,并将分数减去1。range(num_examples)将生成一个从0num_examples - 1的列表,y包含每个示例的真实类标签。因此,对于每一对range(num_examples)y,这将访问正确的行和列位置以减去1,从而最终确定损失函数的梯度。

现在在数学堆栈交换的帖子以及你的理解,梯度是delta3 = probs - y。这假设y是一个单热编码矩阵,这意味着y具有与probs相同的大小,而对于y的每一行,除了包含设置为1的正确类的列索引的之外,它都是零。因此,如果您正确地考虑了这个问题,那么如果您正确地考虑了这个问题,那么如果您生成了一个矩阵y,其中每一行的列都为零,除了该示例所属的类数之外,这相当于访问每一行的右列并减去1的分数。

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

因此:

代码语言:javascript
复制
ind = sub2ind(size(delta3), 1 : num_examples, y + 1);
delta3(ind) = delta3(ind) - 1;

在您所链接的Python教程中,类标签被假定为从0N-1,其中N是类的总数。在MATLAB中,您必须小心,我们从1开始索引数组,因此我在上面的代码中将1添加到y中,以确保标签从1而不是0开始。ind包含我们需要访问的行和列位置的线性索引,因此我们使用这些索引完成减法。

如果您要使用您从编辑中获得的知识来表述这一点,则应该这样做:

代码语言:javascript
复制
ymatrix = full(sparse(1 : num_examples, y + 1, 1, size(delta3, 1), size(delta3, 2));
delta3 = probs - ymatrix;

ymatrix包含我讨论过的矩阵,其中每一行对应于一个包含所有零的示例,除了与该示例所属的类相关的列(即1 )。您可能还没有看到sparsefull函数。sparse允许您创建一个零矩阵,您可以指定非零的行和列位置,以及这些位置中每个位置的值。在本例中,我实际上是在每一行访问一个元素,并使用示例中的类ID来访问这些列,并将每个位置设置为1。还请记住,假设类ID从0开始,我将添加1。因为这是一个sparse矩阵,所以我将它转换为full,以给出一个数字矩阵,而不是以sparse形式表示它。因此,此代码在操作上等效于我演示的前面的代码片段。然而,它是更有效的第一种方式,因为你没有创建一个额外的矩阵,以方便梯度计算。相反,您正在修改渐变。

作为一个侧面,sklearn科学知识-学习 Python机器学习包,NameError是指您没有安装实际的包。要安装它,请使用pipeasy_install将package安装到计算机上.因此,在命令行中,它非常简单:

代码语言:javascript
复制
pip install sklearn

或者:

代码语言:javascript
复制
easy_install sklearn

但是,对于您运行上述减法代码来说,不应该需要scikit学习。不过,您确实需要NumPy,所以请确保安装了该软件包。

对于pip

代码语言:javascript
复制
pip install numpy

..。对于easy_install

代码语言:javascript
复制
easy_install numpy
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41653482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档