在深度学习中,很多我们看着迷糊的东西往往和中学特别是 数学有关,所以学好中学数学很重要;而还有更多我们普通人类学了中学数学还看不懂的东西,那些往往都和高等数学有关,所以再学习好高等数学是多么重要。
梯度下降,求梯度,可能是深度学习中最基础,入门即遇到的一个概念了。如果用纯Python来实现深度学习过程当然不是不可以,不过会过于繁琐和麻烦,对算法要求比较高了。而深度学习框架往往就扮演着这样一个角色,帮助开发者构建图,优化大量底层枯燥操作,内置各种算法,自动求梯度也是其中之一。
各个深度学习框架有各自的类和包。而在PyTorch里,它则提供一个autograd包使其能够根据输入和前向传播过程自动构建计算图,并执行反向传播。比如,我们在创建Tensor的时候,将requires_grad设置为True,那么库就会开始自动追踪在其上的所有操作,这样可以利用链式法则进行梯度传播。而在完成计算后,可以调用.backward来完成所有梯度计算。此Tensor的梯度将累积到.grad属性中。如果不想继续追踪可以调用.detach或者用with torch.no_grad。
说了半天,可能很多朋友还是不明白梯度。的确这个乍一看抽象又玄,云里雾里的。虽然,我们一看那些平面示意图或者3D模型,嗯看懂了,不过一旦回到理论概念和数学知识上就又傻眼了,啥啥啥,唔,说的就是不机智的机智客自己。数学公式的确晦涩严谨,难以让我这样的凡人看懂。不过,说到底核心原理其实是一个微积分的小知识点。函数是可微的,而可微的函数,理论上就可以用解析法来找到最小值。最小值是啥呢,就是导数是0的点。
而梯度其实就是一个为了在神经网络中找到最优参数而用到的偏导数,深度学习中梯度下降就是为了求得最小值。为啥要最小值,是因为神经网络要训练数据,就要确定权重和偏置。最优的权重和偏置往往就是损失函数最小时的参数。所以问题就集中到损失函数上了。而损失函数又过于复杂没法确定,所以就找到了梯度这样的偏导数,它指向的就是各点函数值减少最多的方向。
求梯度就求梯度吧,怎么又要自动求梯度。我们要手工做,正如全部手工用纯Python搭建神经网络,零碎繁杂,实为艰辛。比如一个很基础的调节某个权重的问题,要知道一个神经网络上往往都有很多层,而每个层往往又有很多神经元节点,要调节某一个权重,你不得不先冻结其他节点,一个个来测试,这简直是海量计算,哪怕是计算机也发憷。所以这就要用到梯度。而深度学习框架,恰恰把很多底层琐碎的工作给我们自动完成了。