假设我们想对函数y = 2xTx,关于列向量x求导。并对x赋予初值。
在我们计算y 关于x 的梯度之前,我们需要一个地方来存储梯度。 重要的是,我们不会在每次对一个参数求导时都分配新的内存。 因为我们经常会成千上万次地更新相同的参数,每次都分配新的内存可能很快就会将内存耗尽。
我们通过调用反向传播函数来自动计算y
关于x
每个分量的梯度,并打印这些梯度。
默认情况下,会累积梯度,所以在求另一个函数的梯度时要进行清零操作 。
当将清零代码进行注释时,梯度会累加:
当y
不是标量时,向量y
关于向量x
的导数的最自然解释是一个矩阵。 对于高阶和高维的y
和x
,求导的结果可以是一个高阶张量。深度学习中,我们的目的不是计算微分矩阵,而是批量中每个样本单独计算的偏导数之和。
有时,我们希望将某些计算移动到记录的计算图之外。 例如,假设y
是作为x
的函数计算的,而z
则是作为y
和x
的函数计算的。 想象一下,我们想计算z
关于x
的梯度,但由于某种原因,我们希望将y
视为一个常数, 并且只考虑到x
在y
被计算后发挥的作用。
使用自动微分的一个好处是: 即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度。