1. 程式人生 > >pytorch中的L2和L1正則化,自定義優化器設定等操作

pytorch中的L2和L1正則化,自定義優化器設定等操作

在pytorch中進行L2正則化,最直接的方式可以直接用優化器自帶的weight_decay選項指定權值衰減率,相當於L2正則化中的λ,也就是:

(1)Lreg=||yy^||2+λ||W||2
中的λ。但是有一個問題就是,這個指定的權值衰減是會對網路中的所有引數,包括權值w和偏置b同時進行的,很多時候如果對b進行L2正則化將會導致嚴重的欠擬合1,因此這個時候一般只需要對權值進行正則即可,當然,你可以獲取模型中的所有權值,然後按照定義的方法顯式地進行處理,得到一個正則損失之後在交給優化器優化,這是一個通用的方法。但是其實還有更為簡單的方法,同樣在優化器中提供了。

torch.optim

中包含了很多現成的優化器,包括SGD,Adadelta,Adam,Adagrad,RMSprop等,使用它很簡單,你需要傳入一個可迭代的引數列表(裡面必須都是Variable型別的)進行優化,然後你可以指定一些優化器的引數,如學習率,動量,權值衰減等。例子如:

optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9,weight_decay=1e-5)
optimizer = optim.Adam([var1, var2], lr = 0.0001)

此外,優化器還支援一種稱之為Per-parameter options的操作,就是對每一個引數進行特定的指定,以滿足更為細緻的要求。做法也很簡單,與上面不同的,我們傳入的待優化變數不是一個Variable

而是一個可迭代的字典,字典中必須有params的key,用於指定待優化變數,而其他的key需要匹配優化器本身的引數設定。我們看一下例子:

optim.SGD([
                {'params': model.base.parameters()},
                {'params': model.classifier.parameters(), 'lr': 1e-3}
            ], lr=1e-2, momentum=0.9)

其中,我們可以看到,傳入的list中有兩個字典,每一個都是一個獨立的引數組,其中每一組中都有一個paramskey,用於指定需要訓練的引數,如model.base.parameters()

就是base網路中的所有引數,爾後,也可以在每一組內單獨設定學習率,權值衰減等。如果不顯式地在組內設定,那麼就會繼承優化器的全域性引數,如lr=1e-2,momentum=0.9等,如果組內指定了,那麼全域性的將不會覆蓋掉組內的引數設定。
這樣我們就可以靈活的給每一個子網路設定不同的學習率,權值衰減,momentum了,我們也可以給權值設定權值衰減,而不作用與偏置,如:

weight_p, bias_p = [],[]
for name, p in model.named_parameters():
  if 'bias' in name:
     bias_p += [p]
   else:
     weight_p += [p]
# 這裡的model中每個引數的名字都是系統自動命名的,只要是權值都是帶有weight,偏置都帶有bias,
# 因此可以通過名字判斷屬性,這個和tensorflow不同,tensorflow是可以使用者自己定義名字的,當然也會系統自己定義。
optim.SGC([
          {'params': weight_p, 'weight_decay':1e-5},
          {'params': bias_p, 'weight_decay':0}
          ], lr=1e-2, momentum=0.9)

Reference

  1. Goodfellow I, Bengio Y, Courville A, et al. Deep learning[M]. Cambridge: MIT press, 2016.