簡體   English   中英

如何將 L1 正則化添加到 PyTorch NN Model?

[英]How to add L1 Regularization to PyTorch NN Model?

在尋找在 PyTorch 模型中實現 L1 正則化的方法時,我遇到了這個問題,它現在已經 2 歲了,所以我想知道這個主題是否有任何新內容?

我還發現了最近處理丟失的 l1 function 的方法。 但是我不明白如何將它用於基本 NN,如下所示。

class FFNNModel(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim, dropout_rate):
        super(FFNNModel, self).__init__()
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.hidden_dim = hidden_dim
        self.dropout_rate = dropout_rate
        self.drop_layer = nn.Dropout(p=self.dropout_rate)
        self.fully = nn.ModuleList()
        current_dim = input_dim
        for h_dim in hidden_dim:
            self.fully.append(nn.Linear(current_dim, h_dim))
            current_dim = h_dim
        self.fully.append(nn.Linear(current_dim, output_dim))

    def forward(self, x):
        for layer in self.fully[:-1]:
            x = self.drop_layer(F.relu(layer(x)))
        x = F.softmax(self.fully[-1](x), dim=0)
        return x

我希望在訓練之前簡單地把它放好:

model = FFNNModel(30,5,[100,200,300,100],0.2)
regularizer = _Regularizer(model)
regularizer = L1Regularizer(regularizer, lambda_reg=0.1)

out = model(inputs)
loss = criterion(out, target) + regularizer.__add_l1()

有誰知道如何應用這些“即用型”類?

我還沒有運行有問題的代碼,所以如果某些東西不能正常工作,請回復。 通常,我會說您鏈接的代碼不必要地復雜(可能是因為它試圖通用並允許以下所有類型的正則化)。 我想它的使用方式是

model = FFNNModel(30,5,[100,200,300,100],0.2)
regularizer = L1Regularizer(model, lambda_reg=0.1)

接着

out = model(inputs)
loss = criterion(out, target) + regularizer.regularized_all_param(0.)

您可以檢查regularized_all_param是否只會遍歷model 的參數,如果它們的名稱以weight結尾,它將累積它們的絕對值之和。 出於某種原因,緩沖區要手動初始化,這就是我們傳入0.的原因。

確實,如果您希望有效地規范 L1 並且不需要任何花里胡哨,那么類似於您的第一個鏈接的更手動的方法將更具可讀性。 它會像這樣 go

l1_regularization = 0.
for param in model.parameters():
    l1_regularization += param.abs().sum()
loss = criterion(out, target) + l1_regularization

這確實是這兩種方法的核心。 您使用Module.parameters方法迭代所有 model 參數並總結它們的 L1 規范,然后它成為您的損失 function 中的一個術語。 而已。 您鏈接的回購提出了一些花哨的機制來將其抽象出來,但是,從您的問題來看,失敗了:)

您可以使用以下代碼對損失 function 應用 L1 正則化:

loss = loss_fn(outputs, labels)
l1_lambda = 0.001
l1_norm = sum(p.abs().sum() for p in model.parameters())

loss = loss + l1_lambda*l1_norm

資料來源: 使用 PyTorch (8.5.2) 進行深度學習

任何絆倒這個的人的簡單解決方案:

上面鏈接中的Regularizer_類總是存在一些問題,所以我使用常規函數解決了這個問題,還添加了一個正交正則化器:

def l1_regularizer(model, lambda_l1=0.01):
    lossl1 = 0
    for model_param_name, model_param_value in model.named_parameters():
            if model_param_name.endswith('weight'):
                lossl1 += lambda_l1 * model_param_value.abs().sum()
    return lossl1    
        
def orth_regularizer(model, lambda_orth=0.01):
    lossorth = 0
    for model_param_name, model_param_value in model.named_parameters():
            if model_param_name.endswith('weight'):
                param_flat = model_param_value.view(model_param_value.shape[0], -1)
                sym = torch.mm(param_flat, torch.t(param_flat))
                sym -= torch.eye(param_flat.shape[0])
                lossorth += lambda_orth * sym.sum()
    return lossorth  

在訓練期間做:

loss = criterion(outputs, y_data)\
      +l1_regularizer(model, lambda_l1=lambda_l1)\
      +orth_regularizer(model, lambda_orth=lambda_orth)   

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM