PyTorch损失函数详解:概率模型与分类问题

PyTorch中实现的关于分类问题的损失函数一共有BCELossBCEWithLogitsLossNLLLossCrossEntropyLossKLDivLossCTCLoss六个。

从极大似然估计说起

神经网络得到输入后,输出的是一个概率分布,即每个可能的输出的概率,然后将真实标签带入概率分布得到含有待估参数的概率,进而计算似然函数,作极大似然估计;

对于分类问题来讲,可以直接生成每个类别的概率得到分布,具体来讲,神经网络输出logits之后:

对于二分类问题可以过sigmoid函数生成正类概率$P$,负类概率为$1-P$,即为分布;

对于多分类问题可以过softmax函数生成各个类的概率,即为分布。

BCELoss

适用于二分类问题,二元交叉熵,可以通过设定weight参数来决定每个样本的权重,设定reduction参数来决定是否取平均,如果是默认样本权重相等且取平均数:

\[Loss = \frac{1}{N} \sum_{n=1}^N l_n\]

其中,

\[l_n = - [y_n log\hat{y_n} + (1 - y_n)log(1-\hat{y_n})]\]

$y_n$表示真实的是正类的概率;$\hat{y_n}$为模型预估的是正类的概率

BCEWithLogitsLoss

适用于二分类问题,添加了Sigmoid的二元交叉熵,可以通过设定weight参数来决定每个样本的权重,设定reduction参数来决定是否取平均,如果是默认样本权重相等且取平均数:

\[Loss = \frac{1}{N} \sum_{n=1}^N l_n\]

令:

\[\hat{y_n} = \sigma({\hat{y_n} }')\]

其中,

\[l_n = - [y_n log\sigma({\hat{y_n} }') + (1 - y_n)log(1-\sigma({\hat{y_n} }'))]\]

$y_n$表示真实的是正类的概率;$\hat{y_n}$为模型预估的是正类的概率

NLLLoss

适用于多分类问题,缺少了对数的负对数似然,可以通过设定weight参数来决定每个样本的权重,设定reduction参数来决定是否取平均,如果是默认样本权重相等且取平均数:

\[Loss = \frac{1}{N} \sum_{n=1}^N l_n\]

令:

\[{\hat{y}_{n, c}}' = log\hat{y}_{n, c}\]

其中,

\[l_n = - \sum_{c=1}^C y_{n,c} {\hat{y}_{n, c} }'\]

$y_{n,c}$表示真实的是$c$类的概率;$\hat{y}_{n,c}$为模型预估的是$c$类的概率

CrossEntropyLoss

适用于多分类问题,添加了Softmax的交叉熵,可以通过设定weight参数来决定每个样本的权重,设定reduction参数来决定是否取平均,如果是默认样本权重相等且取平均数:

\[Loss = \frac{1}{N} \sum_{n=1}^N l_n\]

令:

\[\hat{y}_{n,c} = \frac{e^{ {\hat{y}_{n,c} }'}}{\sum_{j=1}^C e^{ {\hat{y}_{n,j} }'} }\]

其中,

\[l_n = - \sum_{c=1}^C y_{n,c} log \frac{e^{ {\hat{y}_{n,c} }'} }{\sum_{j=1}^C e^{ {\hat{y}_{n,j} }'} }\]

$y_{n,c}$表示真实的是$c$类的概率;$\hat{y}_{n,c}$为模型预估的是$c$类的概率

KLDivLoss

适用于多分类问题,KL散度损失,可以通过设定reduction参数来决定是否取平均,如果是默认取平均数:

\[Loss = \frac{1}{N} \sum_{n=1}^N l_n\]

其中,

\[l_n = \sum_{c=1}^C y_{n,c} (logy_{n,c} - log\hat{y}_{n,c})\]

KL散度中的$y_{n,c}$和交叉熵中的$y_{n,c}$区别在于:交叉熵中的$y_{n,c}$是某个类别是$1$,其他全为$0$;KL散度中的$y_{n,c}$可以像交叉熵一样,但也可以各个类别都有概率

KL散度的原理不是极大似然估计,而是直接缩小真实和预估的两个分布之间的差距

CTCLoss