背景信息
在混合精度中,使用float16类型来替代float32类型存储数据,从而达到减少内存和提高计算速度的效果。但是由于float16类型要比float32类型表示的范围小很多,所以当某些参数(比如说梯度)在训练过程中变得很小时,就会发生数据下溢的情况。而动态更新网络结构中的LossScale正是为了解决float16类型数据下溢问题的,loss scale的主要思想是在计算loss时,将loss扩大一定的倍数,由于链式法则的存在,梯度也会相应扩大,然后在优化器更新权重时再缩小相应的倍数,从而避免了数据下溢的情况又不影响计算结果;
在MindSpore中,LossScale的使用方法又分动态LossScale和静态LossScale两种,二者具体区别详见静态LossScale和动态LossScale的区别。
1、示例代码段
from mindspore import FixedLossScaleManager
#Define network
net = resnet()
#1) Drop the parameter update if there is an overflow
loss_scale_manager = FixedLossScaleManager()
optim = nn.Momentum(params=net.trainable_params(), learning_rate=0.1, momentum=0.9)
model = Model(net, loss_scale_manager=loss_scale_manager, optimizer=optim)
loss_scale_manager = FixedLossScaleManager(scale_factor=4, scale_window=3000)
net = Model(net, loss, opt, metrics=metrics, loss_scale_manager=loss_scale_manager)
#2) Execute parameter update even if overflow occurs
loss_scale_manager = FixedLossScaleManager(loss_scale = 1024, drop_overflow_update=False)
optim = nn.Momentum(params=net.trainable_params(), learning_rate=0.1, momentum=0.9, loss_scale=loss_scale)
net = Model(net, loss, opt, metrics=metrics, loss_scale_manager=loss_scale_manager)
2、接口详解
loss_scale_manager = FixedLossScaleManager(loss_scale=1024, drop_overflow_update=True)
**接口功能:**定义一个静态LossScale的控制器,指定LossScale的固定值为loss_scale。在程序进行时,不会改变scale的大小,scale的值由入参loss_scale控制,可以由用户指定,若不指定则取默认值。FixedLossScaleManager
中的另一个参数是drop_overflow_update
用来控制发生溢出时是否更新参数。一般情况下loss scale功能不需要和优化器配合使用,但在使用FixedLossScaleManager
时,如果drop_overflow_update
为Flase,那么在优化器中需设置loss_scale
的值,且loss_scale
的值要与FixedLossScaleManager
的相同。
参数详解:
loss_scale:
float数据类型。初始化的LossScale,默认值为128.0;
drop_overflow_update:
bool类型。默认值为Truth;判断当出现数据溢出时是否执行优化器,如果选择True,则在数据溢出时优化器将不会执行。