2017-06-20 22 views
7

(tutaj początkujący pyton)W Pytorch, jak dodać regulator L1 do aktywacji?

Chciałbym dodać regulator L1 do wyjścia aktywacji z ReLU. Bardziej ogólnie, w jaki sposób można dodać regularyzator tylko do określonej warstwy w sieci?

Ten post może być związane z: Adding L1/L2 regularization in PyTorch? Jednak ani nie jest powiązany, albo ja nie rozumiem odpowiedź:

odnosić do regularizer L2 stosowanej w optymalizacji, która jest inna sprawa. Innymi słowy, jeżeli pożądana całkowita strata jest

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

wierzę parametr dostarczany do torch.optim.Adagrad jest stosowany tylko do poprzecznego entropii strat. A może dotyczy wszystkich parametrów (ciężarów) w sieci. Ale w każdym razie nie wydaje się pozwalać na zastosowanie regulatora do pojedynczej warstwy aktywacji, i nie zapewnia utraty L1.

Innym istotnym tematem jest nn.modules.loss, który obejmuje L1Loss(). Z dokumentacji nie rozumiem jeszcze, jak z tego korzystać.

Wreszcie, nie jest to moduł https://github.com/pytorch/pytorch/blob/master/torch/legacy/nn/L1Penalty.py co wydaje się najbliżej bramki, ale to się nazywa „Legacy”. Dlaczego?

+0

rozwiązania stosunkowo wysokim poziomie, można spojrzeć na [LINK] (https://github.com/ncullen93/torchsample). Daje to interfejs podobny do kerasów do robienia wielu rzeczy z łatwością w pytorch, a konkretnie do dodawania różnych regularyzatorów. –

Odpowiedz

1

Oto jak to zrobić:

  • w module do przodu powrócić wyjście ostateczne i wyjście warstw, dla którego chcesz zastosować L1 regularyzacji
  • loss zmienna będzie suma przekroju utraty entropii produkcji Wrt cele i kary L1.

Oto przykładowy kod

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

dziękuję Nie zdawałem sobie sprawy, że możesz zmienić "podpis" funkcji podstawowej, takiej jak forward() – Bull