TORCH02-03:Torch的損失函數(shù)與邏輯回歸實(shí)現(xiàn)

本主題主要梳理損失函數(shù),并同時使用損失函數(shù)實(shí)現(xiàn)邏輯回歸。本主題內(nèi)容結(jié)構(gòu):
??1. 邏輯回歸模型;
??2. 邏輯回歸Torch實(shí)現(xiàn);
??3. 損失函數(shù)介紹;


邏輯回歸模型

  • 邏輯回歸與線性回歸是有區(qū)別的,只要用來解決分類的問題,邏輯回歸把從二分類基本模型分析,通過概率的方式來區(qū)分兩個類:
    • 屬于A的概率,屬于B的概率,哪個可能概率大就屬于哪一類。

決策模型

  • 邏輯回歸的決策模型,使用的還是是線性模型:

    • y = xW +b
  • 為了從形式上接近概率,采用了一個概率密度函數(shù)(邏輯分布密度函數(shù))

    • sigmoid(x) = \dfrac{1}{1 + e^{-x}}
  • 從而決策模型為:

    • y = sigmoid(xW +b) = \dfrac{1}{1 + e^{-(xW + b)}}

損失模型

  • 邏輯回歸中,損失函數(shù)是:
    • Loss =\sum\limits_{i \in \text{數(shù)據(jù)集}}y_i\ ln(h(x_i)) +(1-y_i)\ln(1-h(x_i))
      • 上述公式被稱為交叉熵(Cross Entropy)
      • 其中h(x_i)=sigmoid(x_iW + b)= \dfrac{1}{1+e^{-(x_iW + b)}}

邏輯回歸PyTorch實(shí)現(xiàn)

  • 采用PyTorch實(shí)現(xiàn),我們還是使用梯度下降方法實(shí)現(xiàn)。

  • 首先認(rèn)識下?lián)p失函數(shù)的表示。

    • 損失函數(shù)的表達(dá)與決策函數(shù)有關(guān)。
  • 數(shù)據(jù)集:

    • 采用鳶尾花數(shù)據(jù)集

決策函數(shù)的表示

  • 線性函數(shù)在torch中已經(jīng)定義:linear函數(shù);
  • sigmoid函數(shù)在torch中已經(jīng)定義:sigmoid函數(shù);
import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data[0:100])   # 取前面100個數(shù)據(jù)樣本 
y = torch.Tensor(target[0:100]).view(100,1) # 形狀與x線性運(yùn)算后的形狀一樣

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) 
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)
print(y_.shape)
sy_ = torch.sigmoid(y_)
print(sy_.shape, y.shape)
torch.Size([100, 1])
torch.Size([100, 1]) torch.Size([100, 1])

損失函數(shù)的表示

  • 邏輯回歸使用的損失函數(shù)是交叉熵,在Torch中也封裝了一個函數(shù):
    • 其他損失函數(shù)后面專門用一節(jié)作為主題介紹。

binary_cross_entropy函數(shù)

  • 對數(shù)損失函數(shù),沒有做邏輯分布函數(shù)(sigmoid)運(yùn)算
    torch.nn.functional.binary_cross_entropy(input, target, weight=None, size_average=None, reduce=None, reduction='mean')
  • 參數(shù)說明:
    • input:就是計算出來的y_
    • target:就是原來數(shù)據(jù)集中標(biāo)簽y
    • reduction: 損失的計算方式:
      • 均值
      • 求和

binary_cross_entropy_with_logits函數(shù)

  • 自動做邏輯分布函數(shù)(sigmoid函數(shù))運(yùn)算。
    torch.nn.functional.binary_cross_entropy_with_logits(input, target, weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)

損失函數(shù)的例子

import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data[0:100])   # 取前面100個數(shù)據(jù)樣本 
y = torch.Tensor(target[0:100]).view(100, 1) # 形狀與x線性運(yùn)算后的形狀一樣

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) 
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)
sy_ = torch.sigmoid(y_)

loss_mean = torch.nn.functional.binary_cross_entropy_with_logits(y_, y, reduction="mean")    # 多一個運(yùn)算,除以樣本個數(shù)
print(loss_mean)
loss_sum = torch.nn.functional.binary_cross_entropy_with_logits(y_, y, reduction="sum")
print(loss_sum)

# 自己手工做sigmoid運(yùn)算
loss_mean = torch.nn.functional.binary_cross_entropy(sy_, y, reduction="mean")    # 多一個運(yùn)算,除以樣本個數(shù)
print(loss_mean)
loss_sum = torch.nn.functional.binary_cross_entropy(sy_, y, reduction="sum")
print(loss_sum)
tensor(0.3298)
tensor(32.9785)
tensor(0.3298)
tensor(32.9785)

邏輯回歸分類實(shí)現(xiàn)

  • 下面的實(shí)現(xiàn)方法,沒有使用隨機(jī)梯度,實(shí)現(xiàn)的核心關(guān)鍵是:
    1. 迭代梯度計算
    2. 數(shù)據(jù)預(yù)測分類
import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data[50:150])   # 取前面100個數(shù)據(jù)樣本 (前面50與后面的兩個50是可分的,后面兩個50線性可分性差點(diǎn))
y = torch.Tensor(target[0:100]).float().view(100, 1) # 形狀與x線性運(yùn)算后的形狀一樣

w = torch.randn(1, 4)    
b = torch.randn(1)        

w.requires_grad = True   # 可訓(xùn)練(x,y是不需要訓(xùn)練的)
b.requires_grad = True

epoch = 10000
learn_rate = 0.01

for n in range(epoch):
    # forward:決策模型表示
    y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)   # 計算線性輸出
    sy_ = torch.sigmoid(y_)    # 計算邏輯分布運(yùn)算(輸出的值可以作為概率使用)
    # loss:損失函數(shù)表示
    loss_mean = torch.nn.functional.binary_cross_entropy(sy_, y, reduction="mean")
    # backward:計算梯度
    loss_mean.backward()
    
    # 更新梯度
    with torch.autograd.no_grad():   # 關(guān)閉梯度計算跟蹤
        w -= learn_rate * w.grad     # 更新權(quán)重梯度
        w.grad.zero_()     # 清空本次計算的梯度(因?yàn)樘荻仁抢奂佑嬎悖磺蹇站屠奂樱?        b -= learn_rate * b.grad     # 更新偏置項梯度
        b.grad.zero_()   
        # 觀察訓(xùn)練過程中的損失下降,與訓(xùn)練集預(yù)測的準(zhǔn)確性
        if n % 1000 == 0:
            print(F"誤差損失值:{loss_mean:10.6f},", end="")
            sy_[sy_ > 0.5] = 1
            sy_[sy_ <= 0.5] = 0

            correct_rate = (sy_ ==  y).float().mean()     # 邏輯值在Torch不給計算平均值,所以需要轉(zhuǎn)換為float類型
            print(F"\t準(zhǔn)確率為:{correct_rate*100: 8.2f}%")
    
print("訓(xùn)練完畢!")   # 下面輸出的結(jié)果與sklearn與tensorflow訓(xùn)練的結(jié)果一致
誤差損失值:  8.051266,   準(zhǔn)確率為:   50.00%
誤差損失值:  0.370522,   準(zhǔn)確率為:   95.00%
誤差損失值:  0.295042,   準(zhǔn)確率為:   95.00%
誤差損失值:  0.252245,   準(zhǔn)確率為:   95.00%
誤差損失值:  0.224739,   準(zhǔn)確率為:   96.00%
誤差損失值:  0.205526,   準(zhǔn)確率為:   96.00%
誤差損失值:  0.191302,   準(zhǔn)確率為:   96.00%
誤差損失值:  0.180313,   準(zhǔn)確率為:   97.00%
誤差損失值:  0.171543,   準(zhǔn)確率為:   97.00%
誤差損失值:  0.164363,   準(zhǔn)確率為:   97.00%
訓(xùn)練完畢!

損失函數(shù)

  • torch提供的損失函數(shù)有:

    1. binary_cross_entropy
    2. binary_cross_entropy_with_logits
    3. poisson_nll_loss
    4. cosine_embedding_loss
    5. cross_entropy
    6. ctc_loss
    7. hinge_embedding_loss
    8. kl_div
    9. l1_loss
    10. mse_loss
    11. margin_ranking_loss
    12. multilabel_margin_loss
    13. multilabel_soft_margin_loss
    14. multi_margin_loss
    15. nll_loss
    16. smooth_l1_loss
    17. soft_margin_loss
    18. triplet_margin_loss
  • 這些函數(shù)都有標(biāo)準(zhǔn)的數(shù)學(xué)公式,每個函數(shù)的使用方式都一樣,下面直接列出公式:

binary_cross_entropy與binary_cross_entropy_with_logits函數(shù)

  • 這兩個函數(shù)的本質(zhì)是一樣的,區(qū)別在于帶后綴的with_logits函數(shù)對input數(shù)據(jù)多一個sigmoid操作。
    • sigmoid函數(shù)也稱logits函數(shù)。
    • 主要用于二分類,比如典型的邏輯回歸,例子見上面;

poisson_nll_loss函數(shù)

  • 泊松負(fù)對數(shù)似然損失(Poisson negative log likelihood loss)
  • 泊松分布的函數(shù)為:

    • P(x=k)= \dfrac{\lambda ^ {k}}{k!} e ^{- \lambda}
      • \lambda表示單位時間內(nèi)隨機(jī)事件發(fā)生的次數(shù);
      • 泊松分布的期望與方差都為\lambda;
      • k!k的階乘;
  • 泊松分布與二項分布的關(guān)系:

    • 泊松分布是由二項分布推導(dǎo)而來,當(dāng)二項分布的n很大,p很小的時候,泊松分布可以作為二項分布的近似,這時\lambda=np。
  • 函數(shù)定義:

    torch.nn.functional.poisson_nll_loss(input, target, log_input=True, full=False, size_average=None, eps=1e-08, reduce=None, reduction='mean')
  • 參數(shù):

    • log_input:邏輯值,用來設(shè)置是否對輸入做exp指數(shù)運(yùn)算:
      • False:exp^{input} - target * input
      • True:input - target * log(input + eps) :其中eps是無窮小量,用來防止input為0的情況。
    • full:是否添加Stirling近似項
      • target * log(target) - target + 0.5 * log(2 * \pi * target)
  • 損失函數(shù)計算公式:

    • target數(shù)據(jù)服從泊松分布;
    • loss = \sum \limits _{i} ( e^{\bar{y_i}} - y_i * \bar{y_i})
  • 例子代碼

import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data[0:100])   # 取前面100個數(shù)據(jù)樣本 
y = torch.Tensor(target[0:100]).view(100, 1) # 形狀與x線性運(yùn)算后的形狀一樣

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) 
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)
sy_ = torch.sigmoid(y_)

loss = torch.nn.functional.poisson_nll_loss(sy_, y)   # 默認(rèn)均值:比較常采用
print(loss)

# 手工計算的效果(log_input = True)
loss_manual = sy_.exp() - y * sy_
loss_manual = loss_manual.mean()
print(loss_manual)
tensor(1.0067)
tensor(1.0067)

cosine_embedding_loss函數(shù)

  • 用來度量兩個向量是否相似。主要用于半監(jiān)督學(xué)習(xí)與學(xué)習(xí)非線性嵌入。

  • 函數(shù)定義:

    torch.nn.functional.cosine_embedding_loss(
        input1,     # 向量1
        input2,     # 向量2
        target,     # 標(biāo)簽
        margin=0, size_average=None, reduce=None, reduction='mean') → Tensor
  • 計算公式:
    • loss(x,y) = \begin{cases} 1-cos(x_1, x_2)& 如 y =1\\ max(0, cos(x_1, x_2)-margin )&如y=-1 \\ \end{cases}
      • 其中:cos(x_1, x_2)是向量x_1,x_2夾角的余弦。
      • margin的取值范圍[-1, 1]

nll_loss與cross_entropy函數(shù)

  • 負(fù)對數(shù)似然損失函數(shù)。用來做C個類別的分類損失函數(shù)。

  • 實(shí)際上這兩個函數(shù)本質(zhì)是一樣的。

    • cross_entropy多做了log_softmax運(yùn)算
  • 函數(shù)定義:

    torch.nn.functional.nll_loss(input, target, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')
  • 參數(shù)說明:

    • weight是一個1-D的張量(Tensor),張量的長度與類別數(shù)相同,用來加權(quán)每個分類的類別。
    • input:是2-D數(shù)據(jù)(N,C):N表示數(shù)量,C表示分類類別;
    • target:是1-D數(shù)據(jù),長度為N即可。
  • 提示:

    • 因?yàn)槭嵌喾诸悊栴},所以對于輸出的結(jié)果應(yīng)該是one-hot,比如2的one-hot就是[0,0,1,0,0,0],假設(shè)最大標(biāo)簽是5。
    • 所以target必須是LongTensor類型的張量。
  • 例子代碼

import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data)   #  (150,4)
y = torch.Tensor(target).long()   # (150)

w = torch.randn(3, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(3)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)
sy_ = y_.log_softmax(dim=1)
# print(sy_.shape)

loss = torch.nn.functional.nll_loss(y_, y)   # 默認(rèn)均值:比較常采用
print(loss)
loss = torch.nn.functional.nll_loss(sy_, y)   #
print(loss)

# cross_entropy交叉熵函數(shù)(多運(yùn)算了一個sigmoid運(yùn)算)
loss_mamual = torch.nn.functional.cross_entropy(y_, y)     # nll_loss就是cross_entrop編碼,自動采用softmax的one-hotb
print(loss_mamual)

tensor(-9.1227)
tensor(7.1684)
tensor(7.1684)

cross_entropy的補(bǔ)充

  • cross_entropy函數(shù)的計算公式是:

    • loss(x, target) = -log( \dfrac{e ^ {x[target]} }{ \sum \limits _i e ^ {x[i]}} ) = -x[target] + log(\sum \limits _i e ^{x[i]})
  • 下面就是cross_entropy的手工實(shí)現(xiàn)函數(shù):

    • 只使用了一個樣本測試,類別是5個類別。
import torch
import math


data_input = torch.FloatTensor([[1.0, 2.0, 3.0, 4.0, 5.0]])  # 計算的y,

data_target = torch.LongTensor([2])  # 改下標(biāo)不能超過上面的維數(shù)-1,這是損失函數(shù)的計算過程決定的

loss_out = torch.nn.functional.cross_entropy(data_input,  data_target)
print("輸入的數(shù)據(jù)集:", data_input)
print("輸出的數(shù)據(jù)集:", data_target)
print("cross_entropy函數(shù)輸出的結(jié)果:", loss_out)

# 下面是交叉熵函數(shù)的手工計算過程

result_1 = 0.0

# 計算第一部分:???[????????????]
for row in range(data_input.size()[0]):    # 行循環(huán)(表示樣本與對應(yīng)的標(biāo)簽),這里其實(shí)是1
    result_1 -= data_input[row][data_target[row]]

result_2 = 0.0

# 計算第二部分:∑????[??]
for row in range(data_input.size()[0]):    # 行循環(huán)(表示樣本與對應(yīng)的標(biāo)簽),這里其實(shí)是1
    for col in range(data_input.size()[1]):
        result_2 += math.exp(data_input[row][col])

# 最終的結(jié)果
print("手工計算結(jié)果:", result_1 + math.log(result_2))   #


輸入的數(shù)據(jù)集: tensor([[1., 2., 3., 4., 5.]])
輸出的數(shù)據(jù)集: tensor([2])
cross_entropy函數(shù)輸出的結(jié)果: tensor(2.4519)
手工計算結(jié)果: tensor(2.4519)

nll_loss函數(shù)的補(bǔ)充

  • nll_loss函數(shù)名字叫負(fù)對數(shù)似然函數(shù),實(shí)際上根本沒有做任何對數(shù)運(yùn)算,其計算公式如下:

    • loss(x, target) = x[target]

    • 直接把x當(dāng)成對數(shù)概率,并最終取x[target]作為這個類別的損失,最后的損失就是所有樣本的損失。

  • 注意:

    • 一般nll_loss會與log_softmax一起使用,本質(zhì)也就等于cross_entropy損失函數(shù)。
import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data)   #  (150,4)
y = torch.Tensor(target).long()   # (150)

w = torch.randn(3, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(3)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)
# sy _ = y_.log_softmax(dim=1)
sy_ = y_ 
loss = torch.nn.functional.nll_loss(sy_, y)   
print(loss)

# 手工計算
y_one = torch.nn.functional.one_hot(y).float()    # 做了個單熱編碼,方便矩陣運(yùn)算,否則就要取下標(biāo)。
re = sy_ *  y_one
# re = re.log()
re = -re
re =re.sum(dim=1)
print(re.mean())
tensor(0.0533)
tensor(0.0533)

mse_loss損失函數(shù)

  • 最直觀的損失函數(shù):均方差損失,計算公式如下:

    • loss(x, target) = \dfrac{1}{N} \sum \limits _{i \in N} (x_i - target_i) ^ 2
  • 函數(shù)說明:

    torch.nn.functional.mse_loss(input, target, size_average=None, reduce=None, reduction='mean') → Tensor
  • 例子代碼
import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data)   #  (150,4)
y = torch.Tensor(target).view(150,1)   # (150)

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)

loss = torch.nn.functional.mse_loss(y_, y)   
print(loss)

# 手工計算
loss_manual = ((y -y_) ** 2).mean()
print(loss_manual)
tensor(14.2841)
tensor(14.2841)

l1_loss函數(shù)

  • 這個函數(shù)從字面上理解,應(yīng)該是L1范數(shù)度量的距離誤差,與均方差損失函數(shù)屬于同一性質(zhì)的損失函數(shù)。函數(shù)公式為:

    • loss(x, target) = \dfrac{1}{N} \sum \limits _{i \in N} | x_i - target_i |
  • 函數(shù)的定義

    torch.nn.functional.l1_loss(input, target, size_average=None, reduce=None, reduction='mean') → Tensor
  • 使用例子
import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data)   #  (150,4)
y = torch.Tensor(target).view(150, 1) # (150, 1)

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)  
sy_ = y_.sigmoid()    
# sy_ = y_

loss = torch.nn.functional.l1_loss(sy_, y)   # 
print(loss)

# 手工計算
loss_manual = (y - sy_).abs().mean()
print(loss_manual)
tensor(0.6954)
tensor(0.6954)

kl_div函數(shù)

  • The Kullback-Leibler divergence_ Loss.

    • 也稱KL距離,一種不同于幾何距離的度量方式,用來度量兩個概率的差異的距離。

    • ??相對熵(relative entropy),又被稱為Kullback-Leibler散度(Kullback-Leibler divergence)或信息散度(information divergence),是兩個概率分布(probability distribution)間差異的非對稱性度量 。
      - > ??在在信息理論中,相對熵等價于兩個概率分布的信息熵(Shannon entropy)的差值。
      - >??相對熵是一些優(yōu)化算法,例如最大期望算法(Expectation-Maximization algorithm, EM)的損失函數(shù) 。此時參與計算的一個概率分布為真實(shí)分布,另一個為理論(擬合)分布,相對熵表示使用理論分布擬合真實(shí)分布時產(chǎn)生的信息損耗 。

  • 計算公式:

    • 信息熵:H(x) = - \sum \limits _{i=1} ^ N p(x_i) log \ p(x_i)

    • 散度:D_{KL}(p | q) = \sum \limits _{i=1} ^ N p(x_i) (log \ p(x_i) - log \ q(x_i)) = \sum \limits _{i=1} ^ N p(x_i) log \dfrac{p(x_i)}{q(x_i)}

    • Torch中封裝的公式:

      • loss(x, target) = target (log (target) - x):target=0的情況總體看成0,只考慮target為1的情況
      • loss(x, target) = target (- x)
  • 函數(shù)定義

    torch.nn.functional.kl_div(input, target, size_average=None, reduce=None, reduction='mean')
    
  • 參數(shù)說明:

    • reduction參數(shù):batchmean最后的均值使用batch_size,mean使用輸出的個數(shù);
      • 注意batch_size與輸出總數(shù)是有差別的。如果是(N,1)維度,則沒有差別。
  • 例子代碼

import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)

x = torch.Tensor(data[:100])   #  (150,4)
y = torch.Tensor(target[:100]).view(100, 1) # (150, 1)

w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)  
sy_ = y_
loss = torch.nn.functional.kl_div(sy_, y, reduction="batchmean")   
print(loss)

# 手工計算(本質(zhì)與nll_loss函數(shù)一樣:nll_loss支持多類)
loss_manual = - y * (sy_)
print(loss_manual.mean())

tensor(-0.9451)
tensor(-0.9451)

hinge_embedding_loss函數(shù)

  • 用來測試兩個輸入的數(shù)據(jù)是否相似。

    • y的取值為-1或者1
  • 函數(shù)定義

    torch.nn.functional.hinge_embedding_loss(input, target, margin=1.0, size_average=None, reduce=None, reduction='mean') → Tensor
  • 函數(shù)公式:

    • loss(x,y) = \begin{cases} x& 如 y =1\\ max(0, 1 -x )&如y=-1 \\ \end{cases}
  • 例子代碼:

import sklearn
import sklearn.datasets
import torch

data, target = sklearn.datasets.load_iris(return_X_y=True)
target[target == 0] = -1 
x = torch.Tensor(data[:100])   #  (150,4)
y = torch.Tensor(target[:100]).view(100, 1) # (150, 1)
w = torch.randn(1, 4)    # 注意形狀(linear會自動轉(zhuǎn)置) :3表示類別數(shù)據(jù)(輸出的長度)
b = torch.randn(1)        # w,b是可訓(xùn)練的,就是需要求導(dǎo)或者梯度

y_ = torch.nn.functional.linear(input=x, weight=w, bias=b)  
sy_ = y_
# print(y_)
# sy_ = y_.sigmoid()
loss = torch.nn.functional.hinge_embedding_loss(sy_, y, reduction="mean")   # 默認(rèn)均值:比較常采用(多一個sigmoid運(yùn)算)
print(loss)

# 手工計算(本質(zhì)與nll_loss函數(shù)一樣:nll_loss支持多類)
loss_manual[0:50] = 1 - sy_[0:50]
loss_manual[loss_manual< 0] = 0

loss_manual[50:100] = sy_[50:100]
# loss_manual[loss_manual <0] = 0
print(loss_manual.mean())


tensor(0.3959)
tensor(0.3959)

其他損失函數(shù)

  • 其他損失函數(shù)是基于多分類與其他目的的變種函數(shù),這些損失函數(shù)在特定的需求理解會更加容易。
    • 比如:soft_margin_loss是基于SVM的軟距離提出的一種損失優(yōu)化方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容