- softmax 和 sigmoid 激活函数
- 有关sigmoid和softmax函数的公式图像和性质可以百度。
- 多标签分类任务(semantic segmentation)和 多类分类任务(手写数字识别、猫狗分类)
首先明确这两种任务的不同。多类分类模型输出的结果唯一,以手写数字识别为例,输入一张图片,模型识别的结果唯一,在模型输出结果之前一步,我们通常使用softmax来对模型计算得到的tensor进行分类。而这里softmax输出的结果是该图片属于每一类的概率大小。(印象很深刻的就是VGG网络最后一层softmax输出为1*1000的线性层,每一个值表示该输入结果分到每一类的概率大小,这些概率加和等于1)。
多标签分类以语义分割为例,输入图片中包含不同的类别,最终输出的时候需要预测每一个像素的类别所属。每一类之间都是独立预测,不同于softmax输出的预测结果加和等于1. Sigmoid输出的是独立预测的每一类的概率。以10分类任务举例。语义分割任务中,sigmoid输出1*10向量中,每一维都是显示该index下属于对应类的概率大小,范围在0-1,和其他9类无关,比如output=[0.3990, 0.1204, 0.2461, 0.0731, 0.7295, 0.7777, 0.0478, 0.5531, 0.3605, 0.4452],index=4时 value=0.7295,表示输入的第四类属于label第四类的概率大小,并且各个输出之间是相互独立的。而在识别任务中,softmax输出的1*10向量输出的是[0.28628283 0.0309893 0.00770005 0.10917224 0.14148639 0.03323315 0.02024344 0.11056698 0.23246488 0.02786074],首先这十个数相加为1,其次数值大小表示输入数据属于某一类别的概率大小。上面这个数组就表示输入数据属于index=0这一类的概率最大。
- 交叉熵函数
1、F.Cross_Entropy()函数公式
q为预测值,p为真实值.
交叉熵是信息熵中的概念,是用来表现估计平均编码长度的,在深度学习中,可以看作概率分布q(x)表示概率分布q(x)的困难程度,即刻画两个概率分布的距离,当交叉熵值越小时候,两个概率分布越相似。
- 计算过程
假定多类分类任务,输入为3张图片,分3类。则输入为3*3tensor。
- 首先得到模型输出的tensor。
首先我们得到模型的Output = [-0.2850, -0.8910, 0.1517],
[ 0.6084, -0.4391, 0.3289],
[-0.5966, 0.7940, 0.7151]
每一行表示不同的每一张图片的预测结果,我们的target是[0,2,0]
- 将模型得到的结果经过softmax分类
将output使用softmax处理,得到结果为
A1= [0.5786, 0.2372, 0.1842],
[0.3106, 0.3123, 0.3771],
[0.4955, 0.3130, 0.1915]
可以看出经过softmax之后每一行的概率之和都为1。每一个值表示这一张图片属于index这一类的概率大小。比如[1,0]坐标的值0.3106就表示第二张图片属于第一类的概率为0.3106。
- 将softmax中输出的值经过log处理,softmax输出的数值范围在0-1之间,所以输入到log函数中得到的结果都在0到负无穷。得到结果为,
A2= [-0.5471, -1.4389, -1.6919],
[-1.1693, -1.1638, -0.9752],
[-0.7023, -1.1615, -1.6528]
④然后就是最后计算的时候,需要明确一点我们的target是一个标量怎么和tensor做loss?target是[0,2,0]和A2∈[3,3]怎么计算loss?
先看target给的信息,可以理解[0,2,0]的含义是第一张图片属于第一类,第二张图片属于第三类,第三张图片属于第一类。而结合上面对softmax的介绍我们可以知道A2中每一行值代表了对图片的预测概率。有了这个知识之后我们继续计算loss。根据公式,我们应该这样计算loss。
loss = (0.5471+0.9752+0.7023)/3
loss = 0.741533
计算过程结束如下
我们使用函数进行验证。
结果一样,所以我们分步计算过程是ok的。
分析可以发现是对A2的每一行分别取index为0,2,0的值,先去掉负号,然后相加在求均值。
怎么理解这
总结:
target是[0,2,0]和A2∈[3,3]怎么计算loss?结合第一节的知识可以知道输入softmax输出的是每一类可能的概率大小。而target直接给出了每一类别的正确的index。比如target是[0,2,0]意思就是第一张图片属于第0类,第二张图片属于第2类,第三张图片属于第0类。在计算loss值的时候我们只需要使用target中提供的值作为index来获取特定坐标的数据,是的最终结果最小即可。
a = torch.tensor([[-0.2585, -1.1503, -1.4033],
[ 0.8442, 0.8497, 1.0383],
[ 0.6672, 0.2079, -0.2833]])
print(a)
s = nn.Softmax(dim=1)
a = s(a)
print(a)
a = a.log()
print(a)
loss = (0.5471+0.9752+0.7023)/3
print(loss)
a = torch.tensor([[-0.2585, -1.1503, -1.4033],
[ 0.8442, 0.8497, 1.0383],
[ 0.6672, 0.2079, -0.2833]])
loss = nn.CrossEntropyLoss()
target = torch.tensor([0,2,0])
out = loss(a,target)
print(out)