2017-06-20 1 views
7

(débutant pytorch ici)Dans Pytorch, comment ajouter le régularisateur L1 aux activations?

Je voudrais ajouter le régularisateur L1 à la sortie d'activations d'un ReLU. Plus généralement, comment ajouter un régularisateur uniquement à une couche particulière du réseau?

Ce poste peut être lié: Adding L1/L2 regularization in PyTorch? Toutefois soit il n'est pas lié, ou bien je ne comprends pas la réponse:

Il se réfère à une régularisateur L2 appliquée dans l'optimisation, ce qui est une autre chose. En d'autres termes, si la perte globale souhaitée est

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

Je crois que le paramètre fourni à torch.optim.Adagrad est appliqué uniquement à la perte d'entropie croisée. Ou peut-être qu'il est appliqué à tous les paramètres (poids) à travers le réseau. Mais dans tous les cas il ne semble pas permettre d'appliquer un régularisateur à une seule couche d'activations, et ne fournit pas de perte L1.

Un autre sujet pertinent est nn.modules.loss, qui inclut L1Loss(). Dans la documentation, je ne comprends pas encore comment l'utiliser.

Enfin, il y a ce module https://github.com/pytorch/pytorch/blob/master/torch/legacy/nn/L1Penalty.py qui semble le plus proche du but, mais il s'appelle "legacy". Pourquoi donc?

+0

Pour une solution de niveau relativement élevé, vous pouvez regarder [lien] (https://github.com/ncullen93/torchsample). Cela vous donne une interface keras-like pour faire beaucoup de choses facilement dans pytorch, et en ajoutant spécifiquement divers régularisateurs. –

Répondre

1

Voici comment vous faites ceci: sortie

  • Dans votre finale du module de retour vers l'avant et la sortie de couches pour lesquelles vous souhaitez appliquer la variable régularisation
  • loss L1 sera la somme de la perte de la production croisée d'entropie wrt cibles et pénalités L1.

Voici un exemple de code

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

merci je ne savais pas que vous pouviez changer la "signature" d'une fonction de base comme forward() – Bull