1. 程式人生 > >PyTorch中的Loss Fucntion

PyTorch中的Loss Fucntion

       深度學習中的Loss Function有很多,常見的有L1、L2、HingeLoss、CrossEntropy,其最終目的就是計算預測的f(x)f(x) 與真值 yy 之間的差別,而優化器的目的就是minimize這個差值,當loss的值穩定後,便是 f(x)f(x) 的引數WW最優的時候。不同的Loss Function適用場景不同,各個深度學習框架實現大同小異,這裡用PyTorch來對常見的Loss Function進行闡述。這裡先構造一個預測值 y^y^ 和真值 yy

Cross Entropy

Cross Entropy(也就是交叉熵)來自夏農的資訊理論,簡單來說,交叉熵是用來衡量在給定的真實分佈p

kpk下,使用非真實分佈qkqk所指定的策略 f(x)f(x) 消除系統的不確定性所需要付出的努力的大小。交叉熵的越低說明這個策略越好,我們總是minimize交叉熵,因為交叉熵越小,就證明演算法所產生的策略越接近最優策略,也就間接證明我們的演算法所計算出的非真實分佈越接近真實分佈。交叉熵損失函式從資訊理論的角度來說,其實來自於KL散度,只不過最後推導的新式等價於交叉熵的計算公式:

H(p,q)=k=1N(pklogqk)H(p,q)=−∑k=1N(pk∗logqk)

最大似然估計、Negative Log Liklihood(NLL)、KL散度與Cross Entropy其實是等價的,都可以進行互相推導,當然MSE也可以用Cross Entropy進行對到出(詳見Deep Learning Book P132)。

Cross Entropy可以用於分類問題,也可以用於語義分割,對於分類問題,其輸出層通常為Sigmoid或者Softmax,當然也有可能直接輸出加權之後的,而pytorch中與Cross Entropy相關的loss Function包括:

  • CrossEntropyLoss: combines LogSoftMax and NLLLoss in one single class,也就是說我們的網路不需要在最後一層加任何輸出層,該loss Function為我們打包好了;
  • NLLLoss: 也就是negative log likelihood loss,如果需要得到log分佈,則需要在網路的最後一層加上LogSoftmax
  • NLLLoss2d: 二維的negative log likelihood loss,多用於分割問題
  • BCELoss: Binary Cross Entropy,常用於二分類問題,當然也可以用於多分類問題,通常需要在網路的最後一層新增sigmoid進行配合使用,其target也就是yy值需要進行one hot編碼,另外BCELoss還可以用於Multi-label classification
  • BCEWithLogitsLoss: 把Sigmoid layer 和 the BCELoss整合到了一起
  • KLDivLoss: TODO
  • PoissonNLLLoss: TODO

下面就用PyTorch對上面的Loss Function進行說明

CrossEntropyLoss

pytorch中CrossEntropyLoss是通過兩個步驟計算出來的,第一步是計算log softmax,第二步是計算cross entropy(或者說是negative log likehood),CrossEntropyLoss不需要在網路的最後一層新增softmax和log層,直接輸出全連線層即可。而NLLLoss則需要在定義網路的時候在最後一層新增softmax和log層

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.autograd as autograd
import numpy as np

# 預測值f(x) 構造樣本,神經網路輸出層
inputs_tensor = torch.FloatTensor( [
 [10, 2, 1,-2,-3],
 [-1,-6,-0,-3,-5],
 [-5, 4, 8, 2, 1]
 ])

# 真值y
targets_tensor = torch.LongTensor([1,3,2])
# targets_tensor = torch.LongTensor([1])

inputs_variable = autograd.Variable(inputs_tensor, requires_grad=True) 
targets_variable = autograd.Variable(targets_tensor)
print('input tensor(nBatch x nClasses): {}'.format(inputs_tensor.shape))
print('target tensor shape: {}'.format(targets_tensor.shape))
input tensor(nBatch x nClasses): torch.Size([3, 5])
target tensor shape: torch.Size([3])
1
2
3
4
loss = nn.CrossEntropyLoss()
output = loss(inputs_variable, targets_variable)
# output.backward()
print('pytorch 內部實現的CrossEntropyLoss: {}'.format(output))
pytorch 內部實現的CrossEntropyLoss: Variable containing:
 3.7925
[torch.FloatTensor of size 1]

手動計算

1.log softmax

1
2
3
4
5
6
7
8
9
# 手動計算log softmax, 計算結果的值域是[0, 1]
softmax_result = F.softmax(inputs_variable) #.sum() #計算softmax
print(('softmax_result(sum=1):{} \n'.format(softmax_result)))
logsoftmax_result = np.log(softmax_result.data)  # 計算log,以e為底, 計算後所有的值都小於0
print('手動計算 calculate logsoftmax_result:{} \n'.format(logsoftmax_result))

# 直接呼叫F.log_softmax
softmax_result = F.log_softmax(inputs_variable)
print('F.log_softmax calculate logsoftmax_result:{} \n'.format(logsoftmax_result))
softmax_result(sum=1):Variable containing:
 9.9953e-01  3.3531e-04  1.2335e-04  6.1413e-06  2.2593e-06
 2.5782e-01  1.7372e-03  7.0083e-01  3.4892e-02  4.7221e-03
 2.2123e-06  1.7926e-02  9.7875e-01  2.4261e-03  8.9251e-04
[torch.FloatTensor of size 3x5]


手動計算 calculate logsoftmax_result:
-4.6717e-04 -8.0005e+00 -9.0005e+00 -1.2000e+01 -1.3000e+01
-1.3555e+00 -6.3555e+00 -3.5549e-01 -3.3555e+00 -5.3555e+00
-1.3021e+01 -4.0215e+00 -2.1476e-02 -6.0215e+00 -7.0215e+00
[torch.FloatTensor of size 3x5]


F.log_softmax calculate logsoftmax_result:
-4.6717e-04 -8.0005e+00 -9.0005e+00 -1.2000e+01 -1.3000e+01
-1.3555e+00 -6.3555e+00 -3.5549e-01 -3.3555e+00 -5.3555e+00
-1.3021e+01 -4.0215e+00 -2.1476e-02 -6.0215e+00 -7.0215e+00
[torch.FloatTensor of size 3x5]

2.手動計算loss

pytorch中NLLLoss定義如下:

loss(x,class)=x[class]loss(x,class)=−x[class]

這裡為什麼可以這麼寫呢?下面用第三個樣本進行解釋

我們用one-hot編碼後,得到真實分佈概率的值px(orpmodel)px(or pmodel)為(這裡一共有5類):[0,0,1,0,0]

而模型預測的每一類分佈概率,也就是非真實分佈的概率qx(orppred)qx(or ppred)為:[2.5782e-01 1.7372e-03 7.0083e-01 3.4892e-02 4.7221e-03] 注意:概率要求其結果為1,這裡使用的是softmax計算出來的結果,而不是log softmax

那麼根據Cross Entroy(交叉熵): Nk=1(pklogqk)−∑k=1N(pk∗logqk)

或者negative log likehood(最大似然): mi=1log(pmodel(yixi;θ))−∑i=1mlog(pmodel(yi∣xi;θ))

將對應專案相乘即可得到最終的loss結果:

0×log(2.57821001)+0×log(1.73721003)+0×lo

相關推薦

PyTorchLoss Fucntion

       深度學習中的Loss Function有很多,常見的有L1、L2、HingeLoss、CrossEntropy,其最終目的就是計算預測的f(x)f(x) 與真值 yy 之間的差別,而優化器的目的就是minimize這個差值,當loss的值穩定後,便是 f(x)f(x) 的引數WW最優的時候。不同

pytorch網路loss傳播和引數更新理解

相比於2018年,在ICLR2019提交論文中,提及不同框架的論文數量發生了極大變化,網友發現,提及tensorflow的論文數量從2018年的228篇略微提升到了266篇,keras從42提升到56,但是pytorch的數量從87篇提升到了252篇。 TensorFlow: 228--->

Pytorch triplet loss的寫法

triplet loss 在Pytorch中有一個類,已經定義好了triplet loss的criterion, class TripletMarginLoss(Module): class T

PytorchRoI pooling layer的幾種實現

IT function 最好 sta 多維 docs CA ner ffi Faster-RCNN論文中在RoI-Head網絡中,將128個RoI區域對應的feature map進行截取,而後利用RoI pooling層輸出7*7大小的feature map。在pytorc

Pytorch的Batch Normalization操作

from 小數 http 結果 data 特定 -c 作用 run 之前一直和小夥伴探討batch normalization層的實現機理,作用在這裏不談,知乎上有一篇paper在講這個,鏈接 這裏只探究其具體運算過程,我們假設在網絡中間經過某些卷積操作之後的輸出的fea

pytorch的cat、stack、tranpose、permute、unsqeeze

ack () oat 在一起 進行 pytorch port 所有 不變 Cat對數據沿著某一維度進行拼接。cat後數據的總維數不變.比如下面代碼對兩個2維tensor(分別為2*3,1*3)進行拼接,拼接完後變為3*3還是2維的tensor。import torch to

pytorchLinear類weight的形狀問題原始碼探討

import torch from torch import nn m = nn.Linear(20, 30) input = torch.randn(128, 20) output = m(input) print(output.size()) print(m.weight.sha

pytorchrequired_grad和detach的澄清

最近和別人討論,發現了自己以前的認識錯誤的地方。 程式碼中的detach和required_grad的引入是減少了計算量,required_grad=false會計算誤差,不計算wb的梯度(原因在於一個網路如果是ABC層這樣的連線方式,B不求梯度,但是A還是會獲得梯度,這就需要計算B的誤差,

pytorch 的grid_sample和affine_grid

pytorch 中提供了對Tensor進行Crop的方法,可以使用GPU實現。具體函式是torch.nn.functional.affine_grid和torch.nn.functional.grid_sample。前者用於生成二維網格,後者對輸入Tensor按照網格進行雙線性取樣。 grid_sample

「Deep Learning」理解PyTorch的「torchvision.transforms」

QQ Group: 428014259 Sina Weibo:小鋒子Shawn Tencent E-mail:[email protected] http://blog.csdn.net/dgyuanshaofeng/article/details/84076608 閱讀的

Pytorch的VGG怎麼修改最後一層FC

https://discuss.pytorch.org/t/how-to-modify-the-final-fc-layer-based-on-the-torch-model/766/12   That’s because vgg19 doesn’t have a f

[work] pytorch的cat、stack、tranpose、permute、unsqeeze

Cat 對資料沿著某一維度進行拼接。cat後資料的總維數不變. 比如下面程式碼對兩個2維tensor(分別為2*3,1*3)進行拼接,拼接完後變為3*3還是2維的tensor。 import torch torch.manual_seed(1) x = torch.r

pytorch 的view和permute的用法

view相當於numpy中resize()的功能,但是用法可能不太一樣.可以參考:https://blog.csdn.net/york1996/article/details/81949843 view只能用在contiguous的variable上。如果在view之前用了transpose,p

pytorch的上取樣以及各種反操作,求逆操作

import torch.nn.functional as F import torch.nn as nn   F.upsample(input, size=None, scale_factor=None,mode='nearest', align

2018.11.14——pytorch的grad_fn,requires_grad

x.grad_fn x.requires_grad x.data x.grad grad_fn的值可以得知該變數是否是一個計算結果,也就是說該變數是不是一個函式的輸出值。每個變數都有grad_fn 程式碼結果解釋:x不是函式輸出值,輸出:None。a是函式輸出值,而且

pytorch資料載入和處理例項

pytorch中資料載入和處理例項 **A lot of effort in solving any machine learning problem goes in to preparing the data. PyTorch provides many tools to make d

pytorch的contiguous()

呼叫view之前最好先contiguous,也就是x.contiguous().view() 因為view需要tensor的記憶體是整塊的 contiguous:中文意思連續的。view只能用在contiguous的variable上。如果在view之前用了transpose, perm

PyTorch使用預訓練的模型初始化網路的一部分引數(增減網路層,修改某層引數等) 固定引數

在預訓練網路的基礎上,修改部分層得到自己的網路,通常我們需要解決的問題包括: 1. 從預訓練的模型載入引數  2. 對新網路兩部分設定不同的學習率,主要訓練自己新增的層  一. 載入引數的方法:  載入引數可以參考apaszke推薦的做法,即刪除與當前mo

pytorch的 relu、sigmoid、tanh、softplus 函式

 四種基本激勵函式是需要掌握的: 1.relu  線性整流函式(Rectified Linear Unit, ReLU),又稱修正線性單元, 是一種人工神經網路中常用的啟用函式(activation function),通常指代以斜坡函式及其變種為代表的非線性函

[PyTorch]PyTorch模型的參數初始化的幾種方法(轉)

plane alt align frame nor view tps class normal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~本文目錄1. xavier初始化2. kaiming初始化3. 實際使用中看到的初始化3.1 ResN