web-dev-qa-db-ja.com

Pytorchでは、アクティベーションにL1レギュラーを追加する方法は?

(パイトーチ初心者はこちら)

ReLUからのアクティベーション出力にL1レギュラーを追加したいと思います。より一般的には、ネットワーク内の特定のレイヤーにのみレギュライザーを追加するにはどうすればよいですか?

この投稿は関連している可能性があります: Adding L1/L2 regularization in PyTorch? しかしそれは関連していないか、そうでなければ答えがわかりません:

最適化で適用されるL2レギュラーを参照しますが、これは別のことです。言い換えれば、全体的に望ましい損失が

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

Torch.optim.Adagradに提供されるパラメーターは、クロスエントロピー損失にのみ適用されると思います。または、おそらくネットワーク全体のすべてのパラメーター(重み)に適用されます。ただし、いずれの場合でも、1つのアクティベーション層にレギュラーを適用することは許可されていないようで、L1損失は発生しません。

別の関連トピックはnn.modules.lossで、これにはL1Loss()が含まれます。ドキュメントから、私はまだこれを使用する方法を理解していません。

最後に、このモジュール https://github.com/pytorch/pytorch/blob/master/torch/legacy/nn/L1Penalty.py がありますが、これは目標に最も近いようですが、 「レガシー」と呼ばれます。何故ですか?

14
Bull

これを行う方法は次のとおりです。

  • モジュールのフォワードリターンの最終出力と、L1正則化を適用するレイヤーの出力
  • loss変数は、出力w.r.tのクロスエントロピー損失の合計になります。ターゲットと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

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

@Sasank Chilamkurthy Regularizationは、各レイヤーの出力ではなく、モデルの各レイヤーの重み付けパラメーターである必要があります。以下をご覧ください: 正規化

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