web-dev-qa-db-fra.com

Dans Pytorch, comment ajouter un régularisateur L1 aux activations?

(débutant pytorch ici)

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 message peut être lié: Ajout de la régularisation L1/L2 dans PyTorch? Cependant soit il n'est pas lié, soit je ne comprends pas la réponse:

Il s'agit d'un régularisateur L2 appliqué dans l'optimisation, ce qui est différent. 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 ne s'applique qu'à la perte d'entropie croisée. Ou peut-être est-il appliqué à tous les paramètres (poids) du réseau. Mais en tout 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 (). D'après 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 de l'objectif, mais il s'appelle " héritage". Pourquoi donc?

14
Bull

Voici comment procéder:

  • Dans la sortie finale de retour de votre module et la sortie des couches pour lesquelles vous souhaitez appliquer la régularisation L1
  • loss variable sera la somme de la perte d'entropie croisée de la sortie w.r.t. 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

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)

all_linear1_params = torch.cat([x.view(-1) for x in model.linear1.parameters()])
all_linear2_params = torch.cat([x.view(-1) for x in model.linear2.parameters()])
l1_regularization = lambda1 * torch.norm(all_linear1_params, 1)
l2_regularization = lambda2 * torch.norm(all_linear2_params, 2)

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

La régularisation @Sasank Chilamkurthy doit être le paramètre de pondération de chaque couche du modèle, et non la sortie de chaque couche. veuillez regarder ci-dessous: régularisation

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

batchsize = 4
lambda1, lambda2 = 0.5, 0.01

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

inputs = Variable(torch.Rand(batchsize, 128))
targets = Variable(torch.ones(batchsize).long())
l1_regularization, l2_regularization = torch.tensor(0), torch.tensor(0)

optimizer.zero_grad()
outputs = model(inputs)
cross_entropy_loss = F.cross_entropy(outputs, targets)
for param in model.parameters():
    l1_regularization += torch.norm(param, 1)
    l2_regularization += torch.norm(param, 2)

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