【pytorch】Loss functions 損失函數總結

首先我們來看一下nn和nn.functional有什麼區別
nn.functional.xxx是函數接口,而nn.Xxx是nn.functional.xxx的類封裝,並且nn.Xxx都繼承於一個共同祖先nn.Module。這一點導致nn.Xxx除了具有nn.functional.xxx功能之外,內部附帶了nn.Module相關的屬性和方法,例如train(), eval(),load_state_dict, state_dict 等。

nn.functional.xxx 就是直接調用
nn.functional.NLLLoss(nn.functional.log_softmax(data),target)
nn.Xxx 就是先定義,之後用的時候再賦值,如

loss = nn.NLLLoss()
conv = nn.Conv2d(16, C, (3, 3))
m = nn.LogSoftmax(dim=1)
#下面再賦值
output = loss(m(conv(data)), target)

參考:https://zhuanlan.zhihu.com/p/61379965

多分類損失函數

多分類任務用到最多的就是nn.NLLLOSS和nn.CrossEntropyLoss。這兩者的關係實際上是
nn.CrossEntropyLoss = nn.NLLLOSS + LogSoftmax

nn.NLLLoss

網絡的最後一層後有LogSoftmax,就用nn.NLLLoss。也就是我們要先對input用一下log_softmax函數,再作爲nn.NLLLoss的輸入。
如果不想讓網絡的最後一層是log_softmax層的話,就可以採用CrossEntropyLoss完全代替此函數。
NLLLoss就是的計算公式可以這樣表示
loss(input, class) = -input[class] 也就是把這個類對應的像素的值找出來,再取一個負號
對圖像來說,我們現在有C個通道的hxw圖像,然後有一個target,那麼對某一個像素來說,我們的target的值爲幾,則我們就選擇第幾個通道的這個像素位置值的負值。

nn.functional.null_loss

torch.nn.functional.nll_loss(input, target, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘mean’)

  • input 預測值
    一維:(N,C),二維:(N,C,H,W) ,k維:(N,C,d1,d2,...,dk)(N,C,d_1,d_2,...,d_k)
    C是要分類的類別的數量,N是batchsize
    注意input在輸入NLLLoss()之前,需要對input進行log_softmax函數激活,即將input轉換成概率分佈的形式,並且取對數。
  • target 真實值
    一維:(N),二維:(N,H,W),k維:(N,d1,d2,...,dk)(N,d_1,d_2,...,d_k)
    其中每個值都是大於等於0小於等於C-1的,也就代表了屬於哪一類。
    對於二維也就是圖像的多分類問題來說,就表示這個像素點屬於哪一類,這也就是語義分割問題
  • weight (Tensor, optional)
    給每一個類設置一個權重,必須爲大小爲C的tensor。常用於類別不均衡問題。
  • size_average(bool)
    當reduce=True時有效。爲True時,返回的loss爲除以權重之和的平均值;爲False時,返回的各樣本的loss之和。
  • reduce(bool)
    返回值是否爲標量,默認爲True。
  • ignore_index(int)
    忽略某一類別,不計算其loss,其loss會爲0,並且,在採用size_average時,不會計算那一類的loss,除的時候的分母也不會統計那一類的樣本。

特別注意,當帶上權值,reduce = True, size_average = True, 其計算公式爲:
在這裏插入圖片描述

當input爲[[0.6, 0.2, 0.2], [0.4, 1.2, 0.4]],target= [0, 1],

①不加權重
l1 = -0.6 , l2=-1.2 loss=l1+l2=-0.6-1.2=-1.8
②加權重
weight = [0.6, 0.2, 0.2]
l1 = - 0.60.6 = - 0.36
l2 = - 1.2
0.2 = - 0.24
loss = -0.36/(0.6+0.2) + -0.24/(0.6+0.2) = -0.75

例子:

>>> # input is of size N x C = 3 x 5
>>> input = torch.randn(3, 5, requires_grad=True)
>>> # each element in target has to have 0 <= value < C
>>> target = torch.tensor([1, 0, 4])
>>> output = F.nll_loss(F.log_softmax(input), target)
>>> output.backward()

nn.NLLLoss

torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘mean’)

參數和上面的一樣

例子:

>>> # 2D loss example (used, for example, with image inputs)
>>> N, C = 5, 4
>>> loss = nn.NLLLoss()
>>> # input is of size N x C x height x width
>>> data = torch.randn(N, 16, 10, 10)
>>> conv = nn.Conv2d(16, C, (3, 3))
>>> m = nn.LogSoftmax(dim=1)
>>> # each element in target has to have 0 <= value < C
>>> target = torch.empty(N, 8, 8, dtype=torch.long).random_(0, C)
>>> output = loss(m(conv(data)), target)
>>> output.backward()

nn.CrossEntropyLoss

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章