(パイトーチ初心者はこちら)
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 がありますが、これは目標に最も近いようですが、 「レガシー」と呼ばれます。何故ですか?
これを行う方法は次のとおりです。
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()
@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()