softmax和分类模型
1|0softmax和分类模型
内容包含:
- softmax回归的基本概念
- 如何获取Fashion-MNIST数据集和读取数据
- softmax回归模型的从零开始实现,实现一个对Fashion-MNIST训练集中的图像数据进行分类的模型
- 使用pytorch重新实现softmax回归模型
1|1softmax的基本概念
-
分类问题
一个简单的图像分类问题,输入图像的高和宽均为2像素,色彩为灰度。
图像中的4像素分别记为x1,x2,x3,x4x1,x2,x3,x4。
假设真实标签为狗、猫或者鸡,这些标签对应的离散值为y1,y2,y3y1,y2,y3。
我们通常使用离散的数值来表示类别,例如y1=1,y2=2,y3=3y1=1,y2=2,y3=3。 -
权重矢量
- 神经网络图
下图用神经网络图描绘了上面的计算。softmax回归同线性回归一样,也是一个单层神经网络。由于每个输出o1,o2,o3o1,o2,o3的计算都要依赖于所有的输入x1,x2,x3,x4x1,x2,x3,x4,softmax回归的输出层也是一个全连接层。
既然分类问题需要得到离散的预测输出,一个简单的办法是将输出值oioi当作预测类别是ii的置信度,并将值最大的输出所对应的类作为预测输出,即输出 argmaxioiargmaxioi。例如,如果o1,o2,o3o1,o2,o3分别为0.1,10,0.10.1,10,0.1,由于o2o2最大,那么预测类别为2,其代表猫。
- 输出问题
直接使用输出层的输出有两个问题:- 一方面,由于输出层的输出值的范围不确定,我们难以直观上判断这些值的意义。例如,刚才举的例子中的输出值10表示“很置信”图像类别为猫,因为该输出值是其他两类的输出值的100倍。但如果o1=o3=103o1=o3=103,那么输出值10却又表示图像类别为猫的概率很低。
- 另一方面,由于真实标签是离散值,这些离散值与不确定范围的输出值之间的误差难以衡量。
softmax运算符(softmax operator)解决了以上两个问题。它通过下式将输出值变换成值为正且和为1的概率分布:
其中
容易看出ˆy1+ˆy2+ˆy3=1^y1+^y2+^y3=1且0≤ˆy1,ˆy2,ˆy3≤10≤^y1,^y2,^y3≤1,因此ˆy1,ˆy2,ˆy3^y1,^y2,^y3是一个合法的概率分布。这时候,如果ˆy2=0.8^y2=0.8,不管ˆy1^y1和ˆy3^y3的值是多少,我们都知道图像类别为猫的概率是80%。此外,我们注意到
因此softmax运算不改变预测类别输出。
- 计算效率
- 单样本矢量计算表达式
为了提高计算效率,我们可以将单样本分类通过矢量计算来表达。在上面的图像分类问题中,假设softmax回归的权重和偏差参数分别为
- 单样本矢量计算表达式
设高和宽分别为2个像素的图像样本ii的特征为
输出层的输出为
预测为狗、猫或鸡的概率分布为
softmax回归对样本ii分类的矢量计算表达式为
- 小批量矢量计算表达式
为了进一步提升计算效率,我们通常对小批量数据做矢量计算。广义上讲,给定一个小批量样本,其批量大小为nn,输入个数(特征数)为dd,输出个数(类别数)为qq。设批量特征为X∈Rn×dX∈Rn×d。假设softmax回归的权重和偏差参数分别为W∈Rd×qW∈Rd×q和b∈R1×qb∈R1×q。softmax回归的矢量计算表达式为
其中的加法运算使用了广播机制,O,ˆY∈Rn×qO,^Y∈Rn×q且这两个矩阵的第ii行分别为样本ii的输出o(i)o(i)和概率分布ˆy(i)^y(i)。
1|2交叉熵损失函数
对于样本ii,我们构造向量y(i)∈Rqy(i)∈Rq ,使其第y(i)y(i)(样本ii类别的离散数值)个元素为1,其余为0。这样我们的训练目标可以设为使预测概率分布ˆy(i)^y(i)尽可能接近真实的标签概率分布y(i)y(i)。
- 平方损失估计
然而,想要预测分类结果正确,我们其实并不需要预测概率完全等于标签概率。例如,在图像分类的例子里,如果y(i)=3y(i)=3,那么我们只需要ˆy(i)3^y(i)3比其他两个预测值ˆy(i)1^y(i)1和ˆy(i)2^y(i)2大就行了。即使ˆy(i)3^y(i)3值为0.6,不管其他两个预测值为多少,类别预测均正确。而平方损失则过于严格,例如ˆy(i)1=ˆy(i)2=0.2^y(i)1=^y(i)2=0.2比ˆy(i)1=0,ˆy(i)2=0.4^y(i)1=0,^y(i)2=0.4的损失要小很多,虽然两者都有同样正确的分类预测结果。
改善上述问题的一个方法是使用更适合衡量两个概率分布差异的测量函数。其中,交叉熵(cross entropy)是一个常用的衡量方法:
其中带下标的y(i)jy(i)j是向量y(i)y(i)中非0即1的元素,需要注意将它与样本ii类别的离散数值,即不带下标的y(i)y(i)区分。在上式中,我们知道向量y(i)y(i)中只有第y(i)y(i)个元素y(i)y(i)y(i)y(i)为1,其余全为0,于是H(y(i),ˆy(i))=−logˆyy(i)(i)H(y(i),^y(i))=−log^yy(i)(i)。也就是说,交叉熵只关心对正确类别的预测概率,因为只要其值足够大,就可以确保分类结果正确。当然,遇到一个样本有多个标签时,例如图像里含有不止一个物体时,我们并不能做这一步简化。但即便对于这种情况,交叉熵同样只关心对图像中出现的物体类别的预测概率。
假设训练数据集的样本数为nn,交叉熵损失函数定义为
其中ΘΘ代表模型参数。同样地,如果每个样本只有一个标签,那么交叉熵损失可以简写成ℓ(Θ)=−(1/n)∑ni=1logˆy(i)y(i)ℓ(Θ)=−(1/n)∑ni=1log^y(i)y(i)。从另一个角度来看,我们知道最小化ℓ(Θ)ℓ(Θ)等价于最大化exp(−nℓ(Θ))=∏ni=1ˆy(i)y(i)exp(−nℓ(Θ))=∏ni=1^y(i)y(i),即最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。
1|3模型训练和预测
在训练好softmax回归模型后,给定任一样本特征,就可以预测每个输出类别的概率。通常,我们把预测概率最大的类别作为输出类别。如果它与真实类别(标签)一致,说明这次预测是正确的。在3.6节的实验中,我们将使用准确率(accuracy)来评价模型的表现。它等于正确预测数量与总预测数量之比。
2|0获取Fashion-MNIST训练集和读取数据
在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用,以方便我们观察比较算法之间在模型精度和计算效率上的区别。图像分类数据集中最常用的是手写数字识别数据集MNIST[1]。但大部分模型在MNIST上的分类精度都超过了95%。为了更直观地观察算法之间的差异,我们将使用一个图像内容更加复杂的数据集Fashion-MNIST[2]。
我这里我们会使用torchvision包,它是服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。torchvision主要由以下几部分构成:
- torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
- torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
- torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
- torchvision.utils: 其他的一些有用的方法。
2|1get dataset
class torchvision.datasets.FashionMNIST(root, train=True, transform=None, target_transform=None, download=False)
- root(string)– 数据集的根目录,其中存放processed/training.pt和processed/test.pt文件。
- train(bool, 可选)– 如果设置为True,从training.pt创建数据集,否则从test.pt创建。
- download(bool, 可选)– 如果设置为True,从互联网下载数据并放到root文件夹下。如果root目录下已经存在数据,不会再次下载。
- transform(可被调用 , 可选)– 一种函数或变换,输入PIL图片,返回变换之后的数据。如:transforms.RandomCrop。
- target_transform(可被调用 , 可选)– 一种函数或变换,输入目标,进行变换。
如果不做变换输入的数据是图像,我们可以看一下图片的类型参数:
3|0softmax从零开始的实现
3|1获取训练集数据和测试集数据
3|2模型参数初始化
3|3对多维Tensor按维度操作
3|4定义softmax操作
3|5softmax回归模型
3|6定义损失函数
3|7定义准确率
3|8训练模型
3|9模型预测
现在我们的模型训练完了,可以进行一下预测,我们的这个模型训练的到底准确不准确。
现在就可以演示如何对图像进行分类了。给定一系列图像(第三行图像输出),我们比较一下它们的真实标签(第一行文本输出)和模型预测结果(第二行文本输出)。
4|0softmax的简洁实现
4|1初始化参数和获取数据
4|2定义网络模型
4|3初始化模型参数
4|4定义损失函数
4|5定义优化函数
4|6训练
__EOF__
作 者:Hichens
出 处:https://www.cnblogs.com/hichens/p/12309150.html
关于博主:莫得感情的浅度学习机器人
版权声明:@Hichens
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)