Softmax与Cross-entropy的求导

引言

在多分类问题中,一般会把输出结果传入到softmax函数中,得到最终结果。并且用交叉熵作为损失函数。本来就来分析下以交叉熵为损失函数的情况下,softmax如何求导。

对softmax求导

softmax函数为:

y ^ i = e z i ∑ k = 1 K e z k \hat y_i = \frac{e^{z_i}}{\sum_{k=1}^K e^{z_k}} y^i=k=1Kezkezi

这里 K K K是类别的总数,接下来求 y ^ i \hat y_i y^i对某个输出 z j z_j zj的导数,
∂ y ^ i ∂ z j = ∂ e z i ∑ k = 1 K e z k ∂ z j \frac{\partial \hat y_i}{\partial z_j} = \frac{\partial \frac{e^{z_i}}{\sum_{k=1}^K e^{z_k}}}{\partial z_j} zjy^i=zjk=1Kezkezi

这里要分两种情况,分别是 i = j i=j i=j i ≠ j i \neq j i=j。当 i = j i=j i=j时, e z i e^{z_i} ezi z j z_j zj的导数为 e z i e^{z_i} ezi,否则当 i ≠ j i \neq j i=j时,导数为 0 0 0

i = j i = j i=j
∂ y ^ i ∂ z j = e z i ⋅ ∑ k = 1 K e z k − e z i ⋅ e z j ( ∑ k = 1 m e z k ) 2 = e z i ∑ k = 1 m e z k − e z i ∑ k = 1 m e z k ⋅ e z j ∑ k = 1 m e z k = y ^ i − y ^ i 2 = y ^ i ( 1 − y ^ i ) \begin{aligned} \frac{\partial \hat y_i}{\partial z_j} &= \frac{e^{z_i}\cdot \sum_{k=1}^K e^{z_k} - e^{z_i} \cdot e^{z_j} }{(\sum_{k=1}^m e^{z_k})^2} \\ &= \frac{e^{z_i}}{\sum_{k=1}^m e^{z_k}} - \frac{e^{z_i}}{\sum_{k=1}^m e^{z_k}} \cdot \frac{e^{z_j}}{\sum_{k=1}^m e^{z_k}} \\ &= \hat y_i - \hat y_i^2 = \hat y_i(1 - \hat y_i) \end{aligned} zjy^i=(k=1mezk)2ezik=1Kezkeziezj=k=1mezkezik=1mezkezik=1mezkezj=y^iy^i2=y^i(1y^i)

i ≠ j i \neq j i=j
∂ y ^ i ∂ z j = 0 ⋅ ∑ k = 1 K e z k − e z i ⋅ e z j ( ∑ k = 1 m e z k ) 2 = − e z i ∑ k = 1 m e z k ⋅ e z j ∑ k = 1 m e z k = − y ^ i y ^ j \begin{aligned} \frac{\partial \hat y_i}{\partial z_j} &= \frac{0 \cdot \sum_{k=1}^K e^{z_k} - e^{z_i} \cdot e^{z_j}}{(\sum_{k=1}^m e^{z_k})^2} \\ &= - \frac{e^{z_i}}{\sum_{k=1}^m e^{z_k}} \cdot \frac{e^{z_j}}{\sum_{k=1}^m e^{z_k}} \\ &= - \hat y_i \hat y_j \end{aligned} zjy^i=(k=1mezk)20k=1Kezkeziezj=k=1mezkezik=1mezkezj=y^iy^j

对cross-entropy求导

损失函数 L L L为:

L = − ∑ k y k log ⁡ y ^ k L = -\sum_k y_k \log \hat y_k L=kyklogy^k

其中 y k y_k yk是真实类别,相当于一个常数,接下来求 L L L z j z_j zj的导数

∂ L ∂ z j = ∂ − ( ∑ k y k log ⁡ y ^ k ) z j = ∂ − ( ∑ k y k log ⁡ y ^ k ) ∂ y ^ k ∂ y ^ k ∂ z j = − ∑ k y k 1 y ^ k ∂ y ^ k z j = ( − y k ⋅ y ^ k ( 1 − y ^ k ) 1 y ^ k ) k = j − ∑ k ≠ j y k 1 y ^ k ( − y ^ k y ^ j ) = − y j ( 1 − y ^ j ) − ∑ k ≠ j y k ( − y ^ j ) = − y j + y j y ^ j + ∑ k ≠ j y k ( y ^ j ) = − y j + ∑ k y k ( y ^ j ) = − y j + y ^ j = y ^ j − y j \begin{aligned} \frac{\partial L}{\partial z_j} &= \frac{\partial -(\sum_k y_k \log \hat y_k)}{z_j}\\ &= \frac{\partial -(\sum_k y_k \log \hat y_k)}{\partial \hat y_k} \frac{\partial \hat y_k}{\partial z_j} \\ &= -\sum_k y_k \frac{1}{\hat y_k} \frac{\partial \hat y_k}{z_j} \\ &= \left(-y_k \cdot \hat y_k(1 - \hat y_k) \frac{1}{\hat y_k} \right)_{k=j} - \sum_{k \neq j} y_k \frac{1}{\hat y_k} (-\hat y_k \hat y_j) \\ &= - y_j (1 -\hat y_j) - \sum_{k \neq j} y_k (-\hat y_j) \\ &= - y_j + y_j \hat y_j + \sum_{k \neq j} y_k (\hat y_j) \\ &= - y_j + \sum_{k} y_k (\hat y_j) \\ &= - y_j +\hat y_j \\ &= \hat y_j -y_j \end{aligned} zjL=zj(kyklogy^k)=y^k(kyklogy^k)zjy^k=kyky^k1zjy^k=(yky^k(1y^k)y^k1)k=jk=jyky^k1(y^ky^j)=yj(1y^j)k=jyk(y^j)=yj+yjy^j+k=jyk(y^j)=yj+kyk(y^j)=yj+y^j=y^jyj

这里用到了 ∑ k y k = 1 \sum_{k} y_k = 1 kyk=1

可以看到,求导结果非常简单,如果不推导都不敢信。

在 PyTorch 中,`nn.CrossEntropyLoss` 是一个常用的损失函数,通常用于多分类问题中。该函数将 softmax 函数和负对数似然损失函数结合在一起,可以直接计算神经网络的输出和真实标签之间的交叉熵损失。 `nn.CrossEntropyLoss` 的输入包括两个部分:神经网络的输出和真实标签。其中,神经网络的输出是一个形状为 `(batch_size, num_classes)` 的张量,其中 `batch_size` 表示批次大小,`num_classes` 表示类别数;真实标签是一个长度为 `batch_size` 的一维张量,其中每个元素的取值范围为 `[0, num_classes-1]`。 使用 `nn.CrossEntropyLoss` 可以在训练过程中方便地计算损失值,并且该函数还可以自动进行反向传播求导。下面是一个简单的使用 `nn.CrossEntropyLoss` 的示例代码: ```python import torch import torch.nn as nn # 定义神经网络的输出和真实标签 outputs = torch.randn(10, 5) # batch_size=10, num_classes=5 labels = torch.tensor([2, 4, 1, 0, 3, 2, 2, 1, 4, 0]) # 定义损失函数 criterion = nn.CrossEntropyLoss() # 计算损失值 loss = criterion(outputs, labels) # 打印损失值 print(loss.item()) ``` 在上面的示例中,`outputs` 的形状为 `(10, 5)`,表示有 10 个样本,每个样本有 5 个类别的输出得分。`labels` 是一个长度为 10 的一维张量,表示 10 个样本的真实标签。定义损失函数时,我们直接使用 `nn.CrossEntropyLoss()`,不需要额外设置参数。使用 `loss.item()` 可以得到一个标量,表示该批次样本的平均交叉熵损失。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愤怒的可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值