反向传导算法

From Ufldl

Jump to: navigation, search
Line 6: Line 6:
-
假设我们有一个固定样本集 <math>\textstyle \{ (x^{(1)}, y^{(1)}), \ldots, (x^{(m)}, y^{(m)}) \}</math>,它包含 <math>\textstyle m</math> 个样例。我们可以用批量梯度下降法求解神经网络。具体来讲,对于单个样例 <math>\textstyle (x,y)</math> ,其代价函数为:
+
假设我们有一个固定样本集 <math>\textstyle \{ (x^{(1)}, y^{(1)}), \ldots, (x^{(m)}, y^{(m)}) \}</math>,它包含 <math>\textstyle m</math> 个样例。我们可以用批量梯度下降法求解神经网络。具体来讲,对于单个样例 <math>\textstyle (x,y)</math>,其代价函数为:
Line 38: Line 38:
-
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们用 <math>\textstyle y = 0</math> 或 <math>\textstyle 1</math> ,来代表两种类型的标签(回忆一下,这是因为 sigmoid激活函数的值域为 <math>\textstyle [0,1]</math> ;如果我们使用双曲正切型激活函数,那么应该选用-1和+1作为标签)。对于回归问题,我们首先要变换输出值域(译者注:也就是 <math>\textstyle y</math>),以保证其范围为 <math>\textstyle [0,1]</math> (同样地,如果我们使用双曲正切型激活函数,使其值域范围为 <math>\textstyle [-1,1]</math>)。
+
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们用 <math>\textstyle y = 0</math> 或 <math>\textstyle 1</math>,来代表两种类型的标签(回忆一下,这是因为 sigmoid激活函数的值域为 <math>\textstyle [0,1]</math> ;如果我们使用双曲正切型激活函数,那么应该选用-1和+1作为标签)。对于回归问题,我们首先要变换输出值域(译者注:也就是 <math>\textstyle y</math>),以保证其范围为 <math>\textstyle [0,1]</math> (同样地,如果我们使用双曲正切型激活函数,使其值域范围为 <math>\textstyle [-1,1]</math>)。
Line 68: Line 68:
</math>  
</math>  
-
以上两行公式稍有不同,第一行比第二行多出一项,是因为权重衰减是作用于 <math>\textstyle W</math> 而不是 <math>\textstyle b</math> 。
+
以上两行公式稍有不同,第一行比第二行多出一项,是因为权重衰减是作用于 <math>\textstyle W</math> 而不是 <math>\textstyle b</math>。
-
反向传播算法的思路如下:给定一个样例 <math>\textstyle (x,y)</math>,我们首先进行“前向传导”运算,计算出网络中所有的激活值,包括 <math>\textstyle h_{W,b}(x)</math> 的输出值。之后,针对第 <math>\textstyle l</math> 层的每一个节点 <math>\textstyle i</math> ,我们计算出其“残差” <math>\textstyle \delta^{(l)}_i</math> ,该残差表明了该节点对最终输出值的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的激活值与实际值之间的差距,我们将这个差距定义为 <math>\textstyle \delta^{(n_l)}_i</math>  (这里的第 <math>\textstyle n_l</math> 层表示输出层)。对于隐藏单元我们是如何处理的呢?我们将基于节点(译者注:第 <math>\textstyle l+1</math> 层节点)残差的加权平均值计算 <math>\textstyle \delta^{(l)}_i</math>,这些节点以 <math>\textstyle a^{(l)}_i</math> 作为输入。下面将给出反向传导算法的细节:
+
反向传播算法的思路如下:给定一个样例 <math>\textstyle (x,y)</math>,我们首先进行“前向传导”运算,计算出网络中所有的激活值,包括 <math>\textstyle h_{W,b}(x)</math> 的输出值。之后,针对第 <math>\textstyle l</math> 层的每一个节点 <math>\textstyle i</math>,我们计算出其“残差” <math>\textstyle \delta^{(l)}_i</math>,该残差表明了该节点对最终输出值的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的激活值与实际值之间的差距,我们将这个差距定义为 <math>\textstyle \delta^{(n_l)}_i</math>  (这里的第 <math>\textstyle n_l</math> 层表示输出层)。对于隐藏单元我们是如何处理的呢?我们将基于节点(译者注:第 <math>\textstyle l+1</math> 层节点)残差的加权平均值计算 <math>\textstyle \delta^{(l)}_i</math>,这些节点以 <math>\textstyle a^{(l)}_i</math> 作为输入。下面将给出反向传导算法的细节:
<ol>
<ol>
<li>进行前向传导计算,得到 <math>\textstyle L_2</math> 、 <math>\textstyle L_3</math> …直到输出层 <math>\textstyle L_{n_l}</math> 的激活值。
<li>进行前向传导计算,得到 <math>\textstyle L_2</math> 、 <math>\textstyle L_3</math> …直到输出层 <math>\textstyle L_{n_l}</math> 的激活值。
-
<li>对于第 <math>\textstyle n_l</math> 层(输出层)的每个输出单元 <math>\textstyle i</math> ,我们根据以下公式计算残差:
+
<li>对于第 <math>\textstyle n_l</math> 层(输出层)的每个输出单元 <math>\textstyle i</math>,我们根据以下公式计算残差:
:<math>  
:<math>  
Line 117: Line 117:
</ol>
</ol>
-
最后,我们用矩阵-向量表示法重写以上算法。我们使用“<math>\textstyle \bullet</math>” 表示向量乘积运算符(在Matlab或Octave里用“<tt>.*</tt>”表示,也称作阿达马乘积),因此若 <math>\textstyle a = b \bullet c</math>,则 <math>\textstyle a_i = b_ic_i</math> 。在上一个教程中我们扩展了 <math>\textstyle f(\cdot)</math> 的定义,使其包含向量运算,这里我们对偏导数 <math>\textstyle f'(\cdot)</math> 也做了同样的处理(于是又有 <math> f'([z_1, z_2, z_3]) =
+
最后,我们用矩阵-向量表示法重写以上算法。我们使用“<math>\textstyle \bullet</math>” 表示向量乘积运算符(在Matlab或Octave里用“<tt>.*</tt>”表示,也称作阿达马乘积),因此若 <math>\textstyle a = b \bullet c</math>,则 <math>\textstyle a_i = b_ic_i</math>。在上一个教程中我们扩展了 <math>\textstyle f(\cdot)</math> 的定义,使其包含向量运算,这里我们对偏导数 <math>\textstyle f'(\cdot)</math> 也做了同样的处理(于是又有 <math> f'([z_1, z_2, z_3]) =
[f'(z_1), f'(z_2), f'(z_3)]</math> )。
[f'(z_1), f'(z_2), f'(z_3)]</math> )。
Line 145: Line 145:
-
'''实现中应注意:'''在以上的第2步和第3步中,我们需要为每一个 <math>\textstyle i</math> 值计算 <math>\textstyle f'(z^{(l)}_i)</math> 。假设 <math>\textstyle f(z)</math> 是sigmoid函数,并且我们已经在神经网络的前向传导运算中得到了 <math>\textstyle a^{(l)}_i</math>。于是,使用我们早先推导出的 <math>\textstyle f'(z)</math> 的表达式,我们可以计算得到 <math>\textstyle f'(z^{(l)}_i) = a^{(l)}_i (1- a^{(l)}_i)</math> 。
+
'''实现中应注意:'''在以上的第2步和第3步中,我们需要为每一个 <math>\textstyle i</math> 值计算 <math>\textstyle f'(z^{(l)}_i)</math>。假设 <math>\textstyle f(z)</math> 是sigmoid函数,并且我们已经在神经网络的前向传导运算中得到了 <math>\textstyle a^{(l)}_i</math>。于是,使用我们早先推导出的 <math>\textstyle f'(z)</math> 的表达式,我们可以计算得到 <math>\textstyle f'(z^{(l)}_i) = a^{(l)}_i (1- a^{(l)}_i)</math>。
Line 152: Line 152:
<ol>
<ol>
-
<li>对于所有 <math>\textstyle l</math>,令 <math>\textstyle \Delta W^{(l)} := 0</math> ,  <math>\textstyle \Delta b^{(l)} := 0</math> ,(设置为全零矩阵或全零向量)
+
<li>对于所有 <math>\textstyle l</math>,令 <math>\textstyle \Delta W^{(l)} := 0</math>,  <math>\textstyle \Delta b^{(l)} := 0</math>,(设置为全零矩阵或全零向量)
<li>对于 <math>\textstyle i = 1</math> 到 <math>\textstyle m</math>,
<li>对于 <math>\textstyle i = 1</math> 到 <math>\textstyle m</math>,
<ol type="a">
<ol type="a">
-
<li>使用反向传播算法计算 <math>\textstyle \nabla_{W^{(l)}} J(W,b;x,y)</math> 和 <math>\textstyle \nabla_{b^{(l)}} J(W,b;x,y)</math> 。
+
<li>使用反向传播算法计算 <math>\textstyle \nabla_{W^{(l)}} J(W,b;x,y)</math> 和 <math>\textstyle \nabla_{b^{(l)}} J(W,b;x,y)</math>。
-
<li>计算 <math>\textstyle \Delta W^{(l)} := \Delta W^{(l)} + \nabla_{W^{(l)}} J(W,b;x,y)</math> 。
+
<li>计算 <math>\textstyle \Delta W^{(l)} := \Delta W^{(l)} + \nabla_{W^{(l)}} J(W,b;x,y)</math>。
-
<li>计算 <math>\textstyle \Delta b^{(l)} := \Delta b^{(l)} + \nabla_{b^{(l)}} J(W,b;x,y)</math> 。  
+
<li>计算 <math>\textstyle \Delta b^{(l)} := \Delta b^{(l)} + \nabla_{b^{(l)}} J(W,b;x,y)</math>。  
</ol>
</ol>
Line 256: Line 256:
This cost function above is often used both for classification and for regression problems. For classification, we let <math>y = 0</math> or <math>1</math> represent the two class labels (recall that the sigmoid activation function outputs values in <math>[0,1]</math>; if we were using a tanh activation function, we would instead use -1 and +1 to denote the labels).  For regression problems, we first scale our outputs to ensure that they lie in the <math>[0,1]</math> range (or if we were using a tanh activation function, then the <math>[-1,1]</math> range).
This cost function above is often used both for classification and for regression problems. For classification, we let <math>y = 0</math> or <math>1</math> represent the two class labels (recall that the sigmoid activation function outputs values in <math>[0,1]</math>; if we were using a tanh activation function, we would instead use -1 and +1 to denote the labels).  For regression problems, we first scale our outputs to ensure that they lie in the <math>[0,1]</math> range (or if we were using a tanh activation function, then the <math>[-1,1]</math> range).
:【初译】:
:【初译】:
-
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们使得<math>y = 0</math>或<math>1</math> ,来代表两种类型的标签(回忆一下,这是因为S型(sigmoid)激励函数的值域为<math>[0,1]</math>;如果我们使用双曲正切型激励函数,我们应该选用-1和+1作为标签)。对于回归问题,我们首先要对我们的输出值域进行缩放,以保证其范围为<math>[0,1]</math>(同样地,如果我们使用双曲正切型激励函数,使其值域范围为<math>[-1,1]</math>)。
+
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们使得<math>y = 0</math>或<math>1</math>,来代表两种类型的标签(回忆一下,这是因为S型(sigmoid)激励函数的值域为<math>[0,1]</math>;如果我们使用双曲正切型激励函数,我们应该选用-1和+1作为标签)。对于回归问题,我们首先要对我们的输出值域进行缩放,以保证其范围为<math>[0,1]</math>(同样地,如果我们使用双曲正切型激励函数,使其值域范围为<math>[-1,1]</math>)。
:【一校】:
:【一校】:
-
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们用<math>y = 0</math>或<math>1</math> ,来代表两种类型的标签(回忆一下,这是因为S型(sigmoid)激活函数的值域为<math>[0,1]</math>;如果我们使用双曲正切型激活函数,我们应该选用-1和+1作为标签)。对于回归问题,我们首先要变换我们的输出值域,以保证其范围为<math>[0,1]</math>(同样地,如果我们使用双曲正切型激励函数,使其值域范围为<math>[-1,1]</math>)。
+
以上的代价函数经常被用于分类和回归问题。在分类问题中,我们用<math>y = 0</math>或<math>1</math>,来代表两种类型的标签(回忆一下,这是因为S型(sigmoid)激活函数的值域为<math>[0,1]</math>;如果我们使用双曲正切型激活函数,我们应该选用-1和+1作为标签)。对于回归问题,我们首先要变换我们的输出值域,以保证其范围为<math>[0,1]</math>(同样地,如果我们使用双曲正切型激励函数,使其值域范围为<math>[-1,1]</math>)。
[一校注:Activation,这里是一种结果,所以用“激活”合适]
[一校注:Activation,这里是一种结果,所以用“激活”合适]

Revision as of 14:15, 14 March 2013

Personal tools