原文: http://www.voidcn.com/article/p-rtzqgqkz-bpg.html
最近看了下 PyTorch 的損失函數文檔,整理了下自己的理解,重新格式化了公式如下,以便以后查閱。
注意下面的損失函數都是在單個樣本上計算的,粗體表示向量,否則是標量。向量的維度用
nn.L1Loss
nn.SmoothL1Loss
也叫作 Huber Loss,誤差在 (-1,1) 上是平方損失,其他情況是 L1 損失。
nn.MSELoss
平方損失函數
nn.BCELoss
二分類用的交叉熵,TODO
nn.CrossEntropyLoss
交叉熵損失函數
而
nn.NLLLoss
負對數似然損失函數(Negative Log Likelihood)
在前面接上一個 LogSoftMax 層就等價於交叉熵損失了。注意這里的
nn.NLLLoss2d
和上面類似,但是多了幾個維度,一般用在圖片上。
- input, (N, C, H, W)
- target, (N, H, W)
比如用全卷積網絡做 Semantic Segmentation 時,最后圖片的每個點都會預測一個類別標簽。
nn.KLDivLoss
KL 散度,又叫做相對熵,算的是兩個分布之間的距離,越相似則越接近零。
注意這里的
nn.MarginRankingLoss
評價相似度的損失
這里的三個都是標量,y 只能取 1 或者 -1,取 1 時表示 x1 比 x2 要大;反之 x2 要大。參數 margin 表示兩個向量至少要相聚 margin 的大小,否則 loss 非負。默認 margin 取零。
nn.MultiMarginLoss
多分類(multi-class)的 Hinge 損失,
其中
nn.MultiLabelMarginLoss
多類別(multi-class)多分類(multi-classification)的 Hinge 損失,是上面 MultiMarginLoss 在多類別上的拓展。同時限定 p = 1,margin = 1.
這個接口有點坑,是直接從 Torch 那里抄過來的,見 MultiLabelMarginCriterion 的描述。而 Lua 的下標和 Python 不一樣,前者的數組下標是從 1 開始的,所以用 0 表示占位符。有幾個坑需要注意,
- 這里的
x,y 都是大小為N 的向量,如果y 不是向量而是標量,后面的∑j 就沒有了,因此就退化成上面的 MultiMarginLoss. - 限制
y 的大小為N ,是為了處理多標簽中標簽個數不同的情況,用 0 表示占位,該位置和后面的數字都會被認為不是正確的類。如y=[5,3,0,0,4] 那么就會被認為是屬於類別 5 和 3,而 4 因為在零后面,因此會被忽略。 - 上面的公式和說明只是為了和文檔保持一致,其實在調用接口的時候,用的是 -1 做占位符,而 0 是第一個類別。
舉個梨子,
import torch
loss = torch.nn.MultiLabelMarginLoss()
x = torch.autograd.Variable(torch.FloatTensor([[0.1, 0.2, 0.4, 0.8]]))
y = torch.autograd.Variable(torch.LongTensor([[3, 0, -1, 1]]))
print loss(x, y) # will give 0.8500
按照上面的理解,第 3, 0 個是正確的類,1, 2 不是,那么,
*注意這里推導的第二行,我為了簡短,都省略了 max(0, x) 符號。
nn.SoftMarginLoss
多標簽二分類問題,這
nn.MultiLabelSoftMarginLoss
上面的多分類版本,根據最大熵的多標簽 one-versue-all 損失,其中
nn.CosineEmbeddingLoss
余弦相似度的損失,目的是讓兩個向量盡量相近。注意這兩個向量都是有梯度的。
margin 可以取
nn.HingeEmbeddingLoss
不知道做啥用的。另外文檔里寫錯了,
nn.TripleMarginLoss
