购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3-3 自动微分

反向传导时,会更新每一层的权重,这时就轮到偏微分运算派上用场,所以,深度学习框架的第二项主要功能就是自动微分(Automatic Differentiation)。

图3.9 神经网络权重求解过程

下列程序代码请参考【03_02_自动微分.ipynb】。

(1)变量 y 会对 x 自动微分,代码如下。

变量 x 要参与自动微分,须指定参数requires_grad=True。

设定 y x 的多项式,y.grad_fn可取得 y 的梯度函数。

执行y.backward(),会进行反向传导,即偏微分

通过x.grad可取得梯度,若有多个变量也是如此。

执行结果中 x ^2对 x 自动偏微分,得2 x ,因 x =4,故 x 梯度=8。

(2)下列程序代码可取得自动微分相关的属性值。

执行结果。

(3)来看一个较复杂的例子,以神经网络进行分类时,常使用交叉熵(Cross Entropy)作为损失函数,下图表达Cross Entropy= CE ( y , wx + b )。

图3.10 交叉熵(Cross Entropy)运算图

PyTorch会依据程序,建构运算图(Computational Graph),描述梯度下降时,变量运算的顺序如下所示,先算 x ,再算 z ,最后计算 loss

torch.nn.functional.binary_cross_entropy_with_logits是PyTorch提供的交叉熵函数。

执行结果:

(4)自动微分中, z w b 的函数,而 loss 又是 z 的函数,故只要对 loss 进行反向传导即可。

执行结果中, w b 梯度分别为:

(5)TensorFlow使用常数(Constant)及变量(Variable),而PyTorch自v0.4.0起已弃用Variable,直接使用tensor即可,但网络上依然常见Variable,特此说明,详情请参阅本章参考文献 [1]

上例以torch.ones替代Variable。

(6)模型训练时,会反复执行正向/反向传导,以找到最佳解,因此,梯度下降会执行很多次,这时要注意两件事:

· y.backward执行后,预设会将运算图销毁,y.backward将无法再执行,故要保留运算图,须加参数retain_graph=True。

· 梯度会不断累加,因此,执行y.backward后要重置(Reset)梯度,指令如下:x.grad.zero_()

(7)不重置梯度代码如下:

执行结果:

一次梯度下降=75.0;

二次梯度下降=150.0;

三次梯度下降=225.0。

二次、三次梯度下降应该都是75,结果都累加。

(8)使用x.grad.zero_()梯度重置代码如下。

(9)多个变量梯度下降。

执行结果:z=6*(x^5)=18750。

接着改写【02_02_梯度下降法.ipynb】,将改用PyTorch函数微分。

(1)只更动微分函数:原来是自己手动计算,现改用自动微分。

执行结果:与【02_02_梯度下降法.ipynb】相同。

(2)再将函数改为2 x 4 -3 x 2 +2 x -20。要缩小学习率(0.001),免得错过最小值,同时增大执行周期数(15000)。

执行结果:与【02_02_梯度下降法.ipynb】相同。

最后来操作一个完整范例,使用梯度下降法对线性回归求解,方程式如下,求 w b 的最佳解。

y = wx + b

下列程序代码请参考【03_03_简单线性回归.ipynb】。

(1)载入套件。

(2)定义训练函数:

· 刚开始 w b 初始值均可设为任意值,这里使用正态分布之随机数。

· 定义损失函数= MSE ,公式见11行。

· 依照2-3-3节证明,权重更新公式如下:

新权重=原权重-学习率(learning_rate)×梯度(gradient)

· 权重更新必须“设定不参与梯度下降”才能运算,参见第14~18行。

· 每一训练周期的 w b 、损失函数都存储至数组,以利后续观察,参见第22~24行。要取得 w b 、损失函数的值,可以使用.item()转为常数,也可以使用.detach().numpy()转为NumPy数组,detach作用是将变量脱离梯度下降的控制。

· 记得梯度重置,包括 w b

(3)产生线性随机数据100笔,介于0~50。

(4)执行训练。

执行结果: w =0.942326545715332, b =1.1824959516525269。

(5)执行训练100000次。

执行结果有差异: w =0.8514814972877502, b =4.500218868255615。

(6)以NumPy验证。

执行结果: w =0.8510051491073364, b =4.517198474698629。结果与梯度下降法训练100000次较相近,显示梯度下降法收敛较慢,需要较多执行周期的训练,这与默认的学习率(lr)有关,读者可以调整反复测试。所以说深度学习必须靠试验与经验,才能找到最佳参数值。

(7)训练100次的模型绘图验证。

执行结果:虽然训练次数不足,但回归线也确实在样本点的中线。

(8)NumPy模型绘图验证。

执行结果:回归线在样本点的中线。

(9)损失函数绘图验证。

执行结果:大约在第10个执行周期后就收敛了。

有了PyTorch自动微分的功能,反向传导变得非常简单,若要改用其他损失函数,只须修改一下公式,其他程序代码都照旧就可以了。这一节模型训练的程序架构非常重要,只要熟悉每个环节,后续复杂的模型也可以运用自如。 D0EHYD6n6UUGZ1lbWrsK9Adn+BuABfgpauKLAoh+RSVV7T6Ios2xO4aBt/kzpwgg

点击中间区域
呼出菜单
上一章
目录
下一章
×