文章目录
1. 输出多个类别
多分类问题不同,以MNIST数据集为例,需要计算出每个方框属于不同数字的10个概率,这10个概率需要满足:
这样才能满足多分类的离散分布;而对于二分类问题,我们只需要求出P(y=1)的概率就可以,因为P(y=0)的概率我们可以通过1-(y=1)求得。
输出之间要有竞争性且满足分布的要求。
对于解决多分类问题,我们不在采样sigmoid作为最后一层,因为sigmoid层不能满足上面的两个条件,而这里采用了softmax层。
softmax层能解决多分类问题,它主要解决的问题就是使得前面输出的正值和负值都统一成正值,此外可以使得多个输出的和为1。
2. softmax层
softmax满足两个要求:
- 让每一个输出都大于0
- 让k个分类的和加起来等于1
softmax的公式:
softmax的过程:
3. loss计算
对于多分类问题,输入的一个对象他只有一个标签是1,其余的都是0,这样0*logY就没有了,只剩下标签1对应的logY,也就是loss值。
整个过程的计算如下**(NLLLoss损失)**:
其实在实际计算过程种,我们一般直接找到标签为1的,然后直接乘以它的log预测值。
import numpy as np
y = np.array([1, 0, 0])
z = np.array([0.2, 0.1, -0.1])
y_pred = np.exp(z) / np.exp(z).sum()
loss = (- y * np.log(y_pred)).sum()
print(loss)
pytorch提供了多分类softmax以及loss的整个计算(交叉熵损失):
最后一层是线性层,后面直接跟torch.nn.CrossEntropyLoss()计算交叉熵损失,其中y是长整形的tensor张量,代表输入属于第几个分类,上图代表y属于第一个分类。z代表最后线性层的输出。
Y代表真实的属于哪一个类,下面的两个为预测的结果,最后线性层的输出。
import torch
y = torch.LongTensor([0])
z = torch.Tensor([[0.2, 0.1, -0.1]])
criterion = torch.nn.CrossEntropyLoss()
loss = criterion(z, y)
print(loss)
注意CrossEntropyLoss()和NLLLoss()的区别:
CrossEntropyLoss损失函数是将Softmax层和NLLLoss损失函数整合在一。
注意:使用CrossEntropyLoss损失函数时,神经网络的最后一层不需要做激活,(也就是不用经过Softmax层的计算),直接输入到CrossEntropyLoss损失函数中就可以,因为CrossEntropyLoss损失函数包含的Sofrmax层。
4. softmax和交叉熵来处理MNIST数据集
MNIST数据集:
手写数字数据集,其中包含0-9数字,也就是十分类问题。
我们之前学习的案例中,输入x都是一个向量;在MNIST数据集中,我们需要输入的是一个图像,怎样,图像怎么才能输入到模型中进行训练呢?一种方法是我们可以把图像映射成一个矩向量,再输入到模型中进行训练。怎样将一个图像映射成一个向量?
如图所示是MNIST数据集中一个方格的图像,它是由28x28=784个像素组成,其中越深的地方数值越接近0,越亮的地方数值越接近1。
图像的像素一般分布在0-255之间,我们通过映射使其分布在0-1之间。
3.1 准备数据集
图像张量:灰度图(黑白图像)就是一个单通道的图像,彩色图像是多通道的图像(分别是R,G,B三个通道),一个通道具有高度——H,宽度——W,通道由——C表示。
transform作用:在pytorch中读取图像时使用的是python的PIL,而由PIL读取的图像一般是由W x H x C组成,而在pytorch中为了进行更高效的图像处理,需要图像由C x W x H这样的顺序组成,因此transform的作用就是将PIL读取的图像顺序转换成C x W x H,同时pytorch图像的类型为tensor类型;像素值从0-255转换成0-1。
Normalize作用:归一化或标准化,提供的参数为均值和标准差。
举例四六级成绩的计算:(你的分数-均值)/标准差*70% + 500
这符合正太分布了 amazing~
对于MNIST数据集,这个均值0.1307和标准差0.3018是根据整个数据集计算得来的一种经验值,不是随便取得。
神经网络喜欢0-1分布的数据,这种对于神经网络是最好的。
对于其他的数据集,我们可以通过numpy包来计算均值和标准差。