地址:广东省清远市
电话:0898-08980898
传真:000-000-0000
邮箱:admin@youweb.com
更新时间:2024-09-09 13:01:07
损失函数Loss是衡量模型输出与真实标签之间的差异的。有了损失函数Loss,通过Loss根据一定的策略 来更新模型中的参数使得损失函数Loss逐步降低;这便是优化器optimizer的任务。本节优化器optimizer主要包括3方面内容,分别是(1)什么是优化器,优化器的定义和作用是?(2)Pytorch中提供的优化器optimizer的基本属性是?(3)optimizer的方法是?
图1 机器学习模型训练步骤
了解优化器之前,可以通过机器学习模型训练步骤简略了解一下优化器。在损失函数模块,根据模型输出与真实标签之间的差异得到Loss损失函数;有了Loss,通常采用Pytorch中的 autograd自动梯度求导 得到 模型中每个可学习参数的梯度grad;有了梯度grad,优化器optimizer获取梯度grad,通过一系列优化策略来更新模型参数,该参数就可使得Loss值下降,进而达到模型输出值与真实标签之间的差异减小的目的。
分析
其中,可学习参数指 权值 和 偏置bias;
其次,优化器最主要的2大功能:
(1)管理:指优化器管理哪一部分参数;
(2)更新:优化器当中具有一些优化策略,优化器可采用这些优化策略更新模型中可学习参数的值;这一更新策略,在神经网络中通常都会采用梯度下降法。
解释
那么,什么是梯度下降法?为什么梯度下降法就可以使得Loss降低呢?
<预备知识>
根据图2例(1)中的一元函数曲线,可以看出函数y=4x2在x=2处的导数(变化率/切线斜率)为16;这说明导数是函数在指定坐标轴上的变化率。由于一元函数只有1个自变量,其方向受限。只有在二元函数或三元函数才考虑方向导数。在图2例(2)中“红色线”标注的,发现?z?x是固定y轴,求在x轴方向上的变化率;而?z?y是固定x,求在y轴方向上的变化率。那么,由于方向l是任意的,该红色点应当具有无穷多个方向导数。由此引出梯度概念。所谓梯度,就是在无穷多个方向导数中,其方向为方向导数取得最大的一个向量。
梯度,是1个向量(应当具有方向/模长2个属性)。①其方向是方向导数取得最大的方向;②模长为方向导数的值。简言之,梯度向量的方向使得当前点增长达到最快的方向,模长为增长速度。
采用梯度下降法的原因—Loss损失函数朝着梯度的负方向去变化:由于梯度方向是增长最快的,那么梯度的负方向就是下降最快的。因此,在模型更新参数时,采用“梯度下降法”朝着梯度的负方向去变化,可以使得损失函数Loss逐步降低。
<总结>
Pytorch中优化器optimizer 管理着模型中的可学习参数,并采用梯度下降法 更新着可学习参数的值。
基本属性:
(1)defaults:优化器超参数;用来存储学习率、momentum的值等等;
(2)state:参数的缓存,如momentum的缓存;采用momentum时会使用前几次更新时使用的梯度,也就是前几次的梯度,把前几次的梯度值缓存下来,在本次更新中使用;
(3)param_groups:管理的参数组;优化器最重要的属性,已经知道优化器是管理可学习参数,这一系列可学习参数就放在param_groups这一属性中,同时,这一参数组定义为list。
param_groups=[{‘params’:param_groups}]
因此,param_groups是1个list。而在list[ ] 中,每一个元素又是1个字典{ } ,这些字典中有很多key,其中最重要的key是-‘params’,只有’params’当中才会存储训练模型的参数。
(4)_step_count:记录更新次数,学习率调整中使用;比如更新在第100次,就下降学习率,更新到200次,又下降学习率。
已知参数param是1个特殊的张量,张量当中都会有梯度grad。由于Pytorch中张量tensor的梯度grad是不会自动清零的,它会在每一次backward反向传播时采用autograd计算梯度,并把梯度值累加到张量的grad属性中的。
如下图3所示,由于Pytorch中的grad属性不自动清零,因此每计算1次梯度就自动累加到grad属性中造成错误;因此,一定要在使用完梯度后或者进行梯度求导(反向传播)之间通过zero_grad进行清零。
Pytorch中优化器对梯度清零zero_grad()的具体实现
当计算得到Loss,利用Loss进行backward反向传播计算各个参数的梯度之后,采用step()进行一步更新,更新权值参数。step()会采用梯度下降的策略,具体方法有很多种,比如随机梯度下降法、momentum+动量方法、autograd自适应学习率等等一系列优化方法。
add_param_group()添加一组参数到优化器中。已知优化器管理很多参数,这些参数是可以分组;对于不同组的参数,有不同的超参数设置,例如在某一模型中,希望特征提取部分的权值参数的学习率小一点,学习更新慢一点,这时可以把特征提取的参数设置为一组参数,而对于后面全连接层,希望其学习率大一点,学习快一点。这时,可以把整个模型参数设置为两组,一组为特征提取部分的参数,另一部分是全连接层的参数,对这两组设置不同的学习率或超参数,这时就需要用到参数组概念。
这两个方法是一组操作,用于模型断点的续训练。例如训练1个模型需要10天,第5天停电或者意外原因,模型终止了训练。为了再次训练可以从断点开始,可以利用该组操作state_dict()和load_state_dict()保存在第5天模型以及优化器中的信息,在模型训练时会一定间隔如10epoch保存当前状态信息,用来在断点可以恢复训练。
图7 state_dict创建的状态信息文件