模型训练Tricks——EMA指数移动平均

模型训练Tricks——EMA指数移动平均

一、一句话总结 EMA指数滑动平均(Exponential Moving Average)就是:Copy一份模型所有权重(记为Weights)的备份(记为EMA_weights,影子参数),训练过程中每次更新权重时同时也对EMA_weights进行滑动平均更新,训练阶段结束后用EMA_weights替换模型权重进行预测。

具体地,EMA的超参decay一般设为接近1的数,从而保证每次EMA_weights的更新都很稳定。每batch更新流程为:

Weights=Weights+LR*Grad(模型正常的梯度下降)

EMA_weights=EMA_weights*decay+(1-decay)*Weights (根据新Weight更新EMA_weights)

需要知道训练阶段无关EMA_weights,它只在测试阶段时导入进行预测。

二、如何保存最优EMA_weights?

keras可以通过回调on_epoch_end在每个epoch结束时,将EMA_weights加载至模型并save_weights,计算验证集Metrics从而决定是否保存。(注意要在下一个epoch开始前将模型参数替换为Weights)

三、Pytorch实现

class EMA():
    def __init__(self, model, decay):
        self.model = model
        self.decay = decay
        self.shadow = {}
        self.backup = {}

    def register(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                self.shadow[name] = param.data.clone()

    def update(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.shadow
                new_average = (1.0 - self.decay) * param.data + self.decay * self.shadow[name]
                self.shadow[name] = new_average.clone()

    def apply_shadow(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.shadow
                self.backup[name] = param.data
                param.data = self.shadow[name]

    def restore(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.backup
                param.data = self.backup[name]
        self.backup = {}

# 初始化
ema = EMA(model, 0.999)
ema.register()

# 训练过程中,更新完参数后,同步update shadow weights
def train():
    optimizer.step()
    ema.update()

# eval前,apply shadow weights;eval之后,恢复原来模型的参数
def evaluate():
    ema.apply_shadow()
    # evaluate
    ema.restore()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值