天天看點

PyTorch學習筆記:nn.CrossEntropyLoss——交叉熵損失PyTorch學習筆記:nn.CrossEntropyLoss——交叉熵損失

PyTorch學習筆記:nn.CrossEntropyLoss——交叉熵損失

功能:建立一個交叉熵損失函數:

l ( x , y ) = L = { l 1 , … , l N } T , l n = − ∑ c = 1 C w c log ⁡ e x n , c ∑ i = 1 C e x n , i ⋅ y n , c l(x,y)=L=\{l_1,\dots,l_N\}^T,l_n=-\sum^C_{c=1}w_c\log\frac{e^{x_{n,c}}}{\sum^C_{i=1}e^{x_{n,i}}}· y_{n,c} l(x,y)=L={l1​,…,lN​}T,ln​=−c=1∑C​wc​log∑i=1C​exn,i​exn,c​​⋅yn,c​

其中 x x x是輸入, y n , c y_{n,c} yn,c​是标簽向量元素(來自經過獨熱編碼後的标簽向量), w w w是類别權重, C C C是類别總數, N N N表示batch size。

輸入:

  • size_average

    reduce

    已被棄用,具體功能由參數

    reduction

    代替
  • weight

    :賦予每個類的權重,指定的權重必須是一維并且長度為 C C C的數組,資料類型必須為

    tensor

    格式
  • ignore_index

    :指定一個被忽略,并且不影響網絡參數更新的目标類别,資料類型必須是整數,即隻能指定一個類别
  • reduction

    :指定損失輸出的形式,有三種選擇:

    none

    |

    mean

    |

    sum

    none

    :損失不做任何處理,直接輸出一個數組;

    mean

    :将得到的損失求平均值再輸出,會輸出一個數;

    sum

    :将得到的損失求和再輸出,會輸出一個數

    注意:如果指定了ignore_index,則首先将ignore_index代表的類别損失删去,在剩下的損失資料裡求均值,是以ignore_index所代表的的類别完全不會影響網絡參數的更新

  • label_smoothing

    :指定計算損失時的平滑量,其中0.0表示不平滑,關于平滑量可參考論文《Rethinking the Inception Architecture for Computer Vision》

注意:

  • 輸入應該包含原始、未經過标準化的預測值,

    CrossEntropyLoss

    函數已經内置

    softmax

    處理
  • 對于輸入張量 x x x,尺寸必須為 ( m i n i b a t c h , C ) (minibatch,C) (minibatch,C)或者 ( m i n i b a t c h , C , d 1 , … , d K ) (minibatch,C,d_1,\dots,d_K) (minibatch,C,d1​,…,dK​),後者對于計算高維輸入時很有用,如計算二維圖像中每個像素點的交叉熵損失,注意: K ≥ 1 K≥1 K≥1
  • 輸入的張量 y y y,尺寸必須為 ( m i n i b a t c h ) (minibatch) (minibatch)或者 ( m i n i b a t c h , d 1 , … , d K ) (minibatch,d_1,\dots,d_K) (minibatch,d1​,…,dK​),與 x x x的尺寸相對應,後者也是用于高維資料的計算
  • 注意 x x x的第二次元尺寸與類别數量一一對應,并且 y y y隻需要輸入物體類别序号即可,無需輸入獨熱編碼(該函數會自動對 y y y做獨熱編碼), y y y裡面資料的大小不能超過 x x x第二次元尺寸的大小減一(減一是因為标簽 y y y是從 0 0 0開始計算)

代碼案例

一般用法

import torch.nn as nn
import torch

x = torch.randn((2, 8))
# 在0-7範圍内,随機生成兩個數,當做标簽
y = torch.randint(0, 8, [2])
ce = nn.CrossEntropyLoss()
out = ce(x, y)
print(x)
print(y)
print(out)
           

輸出

# x
tensor([[ 1.3712,  0.4903, -1.3202,  0.1297, -1.6004, -0.1809, -2.8812, -0.3088],
        [ 0.5855, -0.4926,  0.7647, -0.1717, -1.0418, -0.0381, -0.1307, -0.6390]])
# y
tensor([5, 0])
# 得到的交叉熵損失,預設傳回損失的平均值
tensor(1.9324)
           

參數weight的用法

import torch.nn as nn
import torch

x = torch.randn((2, 2))
y = torch.tensor([0, 1])
# 不添加weight
ce = nn.CrossEntropyLoss(reduction='none')
# 添加weight
ce_w = nn.CrossEntropyLoss(weight=torch.tensor([0.5, 1.5]), reduction='none')
out = ce(x, y)
out_w = ce_w(x, y)
print(x)
print(y)
print(out)
print(out_w)
           

輸出

# x
tensor([[-1.1011,  0.6231],
        [ 0.2384, -0.3223]])
# y
tensor([0, 1])
# 不添加weight時的損失輸出
tensor([1.8883, 1.0123])
# weight定義為[0.5, 1.5]時的損失
# 第一個資料(batch中第一個元素)由于标簽為0
# 是以對應的損失乘以weight中第一個權重
# 第二個資料類似
tensor([0.9441, 1.5184])
           

參數ignore_index的用法

import torch.nn as nn
import torch

x = torch.randn((2, 2))
y = torch.tensor([0, 1])
# 不添加ignore_index
ce = nn.CrossEntropyLoss(reduction='none')
# 添加ignore_index
ce_i = nn.CrossEntropyLoss(ignore_index = 0, reduction='none')
out = ce(x, y)
out_i = ce_i(x, y)
print(x)
print(y)
print(out)
print(out_i)
           

輸出

# x
tensor([[-0.9390, -0.6169],
        [-0.7700,  0.3602]])
# y
tensor([0, 1])
# 不添加ignore_index時的損失輸出
tensor([0.8671, 0.2799])
# ignore_index設定為0,表示忽略類别序号為0的損失
# 這裡第一個資料标簽設定為0,是以第一個損失清零
tensor([0.0000, 0.2799])
           

輸入高維資料時

這裡以對二維的預測圖做損失為例

import torch.nn as nn
import torch
# 這裡表示随機生成batch為1,圖檔尺寸為3*3
# 并且每個點有兩個類别的預測圖
x = torch.randn((1, 2, 3, 3))
# 這裡表示預測圖x對應的标簽y
# 預測圖x每個位置都會對應一個标簽值
# x删去第二次元後的尺寸,就是标簽y的尺寸
y = torch.randint(0, 2, [1, 3, 3])
ce = nn.CrossEntropyLoss(reduction='none')
out = ce(x, y)
print(x)
print(y)
print(out)
           

輸出

# 輸入的高維資料x
tensor([[[[ 0.8859, -2.0889, -0.6026],
          [-1.6448,  0.7807,  0.9609],
          [-0.0646,  0.2204, -0.7471]],

         [[ 0.7075, -0.7013, -0.9280],
          [-0.6913,  2.1507, -0.0758],
          [ 0.2139,  0.8387,  0.3743]]]])
# 對應的标簽,預測圖x長寬為多少,标簽y的長寬就為多少
tensor([[[0, 0, 1],
         [0, 0, 0],
         [1, 0, 1]]])
# 輸出的損失
# 函數會為預測圖x上每個位置都生成一個損失,這裡一共生成3*3個損失(對應長乘寬)
tensor([[[0.6079, 1.6105, 0.8690],
         [1.2794, 1.5964, 0.3035],
         [0.5635, 1.0493, 0.2820]]])
           

官方文檔

nn.CrossEntropyLoss:https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#torch.nn.CrossEntropyLoss

初步完稿于:2022年1月29日

繼續閱讀