2017-06-20 23 views
7

(pytorch初學者在這裏)在Pytorch中,如何將L1調節器添加到激活?

我想將L1正則化轉換器添加到ReLU的激活輸出中。 更普遍的是,如何將調節器僅添加到網絡中的特定層?

這個帖子可能涉及: Adding L1/L2 regularization in PyTorch? 但是它要麼是沒有關係的,要不然我不明白的答案:

它是指在優化,這是一個不同的事情施加L2正則。 換句話說,如果總體上所需要的損失是

crossentropy + lambda1*L1(layer1) + lambda2*L1(layer2) + ... 

相信供給到torch.optim.Adagrad參數僅被施加到交叉熵損失。或者它可能適用於整個網絡的所有參數(權重)。但無論如何, 似乎不允許將調節器應用於單層激活,並且不提供L1損失。

另一個相關的主題是nn.modules.loss,其中包括L1Loss()。 從文檔中,我還不知道如何使用它。

最後,有這個模塊https://github.com/pytorch/pytorch/blob/master/torch/legacy/nn/L1Penalty.py這似乎最接近目標,但它被稱爲「遺產」。這是爲什麼?

+0

對於相對高層次的解決方案,可以看[鏈接](https://github.com/ncullen93/torchsample)。這給你一個類似keras的界面,用於在pytorch中輕鬆完成許多事情,特別是添加各種正規化器。 –

回答

1

這裏是你如何做到這一點:

  • 在你的模塊的正向回報最終輸出和圖層的輸出要申請L1正規化
  • loss變量將輸出的交叉熵損失的總和WRT目標和L1懲罰。

下面是一個例子代碼

import torch 
from torch.autograd import Variable 
from torch.nn import functional as F 


class MLP(torch.nn.Module): 
    def __init__(self): 
     super(MLP, self).__init__() 
     self.linear1 = torch.nn.Linear(128, 32) 
     self.linear2 = torch.nn.Linear(32, 16) 
     self.linear3 = torch.nn.Linear(16, 2) 

    def forward(self, x): 
     layer1_out = F.relu(self.linear1(x)) 
     layer2_out = F.relu(self.linear2(layer1_out)) 
     out = self.linear3(layer2_out) 
     return out, layer1_out, layer2_out 


def l1_penalty(var): 
    return torch.abs(var).sum() 


def l2_penalty(var): 
    return torch.sqrt(torch.pow(var, 2).sum()) 


batchsize = 4 
lambda1, lambda2 = 0.5, 0.01 

model = MLP() 
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4) 

# usually following code is looped over all batches 
# but let's just do a dummy batch for brevity 

inputs = Variable(torch.rand(batchsize, 128)) 
targets = Variable(torch.ones(batchsize).long()) 

optimizer.zero_grad() 
outputs, layer1_out, layer2_out = model(inputs) 
cross_entropy_loss = F.cross_entropy(outputs, targets) 
l1_regularization = lambda1 * l1_penalty(layer1_out) 
l2_regularization = lambda2 * l2_penalty(layer2_out) 

loss = cross_entropy_loss + l1_regularization + l2_regularization 
loss.backward() 
optimizer.step() 
+0

謝謝我沒有意識到你可以改變核心功能的「簽名」,如forward() – Bull

相關問題