# Backpropagation intuition (optional)

![](https://1031991694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ll2t57iip-nhAD5GGKl%2F-LlCgxkrm8y7zoek4wb-%2F-LlDQAv224TWn2Xh38-O%2FScreen%20Shot%202019-08-01%20at%208.23.52%20PM.png?alt=media\&token=6e596b75-31e4-4043-8e2a-873e4ff18b51)

上个视频中 你已经看过了反向传播的等式 在这个视频中 我们会用计算图 来更直观地学习这些式子的推导过程 这个视频不是必须要看的 所以 看或者不看这个视频都可以 不看这个视频你也应该可以完成所有任务 那么 回忆一下我们讨论的逻辑回归 我们首先从这个向前的步骤算出z 然后算出a 还有损失函数 之后我们要计算导数 从这个反向的步骤中我们可以先算出da 然后去计算dz 然后去计算dw和db 这个损失函数L(a,y) 等于-yloga-(1-y)log(1-a) -yloga-(1-y)log(1-a) 如果你熟悉 微积分并对a进行求导的话 你就会得到da的表达式 所以da就等于这个 如果你算出这个微积分的话就会知道这个是 -y/a+(1-y)/(1-a) 这就是对这个进行求导的结果 当你再反向推导一步去计算dz时 我们已经弄清楚了dz等于a-y 我之前解释过了为什么 但是事实证明从微积分的链式求导法则来说dz等于 da乘上g(z)的导数 这里的g(z)等于sigmoid(z) 也就是对于这个输出单元的逻辑回归的激活函数 对吧？ 所以记住这仍然是那个输入x1 x2 x3 然后通过一个sigmoid单元输出a 也就是y-hat的逻辑回归 这里激活函数是个sigmoid函数 顺便说一下 对于那些熟悉微积分的链式求导法则的同学 这个的原因是a等于sigmoid(z) 因此 L关于z的偏导数等于 L关于a的偏导数乘da/dz 这里的a等于sigmoid(z) 这个等于d(g(z))/dz 即g'(z) 这就是为什么这个表达式 也就是我们代码中的dz 等于这个表达式 也就是我们代码中的da乘g'(z) 于是这个就是这个 所以只有你熟悉微积分中的链式求导法则 才能理解那个最后的推导过程 但如果你不熟悉的话别担心 在需要的地方我会具体解释 最后在计算完了这个dz之后 我们会计算dw 也就是 dz乘上x 还有db 当只有一个训练样本时它就是dz 那么以上就是逻辑回归了 现在当我们要计算神经网络的反向传播时 我们要做的其实很像这个 但是我们要做两次因为现在我们的x 不单单是一个输出单元 它会先成为一个隐藏层之后再变成一个输出单元 所以我们会在这个有两层的神经网络里做两步 而不是像在这里一样只计算一步 那么在这个有一个输入层 一个隐藏层 和一个输出层的两层神经网络里 回想一下计算步骤 首先用这个等式算出z1 然后算出a1 再算出z2 注意这里的z2也取决于参数W2和b2 然后根据z2 计算出a2然后最终得到损失函数 而反向传播做的事是它会从反方向计算da2和dz2 然后向后去计算dW2和db2 再向后计算da1 dz1 等等 我们不需要关于输入x进行求导 因为对于监督学习来说x是不变的 所以我们不会去优化x 至少对于监督学习来说 我们不会关于x进行求导 我将会跳过具体计算da2的步骤 如果你想的话 你其实可以算出来 da2然后用它去计算dz2 但是在实际使用中 你可以把这两步合并成一步然后就会得到 dz2等于a2-y 就像以前一样 而且 我先把dw2和db2写在这下面 你会得到dw2等于dz2乘以 a1的转置 然后db2等于dz2 这步和我们在逻辑回归中计算dw=dz*x 的步骤挺像的 只是现在 a1在这里替代了x而且这里有个多出来的转置步骤 因为我们的这个大写的W矩阵和单个的w参数 之间需要进行转置 对吧？ 因为在只有一个输出的逻辑回归的情况下w是一个行向量 dw2是这样的 然而 这里的w是一个列向量 所以这就是为什么a1有个转置 而在逻辑回归的x这里没有 这样我们就完成了一半的反向传播 然后 如果你想的话你可以去计算da1 虽然在实际操作中da1和dz1的计算 通常被合并到一步里 你实际上要实现的是 dz1=W2 的转置乘上dz2 然后再用它的每个元素与 g1'(z1)的每个元素相乘 然后检查一下维度就行了 对吧？ 如果你有一个像这样的神经网络 输出y 如果你有n0个输入的特征 这里nx=n0 n1个隐藏单元 和n2 这种情况下的n2 只是一个输出单元 然后W2矩阵的大小就是n2*n1 z2和dz2的大小就是n2*1 在我们实现二元分类的时候这个的大小其实是1*1 z1还有 dz1就是n1*1维的 对吧？ 注意任意的变量foo和dfoo都会有相同的维度 这就是W和dW的维度永远相同的原因 而相似地 对于b和db与z和dz都是一样的 为了确认它们的维度相同 我们有dz1等于W2的转置乘以dz2 这里是与g1'(z1)进行一个单独元素间的乘法 现在与上面的维度匹配一下的话 这里就应该是n1*1 等于W2的转置 我们对这个矩阵进行一下转置 它就会变成n1*n2维的 dz2就是n2*1维的 然后这个 这个东西的维度应该与z1相同 这个也是n1*1维的 这里有个元素间的乘法 现在维数就对了吧？ n1*1维的向量可以通过 n1*n2维的矩阵乘以n2*n1因为它们两个 的乘积是一个n1*1维的矩阵 之后这就变成了 两个n1*1的向量的单独元素间的乘法 这样维度就匹配了 在写反向传播时有一个注意事项 就是如果你确认你的矩阵维度匹配了的话 如果你从头到尾想一想你的矩阵 比如W1 W2 z1 z2 a1 a2等等的维度 然后确认一下 这些矩阵运算结果的维度都可以相互匹配 有时就已经可以消除许多反向传播过程中的bug了 那么 我们现在得到了dz1 最后 总结一下 dW1和db1 也许我们应该把它们写在这 但现在地方不够 我还是把它们写在幻灯片的右边吧 dW1和db1可以用以下公式表示 这个就会等于dz1乘以x的转置 这个等于dz 你也许注意到了这些等式之间的相似之处 其实这是必然的因为x 在这里是a0的角色 所以x的转置就是a0的转置 所以这些方程实际上非常相似 这些给了我们一些关于推导反向传播的理解 我们一共有6个等式 分别是dz2 dW2 db2 dz1 dW1和db1 我现在要把这六个等式给放到下一页 好了 目前为止 我们已经推导出了对于 只有一个训练样本的反向传播算法 但是不足为奇的是 比起一次只能训练一个样本 我们更想要可以向量化多个不同样本的训练模型 回想一下在前向传播中 我们一次处理一个训练样本时 我们有这样的等式 a1=g1(z1) 为了进行向量化 我们取出这些z 然后把它们以列的方式 堆在一起 然后把它命名为大写的Z 然后我们发现通过把这些以列堆叠 之后在用一个大写字母来定义它们 我们就可以直接得到Z1=W1X+b A1=g1(Z1) 对吧？ 我们在这节课中非常仔细地定义符号来确保 把样本以列堆叠成一个矩阵可以把所有这些解决 事实表明如果你仔细研究一下其中的数学 相同的技巧对于反向传播同样适用 因此向量化的等式如下 首先 如果你把这些不同训练样本的dz 以列堆叠成一个矩阵 而且对这个和这个也进行相同操作的话 那么这就是它向量化的实现 然后 这里是 计算dW2的方式 这里有一个1/m因为代价函数J 等于1/m乘以损失函数从i=1到n的和 在计算导数时 我们会加上1/m 就像我们在 计算逻辑回归的权重时那样 这是db2 就是把这里dz的值都加起来乘以1/m 然后dZ1是这么算的 这里与以前一样是一个单独元素间的乘法 只是之前的幻灯片上它是n1*1维的向量 现在它是一个n1*m维的矩阵 这两项都是n1\*m维的 这就是这个星号代表着单独元素间的乘法的原因 最后 这是剩下的两个 它们看起来不太让人吃惊 我希望以上这些给你了一些关于反向传播推导过程的理解 在所有机器学习算法中 我认为反向传播算法的推导 实际上是我见过用到的数学最复杂的推导之一 你需要熟悉线性代数以及 对于矩阵的求导来从最基本的原理开始推导 如果你十分熟悉矩阵微积分的话 根据这个过程你也许可以自己推出这个算法 但是我认为实际上许多看过像视频里这个级别的 推导过程的深度学习的从业人员 已经完全有能力 对这个算法有一个直观的理解并且有效地实现它了 所以如果你特别熟悉微积分的话 看看你是否可以从头开始推导这个算法 它运用了极难的数学 是我见过在所有机器学习算法中很难推导的之一 但是无论如何 如果你要实现这个 你已经有足够的经验去调试并且让它正常工作 最后 我还想在你自己写神经网络之前 与你分享最后一个细节 就是怎样去初始化你的神经网络的权重 事实表明随机初始化你的参数 而不是直接初始为0 对于训练你的神经网络十分重要 在下一个视频中 你将看到原因
