文章目录
1、负对数似然损失函数
1.1、似然
在解释负对数似然之前,首先要了解什么是似然。似然(likelihood)和概率(probability)有着一定的区别和联系。似然和概率是针对不同内容的估计和近似。概率表达了给定参数 θ \theta θ下样本随机向量 X = x X=x X=x的可能性,而似然表达了给定样本 X = x X=x X=x下参数 θ = θ 1 \theta=\theta_1 θ=θ1(相对于另外的参数取值 θ 2 \theta_2 θ2)为真实值的可能性。用一句话可以总结为:概率是已知参数,推数据。似然是已知数据,推参数。
1.2、似然函数
下面来看一下函数 P ( x ∣ θ ) P(x|\theta) P(x∣θ),输入有两个, x x x表示某一个具体的数据; θ \theta θ表示模型的参数:
-  如果 θ \theta θ是已知确定的, x x x是变量,这个函数叫做概率函数(probability function),它描述对于不同的样本点,其出现的概率是多少。 
-  如果 x x x是已知确定的, θ \theta θ是变量,这个函数叫做似然函数(likelihood function),他描述对于不同的模型参数,出现 x x x这个样本点的概率是多少。 
1.3、极大似然估计
假设有训练集
    
     
      
       
        D
       
      
      
       D
      
     
    D,令
    
     
      
       
        
         D
        
        
         c
        
       
      
      
       D_c
      
     
    Dc表示训练集
    
     
      
       
        D
       
      
      
       D
      
     
    D中第
    
     
      
       
        c
       
      
      
       c
      
     
    c类样本组成的集合,假设这些样本是独立同分布的,则参数
    
     
      
       
        
         θ
        
        
         c
        
       
      
      
       \theta_c
      
     
    θc对于数据集
    
     
      
       
        
         D
        
        
         c
        
       
      
      
       D_c
      
     
    Dc的似然是
 
     
      
       
        
         P
        
        
         (
        
        
         
          D
         
         
          c
         
        
        
         ∣
        
        
         
          θ
         
         
          c
         
        
        
         )
        
        
         =
        
        
         
          ∏
         
         
          
           x
          
          
           ∈
          
          
           
            D
           
           
            c
           
          
         
        
        
         P
        
        
         (
        
        
         x
        
        
         ∣
        
        
         
          θ
         
         
          c
         
        
        
         )
        
       
       
         P(D_c|\theta_c)=\prod_{x \in D_c}P(x|\theta_c) 
       
      
     P(Dc∣θc)=x∈Dc∏P(x∣θc)
 对
    
     
      
       
        
         θ
        
        
         c
        
       
      
      
       \theta_c
      
     
    θc进行极大似然估计(Maximum likelihood estimation,MLE),就是去寻找能最大化似然
    
     
      
       
        P
       
       
        (
       
       
        
         D
        
        
         c
        
       
       
        ∣
       
       
        
         θ
        
        
         c
        
       
       
        )
       
      
      
       P(D_c|\theta_c)
      
     
    P(Dc∣θc)的参数值
    
     
      
       
        
         
          θ
         
         
          c
         
        
        
         ^
        
       
      
      
       \hat{\theta_c}
      
     
    θc^。直观上看,极大似然估计是试图在
    
     
      
       
        
         θ
        
        
         c
        
       
      
      
       \theta_c
      
     
    θc所有可能的取值中,找到一个能使数据出现“可能性”最大的值。
1.4、对数似然
从公式可以看出,似然函数是很多个数相乘的形式。然而很多个数相乘并不容易计算容易造成下溢,一不方便求导,通常对其求对数。使用对数似然(log-likelihood),连乘就可以写成连加的形式:
 
     
      
       
        
         L
        
        
         (
        
        
         
          θ
         
         
          c
         
        
        
         )
        
        
         =
        
        
         l
        
        
         o
        
        
         g
          
        
         P
        
        
         (
        
        
         
          D
         
         
          c
         
        
        
         ∣
        
        
         
          θ
         
         
          c
         
        
        
         )
        
        
         =
        
        
         
          ∑
         
         
          
           x
          
          
           ∈
          
          
           
            D
           
           
            c
           
          
         
        
        
         l
        
        
         o
        
        
         g
          
        
         P
        
        
         (
        
        
         x
        
        
         ∣
        
        
         
          θ
         
         
          c
         
        
        
         )
        
       
       
         L(\theta_c)=log \; P(D_c|\theta_c)=\sum_{x \in D_c}log \; P(x|\theta_c) 
       
      
     L(θc)=logP(Dc∣θc)=x∈Dc∑logP(x∣θc)
1.5、负对数似然
对数似然是对概率分布求对数,概率
    
     
      
       
        P
       
       
        (
       
       
        x
       
       
        )
       
      
      
       P(x)
      
     
    P(x)的值为
    
     
      
       
        [
       
       
        0
       
       
        ,
       
       
        1
       
       
        ]
       
      
      
       [0,1]
      
     
    [0,1]区间,取对数后为
    
     
      
       
        (
       
       
        −
       
       
        ∞
       
       
        ,
       
       
        0
       
       
        ]
       
      
      
       (- \infty ,0]
      
     
    (−∞,0]区间。再在这个前面加个符号,变成
    
     
      
       
        [
       
       
        0
       
       
        ,
       
       
        ∞
       
       
        ]
       
      
      
       [0,\infty]
      
     
    [0,∞]区间,就得到了负对数似然(Negative log-likelihood, NLL):
 
     
      
       
        
         L
        
        
         (
        
        
         
          θ
         
         
          c
         
        
        
         )
        
        
         =
        
        
         −
        
        
         
          ∑
         
         
          
           x
          
          
           ∈
          
          
           
            D
           
           
            c
           
          
         
        
        
         l
        
        
         o
        
        
         g
          
        
         P
        
        
         (
        
        
         x
        
        
         ∣
        
        
         
          θ
         
         
          c
         
        
        
         )
        
       
       
         L(\theta_c)=-\sum_{x \in D_c}log \; P(x|\theta_c) 
       
      
     L(θc)=−x∈Dc∑logP(x∣θc)
 这样就得到了负对数似然函数,我们的目标是要选择合适的参数
    
     
      
       
        θ
       
      
      
       \theta
      
     
    θ使得这个函数的数值最小。
看到有个博客举了一个关于硬币的例子来解释什么是最大似然估计,我在这个加加工一下看看负对数似然是怎么回事。假设有一个形状不规则的硬币,我们不知道它正面朝上的概率是多少,用
    
     
      
       
        θ
       
      
      
       \theta
      
     
    θ表示,为模型的参数。想要求得这个模型参数
    
     
      
       
        θ
       
      
      
       \theta
      
     
    θ是多少合适,就需要数据来进行估计。于是拿这枚硬币抛了10次,得到的数据为:“反正正正正反正正正反”。根据这个实验的结果我们就可以得到负对数似然函数为:
 
     
      
       
        
         L
        
        
         (
        
        
         θ
        
        
         )
        
        
         =
        
        
         −
        
        
         (
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         1
        
        
         −
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         1
        
        
         −
        
        
         θ
        
        
         )
        
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         +
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         1
        
        
         −
        
        
         θ
        
        
         )
        
        
         )
        
        
         =
        
        
         −
        
        
         (
        
        
         3
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         1
        
        
         −
        
        
         θ
        
        
         )
        
        
         +
        
        
         7
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         θ
        
        
         )
        
        
         )
        
       
       
         L(\theta)=-(log(1-\theta)+log(\theta)+log(\theta)+log(\theta)+log(\theta)+log(1-\theta)\\+log(\theta)+log(\theta)+log(\theta)+log(1-\theta))=-(3log(1-\theta)+7log(\theta)) 
       
      
     L(θ)=−(log(1−θ)+log(θ)+log(θ)+log(θ)+log(θ)+log(1−θ)+log(θ)+log(θ)+log(θ)+log(1−θ))=−(3log(1−θ)+7log(θ))
 而我们的目标是使得负对数似然损失函数的值越小越好,我们可以画出损失函数的图像为:
import numpy as np
import matplotlib.pyplot as plt
theta=np.arange(0,1,0.01)
y=-(3*np.log(1-theta)+7*np.log(theta))
plt.plot(x, y, label="NNLLoss")
plt.xlabel("theta")
plt.ylabel("Loss")
plt.legend()
plt.show()

可以看出,在 θ = 0.7 \theta=0.7 θ=0.7时,负对数似然损失函数取得的值最小,至此就求出了是负对数似然损失函数最小的参数取值。(这里正面朝上的概率竟然为0.7,与我们的常识不符呀,有可能是因为抛的次数太少了,或者它确实就是个不规则的硬币哈哈哈,不过都不重要)。
1.6、pytorch中的应用
Pytorch中对应的负对数似然损失函数为:
torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean')
当网络的输出为每个类别的对数概率的时候才可以使用该损失函数,因此可以在网络的最后一层添加一个LogSoftmax层来获得对数概率。
这个损失所使用的标签应该是 [ 0 , C − 1 ] [0, C-1] [0,C−1]范围内的一个类索引,其中C=类的数量。因此不需要使用one-hot编码(使用one-hot编码会错,这个在下面的代码中进行验证)。
当reduction参数设置为none的时候,损失可以描述为:
 
     
      
       
        
         l
        
        
         (
        
        
         x
        
        
         ,
        
        
         y
        
        
         )
        
        
         =
        
        
         L
        
        
         =
        
        
         {
        
        
         
          l
         
         
          1
         
        
        
         ,
        
        
         ⋯
         
        
         ,
        
        
         
          l
         
         
          N
         
        
        
         
          }
         
         
          T
         
        
        
         ,
              
        
         
          l
         
         
          n
         
        
        
         =
        
        
         −
        
        
         
          w
         
         
          
           y
          
          
           n
          
         
        
        
         
          x
         
         
          
           n
          
          
           ,
          
          
           
            y
           
           
            n
           
          
         
          
        
         
          w
         
         
          c
         
        
        
         =
        
        
         w
        
        
         e
        
        
         i
        
        
         g
        
        
         h
        
        
         t
        
        
         [
        
        
         c
        
        
         ]
        
        
         ⋅
        
        
         1
        
        
         {
        
        
         c
        
        
         ≠
        
        
         i
        
        
         g
        
        
         n
        
        
         o
        
        
         r
        
        
         e
        
        
         _
        
        
         i
        
        
         n
        
        
         d
        
        
         e
        
        
         x
        
        
         }
        
       
       
         \mathscr{l}(x,y)=L=\{l_1, \cdots ,l_N\}^T, \; \; \; l_n=-w_{y_n}x_{n,y_n}\;w_c=weight[c] \cdot1 \{c \neq ignore\_index\} 
       
      
     l(x,y)=L={l1,⋯,lN}T,ln=−wynxn,ynwc=weight[c]⋅1{c=ignore_index}
 其中,
    
     
      
       
        x
       
      
      
       x
      
     
    x是输入,
    
     
      
       
        y
       
      
      
       y
      
     
    y是目标,
    
     
      
       
        w
       
      
      
       w
      
     
    w是权重,
    
     
      
       
        N
       
      
      
       N
      
     
    N是批次大小。weight参数如果没有设置的话,默认为1。如果reduction不是none(默认是mean),那么:
 
     
      
       
        
         l
        
        
         (
        
        
         x
        
        
         ,
        
        
         y
        
        
         )
        
        
         =
        
        
         
          {
         
         
          
           
            
             
              
               
                ∑
               
               
                
                 n
                
                
                 =
                
                
                 1
                
               
               
                N
               
              
              
               
                1
               
               
                
                 
                  ∑
                 
                 
                  
                   n
                  
                  
                   =
                  
                  
                   1
                  
                 
                 
                  N
                 
                
                
                 
                  w
                 
                 
                  
                   w
                  
                  
                   
                    y
                   
                   
                    n
                   
                  
                 
                
               
              
              
               
                l
               
               
                n
               
              
              
               ,
              
             
            
           
           
            
             
              
               if 
              
              
               
                r
               
               
                e
               
               
                d
               
               
                u
               
               
                c
               
               
                t
               
               
                i
               
               
                o
               
               
                n
               
              
              
                = ’mean’
              
             
            
           
          
          
           
            
             
              
               
                ∑
               
               
                
                 n
                
                
                 =
                
                
                 1
                
               
               
                N
               
              
              
               
                l
               
               
                n
               
              
              
               ,
              
             
            
           
           
            
             
              
               if 
              
              
               
                r
               
               
                e
               
               
                d
               
               
                u
               
               
                c
               
               
                t
               
               
                i
               
               
                o
               
               
                n
               
              
              
                = ’sum’
              
             
            
           
          
         
        
       
       
         \mathscr{l}(x,y)=\begin{cases} \sum_{n=1}^N \frac{1}{\sum_{n=1}^N w_{w_{yn}}}l_n, & \text{if $reduction$ = 'mean'} \\ \sum_{n=1}^N l_n, & \text{if $reduction$ = 'sum'} \end{cases} 
       
      
     l(x,y)={∑n=1N∑n=1Nwwyn1ln,∑n=1Nln,if reduction = ’mean’if reduction = ’sum’
 下面用一段代码看看torch.nn.NLLLoss如何使用:
import torch
#就是求完softmax后对每一个数求log
logsoftmax=torch.nn.LogSoftmax()
lossFun=torch.nn.NLLLoss()
input=torch.rand(3,5,requires_grad=True)
print(input)
tensor([[0.1805, 0.5916, 0.0331, 0.4528, 0.0881],
        [0.5859, 0.1316, 0.1232, 0.5722, 0.6810],
        [0.8561, 0.3857, 0.6185, 0.5923, 0.4002]])
lsoftmax=logsoftmax(input)
lsoftmax
tensor([[-1.7221, -1.3110, -1.8695, -1.4497, -1.8145],
        [-1.4703, -1.9246, -1.9330, -1.4840, -1.3752],
        [-1.3391, -1.8094, -1.5766, -1.6028, -1.7949]])
#不使用one-hot编码
label=torch.tensor([1,0,4])
loss=lossFun(lsoftmax,label)
loss
tensor(1.5254)
#测试使用one-hot编码
onehot_label=torch.tensor([[0.0,1.0,0.0,0.0,0.0],
                   [1.0,0.0,0.0,0.0,0.0],
                   [0.0,0.0,0.0,0.0,1.0]])
lossFun=torch.nn.NLLLoss()
loss=lossFun(lsoftmax,onehot_label)
loss
RuntimeError: 0D or 1D target tensor expected, multi-target not supported
模型输出在经过LogSoftmax函数后,在经过负对数似然函数的计算过程为:
 
     
      
       
        
         L
        
        
         o
        
        
         s
        
        
         s
        
        
         =
        
        
         −
        
        
         (
        
        
         −
        
        
         1.3110
        
        
         −
        
        
         1.4703
        
        
         −
        
        
         1.7949
        
        
         )
        
        
         /
        
        
         3
        
        
         =
        
        
         1.5254
        
       
       
         Loss=-(-1.3110-1.4703-1.7949)/3=1.5254 
       
      
     Loss=−(−1.3110−1.4703−1.7949)/3=1.5254
 因此在pytorch中,nn.NLLLoss()函数虽然叫负对数似然函数,但是该函数并没有进行对数运算,而须在最后一层的激活函数上使用nn.LogSoftmax()函数,然后nn.NLLLoss()函数只是做了求和取平均再取反的运算。因此在分类问题中要使用nn.NLLLoss(),必须和nn.LogSoftmax()函数一起使用。当然也可以直接使用nn.CrossEntropyLoss()。
在使用nn.NLLLoss()时使用one-hot编码会报错,在使用nn.CrossEntropyLoss()的时候使用one-hot不会报错。
2、交叉熵损失函数
下面看一看交叉熵损失以及如何在Pytorch中使用它。
交叉熵主要是用来判定实际的输出与期望的输出的接近程度。要理解交叉熵,需要先理解以下几个概念。
2.1、信息量
信息是用来消除随机不确定性的东西,也就是说衡量信息量的大小就是看这个信息消除不确定性的程度。
“人会死”,这条信息没有减少不确定性,因为人肯定会死亡的,信息量为0。;“明天会下雨”,我们不知道明天到底会不会下雨,因此明天会下雨的不确定性因素很大,而这句话消除了明天会下雨的不确定性,多以按照定义,这句话的信息量很大。
综上所述:信息量的大小与信息发生的概率成反比。概率越大,信息量越小。概率越小,信息量越大。设某一事件发生的概率是
    
     
      
       
        p
       
       
        (
       
       
        x
       
       
        )
       
      
      
       p(x)
      
     
    p(x),其信息量表示为:
 
     
      
       
        
         I
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         −
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         p
        
        
         (
        
        
         x
        
        
         )
        
        
         )
        
       
       
         I(x)=-log(p(x)) 
       
      
     I(x)=−log(p(x))
2.2、信息熵
信息熵也被成为熵,用来表示所有信息量的期望,即:
 
     
      
       
        
         H
        
        
         (
        
        
         X
        
        
         )
        
        
         =
        
        
         −
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
       
       
         H(X)=-\sum_{i=1}^np(x_i)log(p(x_i)) 
       
      
     H(X)=−i=1∑np(xi)log(p(xi))
 举一个例子,使用明天的天气概率来计算熵:
| 序号 | 事件 | 概率p | 信息量 | 
|---|---|---|---|
| 1 | 晴天 | 0.5 | -log(0.5) | 
| 2 | 雨天 | 0.2 | -log(0.2) | 
| 3 | 多云 | 0.3 | -log(0.3) | 
则熵为:
 
     
      
       
        
         H
        
        
         (
        
        
         X
        
        
         )
        
        
         =
        
        
         −
        
        
         (
        
        
         0.5
        
        
         ∗
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         0.5
        
        
         )
        
        
         +
        
        
         0.2
        
        
         ∗
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         0.2
        
        
         )
        
        
         +
        
        
         0.3
        
        
         ∗
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         0.3
        
        
         )
        
        
         )
        
       
       
         H(X)=-(0.5*log(0.5)+0.2*log(0.2)+0.3*log(0.3)) 
       
      
     H(X)=−(0.5∗log(0.5)+0.2∗log(0.2)+0.3∗log(0.3))
2.3、相对熵(KL散度)
如果对于同一个随机变量X有两个单独的概率分布
    
     
      
       
        P
       
       
        (
       
       
        X
       
       
        )
       
      
      
       P(X)
      
     
    P(X)和
    
     
      
       
        Q
       
       
        (
       
       
        X
       
       
        )
       
      
      
       Q(X)
      
     
    Q(X),其中
    
     
      
       
        Q
       
       
        (
       
       
        X
       
       
        )
       
      
      
       Q(X)
      
     
    Q(X)表示模型所预测的分布,
    
     
      
       
        P
       
       
        (
       
       
        X
       
       
        )
       
      
      
       P(X)
      
     
    P(X)表示样本的真实分布。则KL散度用来衡量这两个概率分布之间的差异。计算公式为:
 
     
      
       
        
         
          D
         
         
          
           K
          
          
           L
          
         
        
        
         (
        
        
         p
        
        
         ∣
        
        
         ∣
        
        
         q
        
        
         )
        
        
         =
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         
          
           p
          
          
           (
          
          
           
            x
           
           
            i
           
          
          
           )
          
         
         
          
           q
          
          
           (
          
          
           
            x
           
           
            i
           
          
          
           )
          
         
        
        
         )
        
       
       
         D_{KL}(p||q)=\sum_{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i)}) 
       
      
     DKL(p∣∣q)=i=1∑np(xi)log(q(xi)p(xi))
 KL散度越小,表示
    
     
      
       
        P
       
       
        (
       
       
        X
       
       
        )
       
      
      
       P(X)
      
     
    P(X)与
    
     
      
       
        Q
       
       
        (
       
       
        X
       
       
        )
       
      
      
       Q(X)
      
     
    Q(X)的分布更加接近,可以通过反复训练
    
     
      
       
        Q
       
       
        (
       
       
        X
       
       
        )
       
      
      
       Q(X)
      
     
    Q(X)的分布逼近
    
     
      
       
        P
       
       
        (
       
       
        X
       
       
        )
       
      
      
       P(X)
      
     
    P(X)。
2.4、交叉熵
将KL散度展开为:
 
     
      
       
        
         
          D
         
         
          
           K
          
          
           L
          
         
        
        
         (
        
        
         p
        
        
         ∣
        
        
         ∣
        
        
         q
        
        
         )
        
        
         =
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         
          
           p
          
          
           (
          
          
           
            x
           
           
            i
           
          
          
           )
          
         
         
          
           q
          
          
           (
          
          
           
            x
           
           
            i
           
          
          
           )
          
         
        
        
         )
        
        
        
         =
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
        
         −
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         q
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
        
        
         =
        
        
         −
        
        
         H
        
        
         (
        
        
         p
        
        
         (
        
        
         x
        
        
         )
        
        
         )
        
        
         +
        
        
         [
        
        
         −
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         q
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
        
         ]
        
       
       
         D_{KL}(p||q)=\sum_{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i)})\\ =\sum_{i=1}^n p(x_i)log(p(x_i))-\sum_{i=1}^n p(x_i)log(q(x_i))\\=-H(p(x))+[-\sum_{i=1}^n p(x_i)log(q(x_i))] 
       
      
     DKL(p∣∣q)=i=1∑np(xi)log(q(xi)p(xi))=i=1∑np(xi)log(p(xi))−i=1∑np(xi)log(q(xi))=−H(p(x))+[−i=1∑np(xi)log(q(xi))]
 其中
    
     
      
       
        H
       
       
        (
       
       
        p
       
       
        (
       
       
        x
       
       
        )
       
       
        )
       
      
      
       H(p(x))
      
     
    H(p(x))表示信息熵,
    
     
      
       
        −
       
       
        
         ∑
        
        
         
          i
         
         
          =
         
         
          1
         
        
        
         n
        
       
       
        p
       
       
        (
       
       
        
         x
        
        
         i
        
       
       
        )
       
       
        l
       
       
        o
       
       
        g
       
       
        (
       
       
        q
       
       
        (
       
       
        
         x
        
        
         i
        
       
       
        )
       
       
        )
       
      
      
       -\sum_{i=1}^n p(x_i)log(q(x_i))
      
     
    −∑i=1np(xi)log(q(xi))代表交叉熵,则KL散度=交叉熵-信息熵
进而得到交叉熵的公式为:
 
     
      
       
        
         H
        
        
         (
        
        
         p
        
        
         ,
        
        
         q
        
        
         )
        
        
         =
        
        
         −
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         p
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         q
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
       
       
         H(p,q)=-\sum_{i=1}^n p(x_i)log(q(x_i)) 
       
      
     H(p,q)=−i=1∑np(xi)log(q(xi))
 而在训练过程中,标签通常采用one-hot编码表示,而样本真实分布的概率
    
     
      
       
        p
       
       
        (
       
       
        
         x
        
        
         i
        
       
       
        )
       
      
      
       p(x_i)
      
     
    p(xi)为1。那么就可以得到交叉熵简化后的公式为:
 
     
      
       
        
         H
        
        
         (
        
        
         p
        
        
         ,
        
        
         q
        
        
         )
        
        
         =
        
        
         −
        
        
         
          ∑
         
         
          
           i
          
          
           =
          
          
           1
          
         
         
          n
         
        
        
         l
        
        
         o
        
        
         g
        
        
         (
        
        
         q
        
        
         (
        
        
         
          x
         
         
          i
         
        
        
         )
        
        
         )
        
       
       
         H(p,q)=-\sum_{i=1}^n log(q(x_i)) 
       
      
     H(p,q)=−i=1∑nlog(q(xi))
 这与上面推导的负对数似然损失函数是一样的哇!!!
2.5、pytorch中的应用
Pytorch中对应的交叉熵损失函数为:
torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)
计算公式为,当reduction设置为none时,表示为
 
     
      
       
        
         l
        
        
         (
        
        
         x
        
        
         ,
        
        
         y
        
        
         )
        
        
         =
        
        
         L
        
        
         =
        
        
         {
        
        
         
          l
         
         
          1
         
        
        
         ,
        
        
         ⋯
         
        
         ,
        
        
         
          l
         
         
          N
         
        
        
         
          }
         
         
          T
         
        
        
         ,
              
        
         
          l
         
         
          n
         
        
        
         =
        
        
         −
        
        
         
          ∑
         
         
          
           c
          
          
           =
          
          
           1
          
         
         
          C
         
        
        
         
          w
         
         
          c
         
        
        
         l
        
        
         o
        
        
         g
        
        
         
          
           e
          
          
           x
          
          
           p
          
          
           (
          
          
           
            x
           
           
            
             n
            
            
             ,
            
            
             c
            
           
          
          
           )
          
         
         
          
           
            ∑
           
           
            
             i
            
            
             =
            
            
             1
            
           
           
            C
           
          
          
           e
          
          
           x
          
          
           p
          
          
           (
          
          
           
            x
           
           
            
             n
            
            
             ,
            
            
             i
            
           
          
          
           )
          
         
        
        
         
          y
         
         
          
           n
          
          
           ,
          
          
           c
          
         
        
       
       
         \mathscr{l}(x,y)=L=\{l_1, \cdots ,l_N\}^T, \; \; \; l_n=-\sum_{c=1}^C w_clog\frac{exp(x_{n,c})}{\sum_{i=1}^Cexp(x_{n,i})}y_{n,c} 
       
      
     l(x,y)=L={l1,⋯,lN}T,ln=−c=1∑Cwclog∑i=1Cexp(xn,i)exp(xn,c)yn,c
 如果reduction不是none(默认是mean),那么:
 
     
      
       
        
         l
        
        
         (
        
        
         x
        
        
         ,
        
        
         y
        
        
         )
        
        
         =
        
        
         
          {
         
         
          
           
            
             
              
               
                
                 
                  ∑
                 
                 
                  
                   n
                  
                  
                   =
                  
                  
                   1
                  
                 
                 
                  N
                 
                
                
                 
                  l
                 
                 
                  n
                 
                
               
               
                N
               
              
              
               ,
              
             
            
           
           
            
             
              
               if 
              
              
               
                r
               
               
                e
               
               
                d
               
               
                u
               
               
                c
               
               
                t
               
               
                i
               
               
                o
               
               
                n
               
              
              
                = ’mean’
              
             
            
           
          
          
           
            
             
              
               
                ∑
               
               
                
                 n
                
                
                 =
                
                
                 1
                
               
               
                N
               
              
              
               
                l
               
               
                n
               
              
              
               ,
              
             
            
           
           
            
             
              
               if 
              
              
               
                r
               
               
                e
               
               
                d
               
               
                u
               
               
                c
               
               
                t
               
               
                i
               
               
                o
               
               
                n
               
              
              
                = ’sum’
              
             
            
           
          
         
        
       
       
         \mathscr{l}(x,y)=\begin{cases} \frac{\sum_{n=1}^Nl_n}{N}, & \text{if $reduction$ = 'mean'} \\ \sum_{n=1}^N l_n, & \text{if $reduction$ = 'sum'} \end{cases} 
       
      
     l(x,y)={N∑n=1Nln,∑n=1Nln,if reduction = ’mean’if reduction = ’sum’
 在使用交叉熵损失函数的时,网络的最后一层不需要加softmax层,因为pytorch中的CrossEntropyLoss帮助我们实现了该操作,如果添加了softmax,那么就重复了,但效果并不会有什么影响。下面我们看一下交叉熵损失函数的计算过程,以及使用pytorch的实现过程。
根据交叉熵损失函数手动计算
首先假设batch_size为4,分类为3的网络最后一层的输出。
import torch
input=torch.rand(4,3)
input
tensor([[0.0515, 0.6730, 0.2852],
        [0.0362, 0.3434, 0.7450],
        [0.7136, 0.6566, 0.2402],
        [0.6989, 0.0917, 0.7857]])
根据交叉熵损失函数,计算完softmax之后还需要计算每一个值的log数值,因此我们可以使用LogSoftmax函数来计算。
output=torch.nn.LogSoftmax(dim=1)(input)
output
tensor([[-1.4170, -0.7956, -1.1834],
        [-1.4796, -1.1724, -0.7708],
        [-0.9429, -0.9999, -1.4163],
        [-0.9691, -1.5762, -0.8823]])
假设标签为:
[1,0,2,1]
根据交叉熵的计算公式,最终的损失为:
 
     
      
       
        
         l
        
        
         o
        
        
         s
        
        
         s
        
        
         =
        
        
         −
        
        
         (
        
        
         −
        
        
         0.7956
        
        
         −
        
        
         1.4796
        
        
         −
        
        
         1.4163
        
        
         −
        
        
         1.5762
        
        
         )
        
        
         /
        
        
         4
        
        
         =
        
        
         1.3169
        
       
       
         loss=-(-0.7956-1.4796-1.4163-1.5762)/4=1.3169 
       
      
     loss=−(−0.7956−1.4796−1.4163−1.5762)/4=1.3169
 使用pytorch进行计算
#未使用one-hot编码
target = torch.tensor([1,0,2,1])
loss = torch.nn.CrossEntropyLoss()
output = loss(input, target)
output
tensor(1.3169)
上述为使用one-hot编码,下面试一下标签使用one-hot编码:
#未使用one-hot编码
target = torch.tensor([[0.0,1.0,0.0],
                      [1.0,0.0,0.0],
                      [0.0,0.0,1.0],
                      [0.0,1.0,0.0]])
loss = torch.nn.CrossEntropyLoss()
output = loss(input, target)
output
tensor(1.3169)
可见在使用交叉熵损失函数时,标签可以使用one-hot编码,也可以不使用one-hot编码。
3、使用总结
虽然负对数似然损失函数和交叉熵损失函数的公式一样,但是他们在pytorch中的使用有一定的差别,下面是对pytorch中的nn.NLLLoss()和nn.CrossEntropyLoss()的使用总结:
- 在使用nn.NLLLoss()是,需要结合nn.LogSoftmax()一起使用,而nn.CrossEntropyLoss不需要。
- 使用nn.CrossEntropyLoss时,网络的最后一层不需要加softmax层。
- 使用nn.NLLLoss()是,标签不能使用one-hot编码标签,在使用nn.CrossEntropyLoss时,可以使用one-hot标签,也可以不使用one-hot标签。
参考:










