1. 程式人生 > >pytorch系列 --11 pytorch loss function: MSELoss BCELoss CrossEntropyLoss及one_hot 格式求 cross_entropy

pytorch系列 --11 pytorch loss function: MSELoss BCELoss CrossEntropyLoss及one_hot 格式求 cross_entropy

本文主要包括:

  1. pytorch 實現的損失函式

pytorch實現的loss function

神經網路主要實現分類以及迴歸預測兩類問題,對於迴歸問題,主要講述均方損失函式,而對於一些迴歸問題,需要根據特殊情況自定義損失函式。對於分類,主要講述二分類交叉熵和多分類交叉熵函式

在講解函式之前,提前說一下:

  1. 所有的loss的基類是Module,所以使用loss的方法是:
# 1. 建立損失函式物件,並指定返回結果,預設為:平均值 以MSE為例
criterion = MSELoss(reduction='...')
# 2.  定義input x, traget y
x = torch.tensor(...) y = torch.tensor(...) # 計算損失函式 loss = criterion(x, y)
  1. 在pytorch 0.4中,引數size_averagereduce已被捨棄,使用reduction引數控制損失函式的輸出行為。
  • reduction (string, optional)
    • ‘none’: 不進行資料降維,輸出為向量
    • ‘elementwise_mean’: 將向量中的數累加求和,然後除以元素數量,返回誤差的平均值
    • ‘sum’: 返回向量的誤差值的和

1. class torch.nn.MSELoss(size_average=None, reduce=None, reduction='elementwise_mean')

計算輸入x和標籤y,n個元素平均平方誤差(mean square error),x和y具有相同的Size

損失函式如下定義:
( x ,

y ) = L = { l 1 , , l N } , l n = ( x n y n ) 2 \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = ( x_n - y_n )^2
如果reduction != ‘none’:
( x , y ) = { mean ( L ) , if    reduction = ’elementwise_mean’ , sum ( L ) , if    reduction = ’sum’ . \ell(x, y) = \begin{cases} \operatorname{mean}(L), & \text{if}\; \text{reduction} = \text{'elementwise\_mean'},\\ \operatorname{sum}(L), & \text{if}\; \text{reduction} = \text{'sum'}. \end{cases}

shape: N 為一批資料的數量

  • input: ( N , ) (N, *) , * 意味著任何數量的附加維度
  • Target: (N,∗), shape與input相同

通過程式碼來看一基本用法,以及reduction引數對返回結果的影響:

import torch

from torch import nn

criterion_none = nn.MSELoss( reduction='none')
criterion_elementwise_mean = nn.MSELoss(reduction='elementwise_mean')
criterion_sum = nn.MSELoss(reduction='sum')

x = torch.randn(3, 2, requires_grad=True)
y = torch.randn(3, 2)

loss_none = criterion_none(x, y)

loss_elementwise_mean = criterion_elementwise_mean(x, y)

loss_sum = criterion_sum(x, y )

print('reduction={}:   {}'.format('none', loss_none.detach().numpy()))
print('reduction={}:   {}'.format('elementwise_mean', loss_elementwise_mean.item()))
print('reduction={}:   {}'.format('sum', loss_sum.item()))

out:

reduction=none:
[[0.02320575 0.30483633]
[0.04768182 0.4319028 ]
[3.11864 7.9872203 ]]
reduction=elementwise_mean: 1.9855811595916748 # 1.9 * 6 = 11.4
reduction=sum: 11.913487434387207

2. 交叉熵損失函式

該部落格講述了交叉熵的定義以及為何使用交叉熵,對交叉熵不是很瞭解的可以看一下:
http://jackon.me/posts/why-use-cross-entropy-error-for-loss-function/
這篇部落格講了如何求交叉熵損失函式的導數,有興趣的可以看一下:
https://zhuanlan.zhihu.com/p/35709485

1. class torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='elementwise_mean')

二分類的交叉熵函式。使用該函式之前先計算Sigmoid值https://pytorch.org/docs/stable/nn.html#torch.nn.Sigmoid
損失函式表示式如下:
( x , y ) = L = { l 1 , , l N } , l n = w n [ y n log x n + ( 1 y n ) log ( 1 x n ) ] , \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_n \left[ y_n \cdot \log x_n + (1 - y_n) \cdot \log (1 - x_n) \right],

如果reduction != ‘none’:
( x , y ) = { mean ( L ) , if    reduction  = ’elementwise_mean’ , sum ( L ) , if    reduction  = ’sum’ . \ell(x, y) = \begin{cases} \operatorname{mean}(L), & \text{if}\; \text{reduction } = \text{'elementwise\_mean'},\\ \operatorname{sum}(L), & \text{if}\; \text{reduction } = \text{'sum'}. \end{cases}

shape: N 為一批資料的數量

  • input: ( N , ) (N, *) , * 意味著任何數量的附加維度
  • Target: (N,∗), shape與input相同

random_:https://pytorch.org/docs/master/tensors.html#torch.Tensor.random_

https://pytorch.org/docs/master/torch.html#in-place-random-sampling

import torch

from torch import nn

m = nn.Sigmoid()
criterion = nn.BCELoss()
x = torch.randn(3, requires_grad=True)
# random_(from=0, to): 按均勻分佈從[from, to -1]內去出離散整數值
# 將y取0或1
y = torch.empty(3).random_(2)
# 在計算前線計算x的sigmoid值
loss = criterion(m(x), y)

print(loss.item())

out:

0.8146645426750183

2. class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='elementwise_mean')

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

在使用該函式前不需要經過softmax計算, target不是one_hot編碼格式

shape: N是一批資料的數量

  • input: (N, C): C是類的數量
    (N,C,d1,d2,…,dK) with K≥2 in the case of K-dimensional loss.
  • Target: (N), 0≤targets[i]≤C−1,為每個樣本的類別。
    (N,d1,d2,…,dK) with K≥2 in the case of K-dimensional loss
    • Output: (N), (N, d1,d2,…,dK)

loss表示式:
loss ( x , c l a s s ) = log ( exp ( x [ c l a s s ] ) j exp ( x [ j ] ) ) = x [ c l a s s ] + log ( j exp ( x [ j ] ) ) \text{loss}(x, class) = -\log\left(\frac{\exp(x[class])}{\sum_j \exp(x[j])}\right) = -x[class] + \log\left(\sum_j \exp(x[j])\right)

import torch

from torch import nn


criterion = nn.CrossEntropyLoss()
x = torch.randn(3, 5, requires_grad=True)
# random_(from=0, to): 按均勻分佈從[from, to -1]內去出離散整數值
# 將y取0或1
y = torch.empty(3, dtype=torch.long).random_(5)
# 在計算前線計算x的sigmoid值
loss = criterion(x, y)

print(loss.item())

out:

1.887318730354309

如果傳給target是one_hot編碼格式呢?

  1. 將target one_hot的編碼格式轉換為每個樣本的類別,再傳給CrossEntropyLoss

程式碼中主要涉及了


import torch

from torch import nn
from torch.nn import functional as F
# 編碼one_hot
def one_hot(y):
    '''
    y: (N)的一維tensor,值為每個樣本的類別
    out: 
        y_onehot: 轉換為one_hot 編碼格式 
    '''
    y = y.view(-1, 1)
    y_onehot = torch.FloatTensor(3, 5)
    
    # In your for loop
    y_onehot.zero_()
    y_onehot.scatter_(1, y, 1)
    return y_onehot


def cross_entropy_one_hot(input_, target):
	# 解碼 
    _, labels = target.max(dim=1)
    # 呼叫cross_entropy
    return F.cross_entropy(input_, labels)

# 呼叫計算loss: loss_1 = cross_entropy_one_hot(x, one_hot(y))

  1. 自己根據CrossEntropyLoss的定義重寫

多類的crossentropy:
[0.1, 0.2, 0.7] (prediction) ------------------ [1.0, 0.0, 0.0] (target)

則損失函式為: - (1.0 * log(0.1) + 0.0 * log(0.2) + 0.0 * log(0.7))


def cross_entropy(input_, target, reduction='elementwise_mean'):
    """ Cross entropy that accepts soft targets
    Args:
         pred: predictions for neural network
         targets: targets, can be soft
         size_average: if false, sum is returned instead of mean

    Examples::

        input = torch.FloatTensor([[1.1, 2.8, 1.3], [1.1, 2.1, 4.8]])
        input = torch.autograd.Variable(out, requires_grad=True)

        target = torch.FloatTensor([[0.05, 0.9, 0.05], [0.05, 0.05, 0.9]])
        target = torch.autograd.Variable(y1)
        loss = cross_entropy(input, target)
        loss.backward()
    """
    logsoftmax = nn.LogSoftmax
            
           

相關推薦

pytorch系列 --11 pytorch loss function MSELoss BCELoss CrossEntropyLossone_hot 格式 cross_entropy

本文主要包括: pytorch 實現的損失函式 pytorch實現的loss function 神經網路主要實現分類以及迴歸預測兩類問題,對於迴歸問題,主要講述均方損失函式,而對於一些迴歸問題,需要根據特殊情況自定義損失函式。對於分類,主要講述二分類交叉熵和多分

pytorch系列12 --pytorch自定義損失函式custom loss function

本文主要內容: nn.Module 和 nn.Functional 區別和聯絡 自定義損失函式 1. 關於nn.Module與nn.Functional的區別: https://discuss.pytorch.org/t/whats-the-differe

pytorch系列 --4 pytorch 0.4改動後Variable和Tensor合併問題data和.detach

本文主要講述pytorch0.4更新後相關的程式碼遷移問題 Tensor和Variable合併 torch.Tensor 和torch.autograd.Variable現在是同一個類。torch.Tensor 能夠像之前的Variable一樣追蹤歷史和反向傳播。Variable仍能

pytorch系列 -- 9 pytorch nn.init 中實現的初始化函式 uniform, normal, const, Xavier, He initialization

本文內容: 1. Xavier 初始化 2. nn.init 中各種初始化函式 3. He 初始化 torch.init https://pytorch.org/docs/stable/nn.html#torch-nn-init 1. 均勻分佈 torch.nn.init.u

TensorFlow系列專題(九)常用RNN網路結構依賴優化問題

歡迎大家關注我們的網站和系列教程:http://panchuang.net/ ,學習更多的機器學習、深度學習的知識! 目錄: 常用的迴圈神經網路結構 多層迴圈神經網路 雙向迴圈神經網路 遞迴神經網路 長期依賴問題及其優化

docker學習筆記(四)docker網路模式映象格式

開發十年,就只剩下這套架構體系了! >>>   

Pytorch loss function函式總結

注意: 很多的loss 函式都有size_average和reduce倆個布林型別的引數。因為一般損失函式都是直接計算batch的資料,因此返回的loss結果都是維度(batch_size, )的向量。 如果 reduce = False,那麼 size_average 引數失

pytorch loss function

值得注意的是,很多的 loss 函式都有 size_average 和 reduce 兩個布林型別的引數,需要解釋一下。因為一般損失函式都是直接計算 batch 的資料,因此返回的 loss 結果都是維度為 (batch_size, ) 的向量。

pytorch系列 ----暫時就叫5的番外吧 nn.Modluenn.Linear 原始碼理解

先看一個列子: import torch from torch import nn m = nn.Linear(20, 30) input = torch.randn(128, 20) output = m(input) output.size() out

faster rcnn pytorch 系列(一)generate_anchors原始碼解析

目錄 首先,新增print,然後直接執行py檔案,生成anchor結果 1.總函式,輸入包括:特徵圖對應於原圖的大小,ratios長寬比,scales放大

pytorch-loss function

nn.LogSoftmax() F.log_softmax() nn.NLLLoss() nn.NLLLoss2d() -----------------reference--------------- 1.http://blog.csdn.net/

Azure運維系列11Azure托管磁盤轉非托管磁盤

雲計算 雲服務 在使用Azure的過程中,在大多數情況下我們都會使用到存儲服務,對於虛擬機來說就是我們的磁盤存儲。Azure對於存儲來說是劃分的非常全面和細致的。 ? ?在我們的磁盤列表中找到需要轉換的托管磁盤。 ? ?單擊右側的導出按鈕。 ? ?在導出磁盤的位置設置URL的過期時間,由於是轉換,不需

pytorch系列6 -- activation_function 啟用函式 relu, leakly_relu, tanh, sigmoid及其優缺點

主要包括: 為什麼需要非線性啟用函式? 常見的啟用函式有哪些? python程式碼視覺化啟用函式線上性迴歸中的變現 pytorch啟用函式的原始碼 為什麼需要非線性的啟用函式呢? 只是將兩個或多個線性網路層疊加,並不能學習一個新的東西,接下來通過簡

pytorch系列 --3 Variable,Tensor 和 Gradient

Variable & Automatic Gradient Calculation Tensor vs Variable graph and gradient 注意,在pytorch0.4中,tensor和pytorch合併了。 https://pytorch.

pytorch系列------2 tensor基礎

pytorch Tensor的基本用法 Tensor的建立 索引,合併,切片 初始化 數學操作 1. Tensor的建立 1) 隨機數字 torch.rand(*sizes, out=None) → Tensor 返回一個張量,包含了從區間

pytorch系列-----1 python class 中 的__call__方法

鑑於pytorch在科學論文領域用的越來越多,想寫一個系列文章,講述pytorch的用法。 要學習pytorch,一個前提是 知道python calss中的__call__和__init__方法. 簡單的說就是: __init__: 類的初始化函式,類似於c++的建構函

pytorch系列8 --self.modules() 和 self.children()的區別

本文主要講述: self.modue和self.children的區別與聯絡 說實話,我真的只想講引數初始化方式,但總感覺在偏離的道路上越走越遠。。。 在看一些pytorch文章講述自定義引數初始化方式時,使用到了self.modules()和self.childr

pytorch系列 ---9的番外, Xavier和kaiming是如何fan_in和fan_out的,_calculate_fan_in_and_fan_out解讀 Conv2d

本文主要藉助程式碼講解Xavier和kaiming是如何藉助_calculate_fan_in_and_fan_out函式來計算當前網路層的fan_in(輸入神經元個數)和fan_out(輸出神經元個數的),先針對Linear和Conv2d兩種。 m_c = nn.Conv2d

運籌系列11google的OR-Tools簡介

1. 介紹 google的開源優化演算法包ortools,支援線性規劃、整數規劃,可以方便的求解Routing、Bin packing、Network flows、Assignment、Scheduling等問題。 官網地址為:https://developers.google.com/