文章目录
0 写在前面
这一章主要是解决多分类的问题,sofxmax。
1 解决输出问题
之前我们学习过糖尿病的二分类问题,现在我们要学习的是手写数据集MNIST——十分类的问题。那么这里的输出就从[0,1]变成了[0,1,2,3,4,5,6,7,8,9]。
1.1 输出属于每一个类别的可能性?
二分类问题——1个输出结果就够了
十分类问题——9个输出结果就够了
但是我们想要的输出:①结果都是正数;②和为1;③满足正态分布(distribution)
-
所以sigmoid函数就不能保证我们的需求。因此我们需要引入
softmax函数
! -
softmax函数的公式如下所示:
这里 Z i Z_i Zi表示的是,上一层的输出结果。让所有的值都正,那么就套一个指数函数, e z i e^{z_i} ezi就能保证全为正。然后加起来求和作为分母,分子是第i个输出的情况。 -
先看一下老师给的图:
-
再手写模拟一遍:
-
softmax函数:每一个输出的值,都做一个exponent,然后求和,每个数除以sum,最后计算分布。
如果你觉得这篇文章有用的话,可以点赞收藏关注我哦!
2 解决loss函数的问题
- 刚刚最后一层的输出是[0.2, 0.1, -0.1],在经过softmax函数之后,得到了[0.38 0.34, 0.28]这样的一个正态分布。
- 方便后面继续计算loss值。
2.1 之前学习的二分类交叉熵
- torch.nn.BCELoss()类定义如下:
torch.nn.BCELoss(
weight=None,
size_average=None,
reduction="mean"
)
- 用公式表示:
- 注意: Z n Z_n Zn表示的是上一层的输出(预测值)! y n y_n yn则表示真实值。
3 引入多分类的交叉熵函数
由于我们在多分类问题中,都是用one-hot编码来打标签的。所以说y中 等于0的分量是对loss不作出贡献的。
- 简单手算一下:
3.1 实现计算过程
- 假设z是上一层的输出,y是真实值
import numpy as np
y = np.array([0, 0, 1])
z = np.array([0.2, 0.1, -0.1])
y_pred = np.exp(z) / np.exp(z).