Pytorch总结三之 softmax回归用于分类问题

  • 上篇博文Pytorch总结二之线性回归算法原理与实现介绍的线性回归模型适⽤于输出为连续值的情景。
  • 在另⼀类情景中,模型输出可以是⼀个像图像类别这样的离散值。对于这样的离散值预测问题,我们可以使⽤诸如softmax回归在内的分类模型。和线性回归不同,softmax回归的输出单元从⼀个变成了多个,且引⼊了softmax运算使输出更适合离散值的预测和训练。本节以softmax回归模型为例,介绍神经⽹络中的分类模型。

1. softmax 回归

1.1 分类问题

  • 让我们考虑⼀个简单的图像分类问题,其输⼊图像的⾼和宽均为2像素,且⾊彩为灰度。这样每个像素值都可以⽤⼀个标量表示。我们将图像中的4像素分别记为x1, x2, x3, x4 。假设训练数据集中图像的真实标签为狗、猫或鸡(假设可以⽤4像素表示出这3种动物),这些标签分别对应离散值y1, y2, y3
  • 我们通常使⽤离散的数值来表示类别,例如y1=1, y2=2, y3=3 。如此,⼀张图像的标签为1、2和 3这3个数值中的⼀个。虽然我们仍然可以使⽤回归模型来进⾏建模,并将预测值就近定点化到1、2和3 这3个离散值之⼀,但这种连续值到离散值的转化通常会影响到分类质量。因此我们⼀般使⽤更加适合离散值输出的模型来解决分类问题

1.2 softmax 回归模型



1.3 单样本分类的矢量计算表达式

1.4 小批量样本分类的矢量计算表达式

1.5 交叉熵损失函数


1.6 模型预测及评价

  • 在训练好softmax回归模型后,给定任⼀样本特征,就可以预测每个输出类别的概率。通常,我们把预测概率最⼤的类别作为输出类别。如果它与真实类别(标签)⼀致,说明这次预测是正确的。在3实验中,我们将使⽤准确率(accuracy)来评价模型的表现。它等于正确预测数量与总预测数量之⽐。
  • softmax回归适⽤于分类问题。它使⽤softmax运算输出类别的概率分布。
  • softmax回归是⼀个单层神经⽹络,输出个数等于分类问题中的类别个数。
  • 交叉熵适合衡量两个概率分布的差异。

2. 图像分类数据集(Fashion-MNIST)

图像分类数据集中最常⽤的是⼿写数字识别数据集MNIST。但⼤部分模型在MNIST上的分类精度都超过了95%。为了更直观地观察算法之间的差异,我们将使⽤⼀个图像内容更加复杂的数据集Fashion-MNIST(这个数据集也⽐较⼩,只有⼏⼗M,没有GPU的电脑也能吃得消)。

  • 本节将使用torchvision包,他是服务于Pytorch深度学习框架的,主要用来构建计算机视觉模型。

  • torchvision主要有以下几部分构成:

    [1] torchvision.datasets:一些加载数据的函数及常用的数据集接口
    [2] torchvision.models:包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等
    [3] torchvision.transforms:常用的图像变换,例如裁剪、旋转等
    [4] torchvision.utils:其他的一些有用的方法

2.1 获取数据集

注:python安装包一定要注意版本问题,安装前最好查下torch对应的其他包的版本,不然下载其他包的时候自动把torch的版本也给替换了,不过到最后一番波折后我选择了系统默认安装的cpu版torch与torchtext一起用,不然就会一直报错!!!

导入模块:

# time:20220824
# writer:yohn
#Pytorch通过softmax实现分类问题#1.获取数据集import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import time
import sys
sys.path.append("..") # 为了导⼊上层⽬录的d2lzh_pytorch
import d2lzh_pytorch as d2l#训练集用于模型训练得到参数,测试机用于模型验证及评价
mnist_train =torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',
train=True, download=True, transform=transforms.ToTensor())
mnist_test =torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',
train=False, download=True, transform=transforms.ToTensor())#mnist_train 和 mnist_test 都是 torch.utils.data.Dataset 的⼦类
print(type(mnist_train))   #<class 'torchvision.datasets.mnist.FashionMNIST'>
print(len(mnist_train),len(mnist_test))   #60000 10000#通过下标来访问任意⼀个样本,变量 feature 对应⾼和宽均为28像素的图像。由于我们使⽤了 transforms.ToTensor() ,所以每个
# 像素的数值为[0.0, 1.0]的32位浮点数。需要注意的是, feature 的尺⼨是 (C x H x W) 的,⽽不是 (H
# x W x C)。第⼀维是通道数,因为数据集中是灰度图像,所以通道数为1。后⾯两维分别是图像的⾼和宽。
feature, label = mnist_train[0]
print(feature.shape, label) # Channel x Height X Width
#torch.Size([1, 28, 28]) tensor(9)# Fashion-MNIST中⼀共包括了10个类别,分别为t-shirt(T恤)、trouser(裤⼦)、pullover(套衫)、
# dress(连⾐裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、
# bag(包)和ankle boot(短靴)。以下函数可以将数值标签转成相应的⽂本标签。
# 本函数已保存在d2lzh包中⽅便以后使⽤
def get_fashion_mnist_labels(labels):text_labels = ['t-shirt', 'trouser', 'pullover', 'dress','coat','sandal', 'shirt', 'sneaker', 'bag', 'ankleboot']return [text_labels[int(i)] for i in labels]#定义一个可在一行里画出多张图像和对应标签的函数,# 本函数已保存在d2lzh包中⽅便以后使⽤
def show_fashion_mnist(images, labels):d2l.use_svg_display()# 这⾥的_表示我们忽略(不使⽤)的变量_, figs = plt.subplots(1, len(images), figsize=(12, 12))for f, img, lbl in zip(figs, images, labels):f.imshow(img.view((28, 28)).numpy())f.set_title(lbl)f.axes.get_xaxis().set_visible(False)f.axes.get_yaxis().set_visible(False)plt.show()#2.显示数据及标签,看⼀下训练数据集中前9个样本的图像内容和⽂本标签。
X, y = [], []
for i in range(10):X.append(mnist_train[i][0])y.append(mnist_train[i][1])print(y)show_fashion_mnist(X, get_fashion_mnist_labels(y))

运行时,其他都没问题,只有这:

暂时还不知道该怎么解决,放张正常无异常的结果图吧,正常结果显示如下

2.2 读取小批量

# #**************读取小批量******************
#PyTorch的DataLoader 中 ⼀ 个 很 ⽅ 便 的 功 能 是 允 许 使 ⽤ 多 进 程 来 加 速 数 据 读 取 。 这 ⾥ 我 们 通 过 参
# 数 num_workers 来设置4个进程读取数据
batch_size = 256
if sys.platform.startswith('win'):num_workers = 0 # 0表示不⽤额外的进程来加速读取数据
else:num_workers = 4
train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test,batch_size=batch_size, shuffle=False, num_workers=num_workers)
start = time.time()
for X, y in train_iter:continue
print('%.2f sec' % (time.time() - start))
#1.57sec

3. softmax的从零开始实现

#3. softmax回归的从零开始实现
import torch
import torchvision
import numpy as np
import sys
sys.path.append("..") # 为了导⼊上层⽬录的d2lzh_pytorch
import d2lzh_pytorch as d2l#1.获取数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)#2.初始化模型参数
# 跟线性回归中的例⼦⼀样,我们将使⽤向量表示每个样本。已知每个样本输⼊是⾼和宽均为28像素的图
# 像。模型的输⼊向量的⻓度是28*28=784 :该向量的每个元素对应图像中每个像素。由于图像有
# 10个类别,单层神经⽹络输出层的输出个数为10,因此softmax回归的权᯿和偏差参数分别为784*10和1*10 的矩阵。
num_inputs = 784
num_outputs = 10
W = torch.tensor(np.random.normal(0, 0.01, (num_inputs,num_outputs)), dtype=torch.float)
b = torch.zeros(num_outputs, dtype=torch.float)#同样需要模型参数梯度
W.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)#3. 实现softmax运算
#对多为tensor按维度操作,我们可以只对其中同⼀列( dim=0 )或同⼀⾏( dim=1 )的元素求
#和,并在结果中保留⾏和列这两个维度( keepdim=True )。
X = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(X.sum(dim=0, keepdim=True))  #tensor([[5, 7, 9]])
print(X.sum(dim=1, keepdim=True))  #tensor([[ 6],[15]])# 在下⾯的函数中,矩阵 X 的⾏数是样本数,列数是输出个数。为了表达样本预测各个输出的概率,softmax运算会先通过 exp 函数对每个元素做指数
# 运算,再对 exp 矩阵同⾏元素求和,最后令矩阵每⾏各元素与该⾏元素之和相除。这样⼀来,最终得到的矩阵每⾏元素和为1且⾮负。因此,该矩阵每⾏
# 都是合法的概率分布。softmax运算的输出矩阵中的任意⼀⾏元素代表了⼀个样本在各个输出类别上的预测概率。
def softmax(X):X_exp = X.exp()partition = X_exp.sum(dim=1, keepdim=True)return X_exp / partition # 这⾥应⽤了⼴播机制#对于随机输⼊,我们将每个元素变成了⾮负数,且每⼀⾏和为1。
X = torch.rand((2, 5))
X_prob = softmax(X)
print(X_prob, X_prob.sum(dim=1))
#tensor([[0.2206, 0.1520, 0.1446, 0.2690, 0.2138],[0.1540, 0.2290, 0.1387, 0.2019, 0.2765]]) tensor([1., 1.])#4.定义模型
def net(X):return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)#5.定义损失函数
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y = torch.LongTensor([0, 2])
y_hat.gather(1, y.view(-1, 1))  #通过使⽤ gather 函数,我们得到了2个样本的标签的预测概率
#tensor([[0.1000],[0.5000]])#交叉熵函数
def cross_entropy(y_hat, y):return - torch.log(y_hat.gather(1, y.view(-1, 1)))#定义优化算法,使⽤学习率为0.1的⼩批量随机梯度下降作为优化算法
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)#6. 计算分类准确率
# 给定⼀个类别的预测概率分布 y_hat ,我们把预测概率最⼤的类别作为输出类别。如果它与真实类
# 别 y ⼀致,说明这次预测是正确的。分类准确率即正确预测数量与总预测数量之⽐。#argmax返回每行中最大元素的索引,且返回结果与y姓黄相同
def accuracy(y_hat, y):return (y_hat.argmax(dim=1) == y).float().mean().item()
print(accuracy(y_hat, y))  #0.5# 本函数已保存在d2lzh_pytorch包中⽅便以后使⽤。该函数将被逐步改进:它的完整实现将在“图像增⼴”⼀节中描述
def evaluate_accuracy(data_iter, net):acc_sum, n = 0.0, 0for X, y in data_iter:acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()n += y.shape[0]return acc_sum / n#为我们随机初始化了模型 net ,所以这个随机模型的准确率应该接近于类别个数10的倒数即0.1
print(evaluate_accuracy(test_iter,net))#7.训练模型
# 训练softmax回归的实现跟“线性回归的从零开始实现” ⼀节介绍的线性回归中的实现⾮常相似。我们同
# 样使⽤⼩批量随机梯度下降来优化模型的损失函数。在训练模型时,迭代周期数 num_epochs 和学习
# 率 lr 都是可以调的超参数。改变它们的值可能会得到分类更准确的模型。
num_epochs,lr = 5,0.1def train_ch3(net,train_iter,test_iter,loss,num_epochs,batch_size,params=None,lr=None,optimizer=None):for epoch in range(num_epochs):train_l_sum,train_acc_sum,n=0.0,0.0,0for x,y in train_iter:y_hat=net(x)l=loss(y_hat,y).sum()#梯度清零if optimizer is not None:optimizer.zero_grad();elif params is not None and params[0].grad is not None:for param in params:param.grad.data.zero_()l.backward()if optimizer is None:d2l.sgd(params,lr,batch_size)else:optimizer.step()train_l_sum += l.item()train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = evaluate_accuracy(test_iter, net)print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n,train_acc_sum / n,test_acc))
#开始训练
train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs,batch_size, [W, b], lr)
# epoch 1, loss 0.7853, train acc 0.751, test acc 0.794
# epoch 2, loss 0.5692, train acc 0.814, test acc 0.811
# epoch 3, loss 0.5257, train acc 0.826, test acc 0.814
# epoch 4, loss 0.5007, train acc 0.833, test acc 0.823
# epoch 5, loss 0.4866, train acc 0.836, test acc 0.827#8.预测
X, y = iter(test_iter).next()
true_labels = d2l.get_fashion_mnist_labels(y.numpy())
pred_labels =d2l.get_fashion_mnist_labels(net(X).argmax(dim=1).numpy())
titles = [true + '\n' + pred for true, pred in zip(true_labels,pred_labels)]
d2l.show_fashion_mnist(X[0:9], titles[0:9])

result:

Pytorch总结三之 softmax回归用于分类问题相关推荐

  1. 机器学习心得(三)——softmax回归

    机器学习心得(三)--softmax回归 在上一篇文章中,主要以二分类为例,讲解了logistic回归模型原理.那么对于多分类问题,我们应该如何处理呢?当然,选择构建许多二分类器进行概率输出自然是一个 ...

  2. UFLDL教程笔记及练习答案三(Softmax回归与自我学习***)

    UFLDL教程笔记及练习答案三(Softmax回归与自我学习***) 1:softmax回归 当p(y|x,theta)满足多项式分布,通过GLM对其进行建模就能得到htheta(x)关于theta的 ...

  3. 深度学习 第3章线性分类 实验四 pytorch实现 Softmax回归 鸢尾花分类任务 下篇

    目录: 第3章 线性分类 3.3 实践:基于Softmax回归完成鸢尾花分类任务 3.3.1 数据处理 3.3.1.1 数据集介绍 3.3.1.2 数据清洗 1. 缺失值分析 2. 异常值处理 3.3 ...

  4. 【ML】自动编码器结合逻辑回归用于分类预测(数据+代码详细教程)

    自动编码器(aotoencoder)是一种神经网络,可用于学习原始数据的压缩表征.一种自动编码器由编码器(encoder)和解码器(decoder)两个子模型组成.编码器压缩输入,解码器尝试从编码器提 ...

  5. PyTorch搭建简单神经网络实现回归和分类

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 安装 PyTorch 会安装两个模块,一个是torch,一个 torchvision, tor ...

  6. softmax回归多元分类

    介绍 本次使用x1.x2两个参数进行0/1/2/3四类的多元分类问题模型的搭建 代码实现 import numpy as np import matplotlib.pyplot as pltnp.ra ...

  7. 【Pytorch神经网络基础理论篇】 08 Softmax 回归 + 损失函数 + 图片分类数据集

    3.4. softmax回归 回归可以用于预测多少的问题. 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数. 事实上,我们也对分类问题感兴趣:不是问"多少" ...

  8. Softmax回归——logistic回归模型在多分类问题上的推广

    Softmax回归 Contents [hide] 1 简介 2 代价函数 3 Softmax回归模型参数化的特点 4 权重衰减 5 Softmax回归与Logistic 回归的关系 6 Softma ...

  9. 分类模型——Softmax回归

    分类模型--Softmax回归 第一章 机器学习是什么 第二章 深度学习是什么 第三章 前馈神经网络 第四章 卷积神经网络 第五章 交叉熵函数 文章目录 分类模型--Softmax回归 前言 Soft ...

最新文章

  1. 2022-2028年中国电熔镁行业市场研究及发展趋势分析报告
  2. python txt提取特定数据_Python提取列表中的内容 用“python”怎么提取文件里的指定内容?...
  3. Error: bin/bash^M: bad interpreter: no such file o
  4. 最小生成树之克鲁斯卡尔(Kruskal)算法
  5. android仿苹果SwitchButton效果的实现
  6. springboot 系列教程十:springboot单元测试
  7. ElasticSearch、Logstash和Kiabana三个开源工具。
  8. 朱晔和你聊Spring系列S1E3:Spring咖啡罐里的豆子
  9. android图标字体大小设置,Android系统上如何调节显示的字体图标的大小
  10. 随想录(从kaldi学习语音识别)
  11. 浅谈数据结构之顺序队列(五)
  12. c++ auto 属性
  13. 1001系列之案例0003如何对欧洲人口普查数据集整理挖掘
  14. ThinkPad E450 10.11 驱动HD4400的注意即解决方法
  15. word 2016编辑区鼠标光标消失/变白解决方案
  16. c语言韦达定理求方程解,高一上韦达定理,高次,多元方程解法.doc
  17. CSS实现空心三角指示箭头
  18. svn冲突问题详解 SVN版本冲突解决详解
  19. 7大爱好来提高编程技能
  20. div展开和折叠 php,超酷堆叠图片展开和折叠

热门文章

  1. stick和stuck的区别_Stick to和Stick with的区别
  2. 用python打开视频_MoviePy - 用Python玩转视频剪辑!(MoviePy安装及视频文件读取)...
  3. java毕业设计后勤管理系统在线报修系统mybatis+源码+调试部署+系统+数据库+lw
  4. mapgis中6.7属性结构_【技术】这世界的完美,原本一直在我们眼前 ——MapGIS打造全空间GIS平台...
  5. nexus7 android 5.0.2,移动数据版Nexus 7可升级Android 5.0.2
  6. vue基于elementUI表格状态判断展示
  7. CodeSoft官方Demo
  8. 小程序智能识别快递收货地址,自动解析出省市区等信息,让地址标准化格式的实现(使用腾讯云api)
  9. 操作无法完成.键入的打印机名不正确,或者指定的打印机没有连接到服务器上.有关详细信息
  10. 生存分析的一些整理笔记