赞
踩
这篇文章主要介绍一些在深度学习模型训练时的一些小技巧。
warmup可以理解为预热、热身的意思,它的思想是一开始以较小的学习率去更新参数,然后逐步提高学习率。
这样的好处是:
# 线性warmup # num_warmup_steps:warmup的步数 # init_lr:预设的学习率 global_step = tf.train.get_or_create_global_step() global_steps_int = tf.cast(global_step, tf.int32) warmup_steps_int = tf.constant(num_warmup_steps, dtype=tf.int32) global_steps_float = tf.cast(global_steps_int, tf.float32) warmup_steps_float = tf.cast(warmup_steps_int, tf.float32) warmup_percent_done = global_steps_float / warmup_steps_float warmup_learning_rate = init_lr * warmup_percent_done is_warmup = tf.cast(global_steps_int < warmup_steps_int, tf.float32) learning_rate = ( (1.0 - is_warmup) * learning_rate + is_warmup * warmup_learning_rate)
为什么需要学习率递减呢?因为当我们的模型在接近最优点的时候,过大的学习率会导致一直在最优点附近动荡,难以找到最优点,甚至可能会逃离,这个时候就需要以较小的学习率才能找到最优点,换另一种说法:这个时候我们的网络已经趋于稳定了,过大的学习率会破坏网络的稳定性。
适用场景:通过上述的理解,当我们的模型在前期loss能够正常下降,但在后期难以收敛的情况下,就可以派上用场了。
global_step = tf.train.get_or_create_global_step()
# learning_rate:初设的学习率
# num_train_steps:总的训练次数
# end_learning_rate:学习率最终降为多少
# power:决定递减的幅度
# cycle:当学习率递减为end_learning_rate时,是否开始新的一轮递减
learning_rate = tf.train.polynomial_decay(
learning_rate,
global_step,
num_train_steps,
end_learning_rate=0.0,
power=1.0,
cycle=False)
根据官方API的解释,递减的公式为:
global_step = min(global_step, decay_steps)
decayed_learning_rate = (learning_rate - end_learning_rate) *
(1 - global_step / decay_steps) ^ (power) +
end_learning_rate
这里的decay_steps就是总的递减步数,一般是训练的总步数即num_train_steps。
看到这里, 相信有人就有疑问了:warmup和学习率递减,这不是自相矛盾吗?
确实,它们两者是完全相反的思路,但是它们有各自不同的适用场景。
并且,在实际情况中,两者是可以结合一起使用的,例如大名鼎鼎的Bert
模型就是这么干的。但是,warmup一般在前10%-20%的训练过程中,所以在前期对学习率影响较大的还是warmup,即专注于warmup,后期则是专注于lr_decar。
这样即可以缓解初设阶段对局部数据的过拟合,也能缓解后期的动荡,提高网络的稳定性,增加模型收敛的可能性
适用场景:当你的梯度很容易出现爆炸的情况下,这个时候就可以考虑使用梯度裁剪了。
# 获取所有待更新参数
tvars = tf.trainable_variables()
# 计算所有参数的梯度
# loss:your loss
grads = tf.gradients(loss, tvars)
# 对梯度进行裁剪
(grads, _) = tf.clip_by_global_norm(grads, clip_norm=1.0)
optimizer = tf.train.GradientDescentOptimizer(0.1)
# 进行梯度下降
train_op = optimizer.apply_gradients(
zip(grads, tvars))
根据官方API的解释,梯度裁剪的公式为:
grads[i] = grads[i] * clip_norm / max(global_norm, clip_norm)
global_norm = sqrt(sum([l2norm(t)**2 for t in grads]))
l2norm(t) = sqrt(sum(t ** 2))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。