一般來說,監督學習的目標函數由損失函數和正則化項組成。(Objective = Loss + Regularization)
Pytorch中的損失函數一般在訓練模型時候指定。
注意Pytorch中內置的損失函數的參數和tensorflow不同,是y_pred在前,y_true在后,而Tensorflow是y_true在前,y_pred在后。
對于回歸模型,通常使用的內置損失函數是均方損失函數nn.MSELoss 。
對于二分類模型,通常使用的是二元交叉熵損失函數nn.BCELoss (輸入已經是sigmoid激活函數之后的結果) 或者 nn.BCEWithLogitsLoss (輸入尚未經過nn.Sigmoid激活函數) 。
對于多分類模型,一般推薦使用交叉熵損失函數 nn.CrossEntropyLoss。 (y_true需要是一維的,是類別編碼。y_pred未經過nn.Softmax激活。)
此外,如果多分類的y_pred經過了nn.LogSoftmax激活,可以使用nn.NLLLoss損失函數(The negative log likelihood loss)。 這種方法和直接使用nn.CrossEntropyLoss等價。
如果有需要,也可以自定義損失函數,自定義損失函數需要接收兩個張量y_pred,y_true作為輸入參數,并輸出一個標量作為損失函數值。
Pytorch中的正則化項一般通過自定義的方式和損失函數一起添加作為目標函數。
一,內置損失函數
內置的損失函數一般有類的實現和函數的實現兩種形式。
如:nn.BCE 和 F.binary_cross_entropy 都是二元交叉熵損失函數,前者是類的實現形式,后者是函數的實現形式。
實際上類的實現形式通常是調用函數的實現形式并用nn.Module封裝后得到的。
一般我們常用的是類的實現形式。它們封裝在torch.nn模塊下,并且類名以Loss結尾。
常用的一些內置損失函數說明如下。
nn.MSELoss(均方誤差損失,也叫做L2損失,用于回歸)
nn.L1Loss (L1損失,也叫做絕對值誤差損失,用于回歸)
nn.SmoothL1Loss (平滑L1損失,當輸入在-1到1之間時,平滑為L2損失,用于回歸)
nn.BCELoss (二元交叉熵,用于二分類,輸入已經過nn.Sigmoid激活,對不平衡數據集可以用weigths參數調整類別權重)
nn.BCEWithLogitsLoss (二元交叉熵,用于二分類,輸入未經過nn.Sigmoid激活)
nn.CrossEntropyLoss (交叉熵,用于多分類,要求label為稀疏編碼,輸入未經過nn.Softmax激活,對不平衡數據集可以用weigths參數調整類別權重)
nn.NLLLoss (負對數似然損失,用于多分類,要求label為稀疏編碼,輸入經過nn.LogSoftmax激活)
nn.CosineSimilarity(余弦相似度,可用于多分類)
nn.AdaptiveLogSoftmaxWithLoss (一種適合非常多類別且類別分布很不均衡的損失函數,會自適應地將多個小類別合成一個cluster)
更多損失函數的介紹參考如下知乎文章:
《PyTorch的十八個損失函數》
二,自定義L1和L2正則化項
通常認為L1 正則化可以產生稀疏權值矩陣,即產生一個稀疏模型,可以用于特征選擇。
而L2 正則化可以防止模型過擬合(overfitting)。一定程度上,L1也可以防止過擬合。
# L2正則化
def L2Loss(model,alpha):l2_loss = torch.tensor(0.0, requires_grad=True)for name, param in model.named_parameters():if 'bias' not in name: #一般不對偏置項使用正則l2_loss = l2_loss + (0.5 * alpha * torch.sum(torch.pow(param, 2)))return l2_loss# L1正則化
def L1Loss(model,beta):l1_loss = torch.tensor(0.0, requires_grad=True)for name, param in model.named_parameters():if 'bias' not in name:l1_loss = l1_loss + beta * torch.sum(torch.abs(param))return l1_loss# 將L2正則和L1正則添加到FocalLoss損失,一起作為目標函數
def focal_loss_with_regularization(y_pred,y_true):focal = FocalLoss()(y_pred,y_true) l2_loss = L2Loss(model,0.001) #注意設置正則化項系數l1_loss = L1Loss(model,0.001)total_loss = focal + l2_loss + l1_lossreturn total_lossmodel.compile(loss_func =focal_loss_with_regularization,optimizer= torch.optim.Adam(model.parameters(),lr = 0.01),metrics_dict={"accuracy":accuracy})
只寫了部分,具體的參考《20天吃透Pytorch》