- 什麼是EMA(ExponentialMovingAverage)
在採用 SGD 或者其他的一些優化算法 (Adam, Momentum) 訓練神經網絡時,通常會使用一個叫 ExponentialMovingAverage (EMA) 的方法,中文名叫指數滑動平均。 它的意義在於利用滑動平均的參數來提高模型在測試數據上的健壯性。
滑動平均(exponential moving average),或者叫做指數加權平均(exponentially weighted moving average),可以用來估計變量的局部均值,使得變量的更新與一段時間內的歷史取值有關。
滑動平均可以看作是變量的過去一段時間取值的均值,相比對變量直接賦值而言,滑動平均得到的值在圖像上更加平緩光滑,抖動性更小,不會因爲某次的異常取值而使得滑動平均值波動很大
隨機梯度下降,更平滑的更新說明不會偏離最優點很遠;
梯度下降 batch gradient decent,影子變量作用可能不大,因爲梯度下降的方向已經是最優的了,loss 一定減小;
mini-batch gradient decent,可以嘗試滑動平均,因爲mini-batch gradient decent 對參數的更新也存在抖動。
- EMA定義,Pytorch實現
class EMA():
def __init__(self, mu):
self.mu = mu
self.shadow = {}
def register(self, name, val):
self.shadow[name] = val.clone()
def get(self, name):
return self.shadow[name]
def update(self, name, x):
assert name in self.shadow
new_average = (1.0 - self.mu) * x + self.mu * self.shadow[name]
self.shadow[name] = new_average.clone()
- 訓練過程中怎麼用
train時:
1.註冊---拿到model的參數,加入
ema = EMA(0.999)
for name, param in model.named_parameters():
if param.requires_grad:
ema.register(name, param.data)
2.更新--喂batch後,模型更新參數之後,取到model的param,執行param的指數加權平均操作
loss += batch_loss.item()
batch_loss.backward()
optimizer.step()
for name, param in model.named_parameters():
if param.requires_grad:
ema.update(name, param.data)
3.測試時候要把加權的更新去掉,直接去參數的值
backup_params = EMA(0)#注意這裏衰減參數值爲0
for name, param in model.named_parameters():
if param.requires_grad:
backup_params.register(name, param.data)
param.data.copy_(ema.get(name))
其他博客