• 【pytorch】pytorch-backward()的理解


    pytorch-backword函数的理解

    函数:(tensor.backward(params))

    这个params的维度一定要和tensor的一致,因为tensor如果是一个向量y = [y1,y2,y3],那么传入的params=[a1,a2,a3],这三个值是系数,那么是什么的系数呢?
    假定对x =[ x1,x2]求导,那么我们知道,
    (dy/dx) 为:
    第一列: (dy1/dx1,dy2/dx1,dy3/dx1)
    第二列:(dy1/dx2, dy2/dx2,dy3/dx2)
    从而 (dy/dx)是一个3行2列的矩阵,每一列对应了对x1的导数,每一列也就是(x1)的梯度向量
    而反向计算的时候,并不是返回这个矩阵,而是返回这个矩阵每列的和作为梯度,也就是:(dy1/dx1+dy2/dx1+dy3/dx1) 是y对x1的梯度
    这就好理解了,系数为(params=[a1,a2,a3])就对应了这加和的三项!也就是,对(x1)的梯度实际上是(a1*dy1/dx1+a2*dy2/dx1+a3*dy3/dx1)
    而输出y是标量的时候,就不需要了,默认的就是(1.)

    自己重写backward函数时,要写上一个grad_output参数,这个参数就是上面提到的params

    这个grad_output参数究竟是什么呢?下面作出解释:
    是这样的,假如网络有两层, h = h(x),y = y(h)
    你可以计算(dy/dx),这样,y.backward(),因为(dy/dy=1),那么,backward的参数就可以省略
    如果计算h.backward(),因为你想求的是(dy/dx),(这才是输出对于输入的梯度),那么,计算图中的y = y(h)就没有考虑到
    因为(dy/dx = dy/dh * dh/dx)h.backward()求得是(dh/dx),那么你必须传入之前的梯度(dy/dh)才行,也就是说,h.backward(params=dy/dh)这里面的参数就是(dy/dh)

    这就好理解了,如果我们自己实现了一层,继承自Function,自己实现静态方法forwardbackward时,backward必须有个grad_output参数,这个参数就是计算图中输出对该自定义层的梯度,这样才能求出对输入的梯度。

    另外,假设定义的层计算出的是y,调用的就是y.backward(grad_output),这个里面的参数的维度必须和y是相同的。这也就是为什么前面提到对于输出是多维的,会有个“系数”的原因,这个系数就是后向传播时,该层之前的梯度的累积,这样与本层再累积,才实现了完整的链式法则,最终求出outinput的梯度。

    另外,自定义实现forwardbackward时,两函数的输入输出是有要求的,即forward的输入必须和~的return相对应,如forwardinput有个w参数,那么backwardreturn就必须在对应的位置返回grad_w,因为只有这样,才能够对相应的输入参数梯度下降。

  • 相关阅读:
    java+web+多级文件上传
    Java+web+上传文件夹
    java文件实现文件的上传和下载
    web文件夹上传
    js实现上传文件夹
    云中应用性能管理(APM)的下一步
    Cocoa 静态显示一个对话框
    Gradle 1.12用户指南翻译——第三十三章. PMD 插件
    LeetCode_Minimum Depth of Binary Tree
    Android控件ListView获取item中EditText值
  • 原文地址:https://www.cnblogs.com/duye/p/9913602.html
Copyright © 2020-2023  润新知