nn.CrossEntropyLoss


nn.CrossEntropyLoss

pytorch中交叉熵計算方式為:

\[H(p,q) = -\sum p(i)logq(i) \]

其中,p為真實值矩陣,q為預測值矩陣
當P使用one-hot embedding時,只有在分類正確時

nn.CrossEntropyLoss()計算包括:
Softmax --> log --> NLLoss

  1. softmax:將數值映射到01之間,故ln后的值為-inf0
  2. 對Softmax的結果取log,將乘法改為加法,減少計算量,同時保持函數的單調性
  3. NLLoss:將log結果中與label對應的值取出,去掉負號求均值。

官方文檔

torch.nn.functional.cross_entropy(input, target, weight=None, size_average=True)

input: [batch_size, num_class]
target: [batch_size]

參數 shape 注釋
input (N,C) C為類別數
target N 0<= targets[i] <= C-1
import torch
import torch.nn as nn
x_input=torch.randn(3,3)#隨機生成輸入 
print('x_input:\n',x_input) 
y_target=torch.tensor([1,2,0])#設置輸出具體值 print('y_target\n',y_target)

#計算輸入softmax,此時可以看到每一行加到一起結果都是1
softmax_func=nn.Softmax(dim=1)
soft_output=softmax_func(x_input)
print('soft_output:\n',soft_output)

#在softmax的基礎上取log
log_output=torch.log(soft_output)
print('log_output:\n',log_output)

#對比softmax與log的結合與nn.LogSoftmaxloss(負對數似然損失)的輸出結果,發現兩者是一致的。
logsoftmax_func=nn.LogSoftmax(dim=1)
logsoftmax_output=logsoftmax_func(x_input)
print('logsoftmax_output:\n',logsoftmax_output)

#pytorch中關於NLLLoss的默認參數配置為:reducetion=True、size_average=True
nllloss_func=nn.NLLLoss()
nlloss_output=nllloss_func(logsoftmax_output,y_target)
print('nlloss_output:\n',nlloss_output)

#將結果與nn.CrossEntropyLoss()結果進行對比
cross_entropyloss=nn.CrossEntropyLoss()
cross_entropyloss_output=crossentropyloss(x_input,y_target)
print('cross_entropyloss_output:\n',crossentropyloss_output)

output:

x_input:
 tensor([[ 2.8883,  0.1760,  1.0774],
        [ 1.1216, -0.0562,  0.0660],
        [-1.3939, -0.0967,  0.5853]])
y_target
 tensor([1, 2, 0])
soft_output:
 tensor([[0.8131, 0.0540, 0.1329],
        [0.6039, 0.1860, 0.2102],
        [0.0841, 0.3076, 0.6083]])
log_output:
 tensor([[-0.2069, -2.9192, -2.0178],
        [-0.5044, -1.6822, -1.5599],
        [-2.4762, -1.1790, -0.4970]])
logsoftmax_output:
 tensor([[-0.2069, -2.9192, -2.0178],
        [-0.5044, -1.6822, -1.5599],
        [-2.4762, -1.1790, -0.4970]])
nlloss_output:
 tensor(2.3185)
cross_entropyloss_output:
 tensor(2.3185)

發現通過nn.CrossEntropyLoss()計算得到的結果與nn.LogSoftmax --> NLLLoss()結果相同。

使用時遇到的問題:

loss_id = self.IDLoss(id_preds, id_targets)
"nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Int'

解決方法:

數據類型轉換

id_targets = id_targets.to(torch.int64)     # TODO: ReID. [matched_anchor], float16 to int

F.cross_entropy只是一個函數,nn.CrossEntropyLoss不僅可以計算還可以進行反向傳播,是網絡的一個層

來源:
https://blog.csdn.net/qq_41683065/article/details/122441927
https://blog.csdn.net/wuliBob/article/details/104119616


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM