梯度检查省了我大量的时间 还帮我多次找出了反向传播代码中的错误 我将介绍怎么用梯度检查来调试代码 并检验你的反向传播代码 你刚刚写的神经网络里有一些参数 从W1,B1,一直到,WL,bL 要实现梯度检查算法 首先要把你的所有参数 重新拼成一个巨大的参数向量θ 你要把W矩阵转化成一个向量 把所有的W矩阵都转化成向量 然后把他们首尾相接拼在一起 成为一个巨大的参数向量θ 之前代价函数J是所有W和b的函数 经过向量转化后它变成了θ的函数 W和b按照同样的顺序转化后 你也可以把dW[1],dB[1]等等参数都转化成 和θ的维度相同的向量dθ 和之前一样,把dW[1]转化成向量 db[1]已经是向量 把所有的dW矩阵转化成向量 记住dW[1]和W[1]的维度相同 db[1]和b[1]的维度相同 经过相同的矩阵转化和向量拼接之后 你就把所有的微分也转化成 一个参数向量dθ dθ和θ的维度一样 现在的问题是 θ是代价函数J的梯度 或者斜率吗? 接下来就是如何编写梯度检查算法 梯度检查(Gradient Checking) 经常缩写成(Grad Check) 现在 代价函数J是θ的函数 现在 代价函数J是θ的函数 也就是说 不管这个参数向量θ的维度是多少 代价函数J都是θ1,θ2,θ3 等参数的函数 实现梯度检查算法时 我们首先要写一个循环 对于每个i,取出θ的每个分量θi 计算θi的近似微分 让我们取双向微分 代价函数J的参数是 θ1,θ2,一直到θi 我们给θi加上一个极小数ε 并保持其他的θ分量不变 因为我们要做双向微分 我们把另一边的代价函数J的参数θi减去ε θ的其他分量不变 然后把两个J相减的结果除以2ε 我们之前讲过 这个结果应该约等于dθi 因为dθi应该是代价函数J 关于θi的偏微分 因为dθi应该是代价函数J 关于θi的偏微分 然后 你要把θ的所有分量θi 都按照这个方法计算一遍 最后 你将得到两个向量 dθ的近似值和dθ dθ的近似值和dθ的维度相同 他们的维度又和θ一样 你要检查这两个向量是否大致相等 得知植物能闻到彼此时一定很惊讶 而是因为相互怀疑所以我们全副武装 那么 怎样定义两个向量是大致相等呢? 那么 怎样定义两个向量是大致相等呢? 我是这么做的 我计算两个向量的欧几里得距离 dθ的近似 减去dθ 并把结果o2标准化 注意这个式子的右上角没有平方符号 它把两个向量的每个分量的差的平方之和再开方 就是欧几里得距离 它把两个向量的每个分量的差的平方之和再开方 就是欧几里得距离 再把结果根据向量的长度标准化 把它除以向量dθ的近似和向量dθ的 欧几里得长度的和 把它除以向量dθ的近似和向量dθ的 欧几里得长度的和 除以这个分母是为了 防止这两个向量太小或太大 除以分母就把这个式子变成了一个比值 在实际中 我取ε为10的负7次方 这样 如果这个式子的结果 小于10的负7次方 那就认为计算正确 它表示你的微分近似是对的 因为(误差)很小 如果该式的结果在10的负5次方的量级的话 我会很仔细地检查一遍 有可能式子也是对的 但我会再三检查这个向量的每个分量 确定没有某个分量很大 如果某个分量很大的话 那么可能你的式子里有错误了 如果左面的式子在10的负3次方的量级的话 我觉得你一定要检查代码 它很可能有错误 它的结果应该远远小于10的负3次方 如果(某个分量)大于10的负3次方 我很担心你的代码有错误 如果(某个分量)大于10的负3次方 我很担心你的代码有错误 你应该仔细检查数据的每个部分 看看是不是有某个i 使得dθi的近似和dθi很不一样 然后继续跟踪调试,看看 你的求导部分可能有错 调试程序之后 最终这个数字应该很小很小 这样你的代码就是正确的 在写神经网络时 我会经常写正向传播和反向传播算法 梯度检查可能返回一个非常大的值 那么我的程序可能有错,赶紧调试,调试,调试 调试之后 如果我的算法通过了梯度检查 返回了一个小值 那么我可以自信地说我的算法是对的 现在你知道梯度检查是怎么回事了 它找出了我写的神经网络中的很多错误 我希望它也会帮到你 在下一段视频中 我将讲一些 实现梯度检查的小窍门 我们来看下一段视频 GTC字幕组翻译