本文首发于公众号【拇指笔记】

1. 使用pytorch实现softmax回归模型

使用pytorch可以更加便利的实现softmax回归模型。

1.1 获取和读取数据

读取小批量数据的方法:

首先是获取数据,pytorch可以通过以下代码很方便的获取Fashion-MNIST数据集。

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())#参数#root : processed/training.pt 和 processed/test.pt 的主目录
#train : True = 训练集, False = 测试集
#download : True = 从互联网上下载数据集,并把数据集放在root目录下. 如果数据集之前下载过,将处理过的数据(minist.py中有相关函数)放在processed文件夹下
#transform = transforms.ToTensor():使所有数据转换为Tensor

然后是生成一个迭代器,用来读取数据

#生成迭代器
train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle = True,num_workers = 0)test_iter = torch.utils.data.DataLoader(mnist_test,batch_size = batch_size,shuffle=False,num_workers=0)
#参数#dataset:Dataset类型,从其中加载数据
#batch_size:int类型,每个批量加载多少个数
#shuffle:bool类型,每个学习周期都打乱顺序
#num_workers:int类型,加载数据时使用多少子进程。默认值为0.
#collate_fn:定义如何取样本,可通过定义自己的函数来实现。
#pin_memory:锁页内存处理。
#drop_last:bool类型,如果有剩余的样本,True表示丢弃;Flase表示不丢弃

1.2 定义和初始化模型

由softmax回归模型的定义可知,softmax回归模型只有权重参数和偏差参数。因此可以使用神经网络子模块中的线性模块。

  1. 首先定义网络,softmax回归是一个两层的网络,所以只需要定义输入层和输出层即可。
num_inputs = 784
num_outputs = 10class LinearNet(nn.Module):def __init__(self,num_inputs,num_outputs):super(LinearNet,self).__init__()self.linear = nn.Linear(num_inputs,num_outputs)#定义一个输入层#定义向前传播(在这个两层网络中,它也是输出层)def forward(self,x):y = self.linear(x.view(x.shape[0],-1))#将x换形为y后,再继续向前传播return ynet = LinearNet(num_inputs,num_outputs)

  1. 初始化参数

使用torch.nn中的init可以快速的初始化参数。我们令权重参数为均值为0,标准差为0.01的正态分布。偏差为0。

init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0)

1.3 softmax运算和交叉熵损失函数

分开定义softmax运算和交叉熵损失函数会造成数值不稳定。因此PyTorch提供了一个具有良好数值稳定性且包括softmax运算和交叉熵计算的函数。

loss = nn.CrossEntropyLoss()

1.4 定义优化算法

依然使用小批量随机梯度下降作为优化算法。定义学习率为0.1。

optimizer = torch.optim.SGD(net.parameters(),lr=0.01)

1.5 计算分类准确率

计算准确率的原理:

我们把预测概率最大的类别作为输出类别,如果它与真实类别y一致,说明预测正确。分类准确率就是正确预测数量与总预测数量之比

首先我们需要得到预测的结果。

从一组预测概率(变量y_hat)中找出最大的概率对应的索引(索引即代表了类别)

#argmax(f(x))函数,对f(x)求最大值所对应的点x。我们令f(x)= dim=1,即可实现求所有行上的最大值对应的索引。
A = y_hat.argmax(dim=1)
#最终输出结果为一个行数与y_hat相同的列向量

然后我们需要将得到的最大概率对应的类别与真实类别(y)比较,判断预测是否是正确的

B = (y_hat.argmax(dim=1)==y).float()
#由于y_hat.argmax(dim=1)==y得到的是ByteTensor型数据,所以我们通过.float()将其转换为浮点型Tensor()

最后我们需要计算分类准确率

我们知道y_hat的行数就对应着样本总数,所以,对B求平均值得到的就是分类准确率

(y_hat.argmax(dim=1)==y).float().mean()

上一步最终得到的数据为tensor(x)的形式,为了得到最终的pytorch number,需要对其进行下一步操作

(y_hat.argmax(dim=1)==y).float().mean().item()
#pytorch number的获取统一通过.item()实现

整理一下,得到计算分类准确率函数

def accuracy(y_hat,y):return (y_hat.argmax(dim=1).float().mean().item())

作为推广,该函数还可以评价模型net在数据集data_iter上的准确率。

def net_accurary(data_iter,net):right_sum,n = 0.0,0for X,y in data_iter:#从迭代器data_iter中获取X和yright_sum += (net(X).argmax(dim=1)==y).float().sum().item()#计算准确判断的数量n +=y.shape[0]#通过shape[0]获取y的零维度(列)的元素数量return right_sum/n

1.6 训练模型

num_epochs = 5
#一共进行五个学习周期def train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary):for epoch in range(num_epochs):#损失值、正确数量、总数 初始化。train_l_sum,train_right_sum,n= 0.0,0.0,0for X,y in train_iter:y_hat = net(X)l = loss(y_hat,y).sum()#数据集损失函数的值=每个样本的损失函数值的和。            optimizer.zero_grad()            #对优化函数梯度清零l.backward()  #对损失函数求梯度optimizer(params,lr,batch_size)train_l_sum += l.item()train_right_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = net_accurary(test_iter, net)   #测试集的准确率print('epoch %d, loss %.4f, train right %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_right_sum / n, test_acc))train_softmax(net,train_iter,test_iter,cross_entropy,num_epochs,batch_size,optimizernet_accurary,net_accurary)

训练属实是有点慢,只训练了五个周期。 训练结果:

1.7 预测

使用训练好的模型对测试集进行预测

做一个模型的最终目的当然不是训练了,所以来预测一下试试。

#将样本的类别数字转换成文本
def get_Fashion_MNIST_labels(labels):text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]#labels是一个列表,所以有了for循环获取这个列表对应的文本列表#显示图像
def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#绘制矢量图_,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()#从测试集中获得样本和标签
X, y = iter(test_iter).next()true_labels = get_Fashion_MNIST_labels(y.numpy())
pred_labels = get_Fashion_MNIST_labels(net(X).argmax(dim=1).numpy())#将真实标签和预测得到的标签加入到图像上
titles = [true + 'n' + pred for true, pred in zip(true_labels, pred_labels)]show_fashion_mnist(X[0:9], titles[0:9])

预测结果:

完整程序

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("..") import torchvision
from IPython import display
from numpy import argmax
import torchvision.transforms as transforms
from time import time
import matplotlib.pyplot as plt
import numpy as npbatch_size =256mnist_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())#生成迭代器
train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle = True,num_workers = 4)test_iter = torch.utils.data.DataLoader(mnist_test,batch_size = batch_size,shuffle=False,num_workers=4)num_inputs = 784
num_outputs = 10class LinearNet(nn.Module):def __init__(self,num_inputs,num_outputs):super(LinearNet,self).__init__()self.linear = nn.Linear(num_inputs,num_outputs)#定义一个输入层#定义向前传播(在这个两层网络中,它也是输出层)def forward(self,x):y = self.linear(x.view(x.shape[0],-1))#将x换形为y后,再继续向前传播return ynet = LinearNet(num_inputs,num_outputs)#初始化参数
init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0) #损失函数
loss = nn.CrossEntropyLoss()#优化函数
optimizer = torch.optim.SGD(net.parameters(),lr=0.01)num_epochs = 5
#一共进行五个学习周期#计算准确率
def net_accurary(data_iter,net):right_sum,n = 0.0,0for X,y in data_iter:#从迭代器data_iter中获取X和yright_sum += (net(X).argmax(dim=1)==y).float().sum().item()#计算准确判断的数量n +=y.shape[0]#通过shape[0]获取y的零维度(列)的元素数量return right_sum/ndef get_Fashion_MNIST_labels(labels):text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]#labels是一个列表,所以有了for循环获取这个列表对应的文本列表def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#绘制矢量图_,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()def train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary):for epoch in range(num_epochs):#损失值、正确数量、总数 初始化。train_l_sum,train_right_sum,n= 0.0,0.0,0for X,y in train_iter:y_hat = net(X)l = loss(y_hat,y).sum()#数据集损失函数的值=每个样本的损失函数值的和。            optimizer.zero_grad()          #对优化函数梯度清零l.backward()  #对损失函数求梯度optimizer.step()train_l_sum += l.item()train_right_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = net_accurary(test_iter, net)  #测试集的准确率print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_right_sum / n, test_acc))train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary)X, y = iter(test_iter).next()true_labels = get_Fashion_MNIST_labels(y.numpy())
pred_labels = get_Fashion_MNIST_labels(net(X).argmax(dim=1).numpy())
titles = [true + 'n' + pred for true, pred in zip(true_labels, pred_labels)]show_fashion_mnist(X[0:9], titles[0:9])


最后

在学习Python一年中,收集了很多Python学习资料,在这里整理一下,分享给各位!

Python入门、数据分析、爬虫、运维、机器学习方面的学习资料

干货 | Python学习资源整理分享​mp.weixin.qq.com

如果觉得本文还可以,还请各位点个赞。

添加softmax层_PyTorch入门之100行代码实现softmax回归分类相关推荐

  1. 100行代码搞定实时视频人脸表情识别(附代码)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自|OpenCV学堂 好就没有写点OpenCV4 + Open ...

  2. SAP系统和微信集成的系列教程之八:100行代码在微信公众号里集成地图搜索功能

    本系列的英文版Jerry写作于2017年,这个教程总共包含十篇文章,发表在SAP社区上. 系列目录 (1) 微信开发环境的搭建 (2) 如何通过微信公众号消费API (3) 微信用户关注公众号之后,自 ...

  3. 100行代码让您学会JavaScript原生的Proxy设计模式

    面向对象设计里的设计模式之Proxy(代理)模式,相信很多朋友已经很熟悉了. 其实和Java一样,JavaScript从语言层面来讲,也提供了对代理这个设计模式的原生支持.我们用一个不到100行代码的 ...

  4. react hooks使用_我如何使用React Hooks在约100行代码中构建异步表单验证库

    react hooks使用 by Austin Malerba 奥斯汀·马勒巴(Austin Malerba) 我如何使用React Hooks在约100行代码中构建异步表单验证库 (How I bu ...

  5. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器

    简介 FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频 ...

  6. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  7. PONG - 100行代码写一个弹球游戏

    大家好,欢迎来到 Crossin的编程教室 ! 今天跟大家讲一讲:如何做游戏 游戏的主题是弹球游戏<PONG>,它是史上第一款街机游戏.因此选它作为我这个游戏开发系列的第一期主题. 游戏引 ...

  8. C语言100行代码实现推箱子

    1 C语言100行代码实现推箱子 1.1 概述  C语言是很好入门编程的一个语言,它拥有着很好的移植性,基本上所有的平台都支持C语言编程.有些C语言基础的你,是不是也很想做一个项目来检验一下自己的学习 ...

  9. Android鬼点子 100行代码,搞定柱状图!

    最近,项目中遇到一个地方,要用到柱状图.所以这篇文章主要讲怎么搞一个柱子. 100行代码,搞定柱状图! 我的印象中柱子是这样的. 恩,简单,一个View直接放到xml,搞定! 但,设计师给的柱子是这样 ...

最新文章

  1. Json文件解析(上)
  2. 西南这座城,脸,比北上广还有用
  3. 即时消息服务框架(iMSF)应用实例之分布式事务三阶段提交协议的实现
  4. matlab能力处理,书+程序《MATLAB图像处理:能力提高与应用案例》赵小川
  5. string int 相互转换
  6. 残疾人软件开发_残疾人应该使用Linux的6个理由
  7. goquery php,golang:Goquery简单爬虫实例
  8. 洛谷P1127 词链 欧拉路问题
  9. 从dig命令理解DNS
  10. 制作PCB的基本设计流程;
  11. GeoGebra官方版下载
  12. h5页面自定义字体_自定义app字体(原生+h5)
  13. js获取服务器时间,并以北京时区显示
  14. 自动切换手机耳机模式和话筒模式
  15. ubuntu 进不去界面解决方案
  16. 基于codesys开发的多轴运动控制程序框架,将逻辑与运动控制分离,将单轴控制封装成功能块,对该功能块的操作包含了所有的单轴控制
  17. 网站加载图片慢 网页响应慢 网页优化
  18. 看动画理解「链表」实现LRU缓存淘汰算法
  19. Three.js进阶篇之4 - 着色器
  20. Zzzzzz 每天来点负能量---看着就会心地笑了

热门文章

  1. android编译产生的apk或so不安装 .
  2. 创意DIY项目分享(3)
  3. 十一、Linux时间
  4. 善用rel=’canonical’,权重更集中(转)
  5. ppwjs之bootstrap表格:String.到表头单元格元素 和 String.到表格单元格元素
  6. ES6之---读懂let才能少踩坑
  7. 树莓派搭建ActiveMQ
  8. Gson简要使用笔记
  9. PostgreSQL在何处处理 sql查询之二十二
  10. C#控制DataMax指令打印DPL问题总结