Я пытаюсь добавить штраф L1 к указанному c слою нейронной сети, и у меня есть код ниже (в котором я пытаюсь добавить штраф l1 к первому слою). Если я запускаю его для лямбда = 0 (то есть без штрафа), результат будет очень близок к ожидаемому весу, который равен [10, 12, 2, 11, -0,25]), и если я бегу в течение достаточного количества эпох или уменьшаю размер пакета, его получит его точно так, как показано ниже:
mlp.0.weight
Параметр, содержащий:
тензор ([[9.8657, -11.8305, 2.0242 , 10.8913, -0.1978]], require_grad = True)
Затем, когда я запускаю его для большой лямбды, скажем, 1000, я ожидаю, что эти веса уменьшатся до нуля, поскольку существует большой штраф быть добавленным к потере, которую мы пытаемся минимизировать. Однако происходит обратное, и веса взрываются, как показано ниже (для lam = 1000)
mlp.0.weight
Параметр, содержащий:
тензор ([[- 13,9368, 9,9072, 2,2447, -11,6870, 26,7293]], require_grad = True)
Если бы кто-нибудь мог мне помочь, это было бы здорово. Я новичок в pytorch (но не в идее регуляризации), поэтому я предполагаю, что проблема в моем коде.
Спасибо
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import numpy as np
from sklearn.linear_model import LinearRegression
class TrainDataset(Dataset):
def __init__(self, data):
self.data = data
def __len__(self):
return self.data.shape[0]
def __getitem__(self, ind):
x = self.data[ind][1:]
y = self.data[ind][0]
return x, y
class TestDataset(TrainDataset):
def __getitem__(self, ind):
x = self.data[ind]
return x
torch.manual_seed(94)
x_train = np.random.rand(1000, 5)
y_train = x_train[:, 0] * 10 - x_train[:, 1] * 12 + x_train[:, 2] * 2 + x_train[:, 3] * 11 - x_train[:, 4] * 0.25
y_train = y_train.reshape(1000, 1)
x_train.shape
y_train.shape
train_data = np.concatenate((y_train, x_train), axis=1)
train_set = TrainDataset(train_data)
batch_size = 100
train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True)
class MLP(nn.Module):
def __init__(self):
super(MLP, self).__init__()
self.mlp = nn.Sequential(nn.Linear(5, 1, bias=False))
def forward(self, x_mlp):
out = self.mlp(x_mlp)
return out
device = 'cpu'
model = MLP()
optimizer = torch.optim.SGD(model.parameters(), lr=0.02, momentum=0.82)
criterion = nn.MSELoss()
epochs = 5
lam = 0
model.train()
for epoch in range(epochs):
losses = []
for batch_num, input_data in enumerate(train_loader):
optimizer.zero_grad()
x, y = input_data
x = x.to(device).float()
y = y.reshape(batch_size, 1)
y = y.to(device)
output = model(x)
for name, param in model.named_parameters():
if name == 'mlp.0.weight':
l1_norm = torch.norm(param, 1)
loss = criterion(output, y) + lam * l1_norm
loss.backward()
optimizer.step()
print('\tEpoch %d | Batch %d | Loss %6.2f' % (epoch, batch_num, loss.item()))
for name, param in model.named_parameters():
if param.requires_grad:
print(name)
print(param)