上一讲PyTorch深度学习实践概论笔记8-加载数据集中,主要介绍了Dataset 和 DataLoader是加载数据的两个工具类。这一讲介绍多分类问题如何解决,一般会用到SoftMax分类器

0 Revision

0.1 Revision: Diabetes dataset

在之前的糖尿病数据集中进行了二分类,只有输出P(y=1),另一个概率就等于1-P(y=1)。

0.2 Revision: MNIST Dataset

在MNIST数据集中,有10种不同的分类标签,我们如何用SoftMax分类器来实现分类?

2 Design Neural Network

2.1 Design 10 outputs using Sigmoid?

第一种设计方式是改变输出,变成10个输出,每一个输出代表样本属于对应类的概率。这样的方法相当于把每个类分别看成二分类,但是会出现一个问题,各个类别之间的概率没有直接的联系,不好给出明确的预测我们更希望输出服从一个分布,满足:

  • 输出的概率大于等于0
  • 输出的概率之和等于1

2.2 Output a Distribution of prediction with Softmax

所以在处理多分类问题时,前面的层还是采用Sigmoid,最后一层输出的时候采用Softmax层。

多分类问题用SoftMax分类器要求输出的分类概率都大于0且总和为1,把输出经过sigmoid层就可以。

2.2.1 Softmax Layer

接下来看看Softmax层的定义。假设Z^l是最后一个线性层的输出,则Softmax函数为:

老师讲解版:

2.2.2 Softmax Layer-Example

看一个具体栗子。

经过线性变换之后有0.2,0.1和-0.1三个数值,用上述的公式进行计算,得到输出0.38,0.34和0.28(对应的是概率值)。

接下来看看用Softmax分类器,损失函数怎么求?

2.2.3 Loss function-Cross Entropy

对于多分类的损失函数是上面的公式,名称叫Negative Log Likelihood Loss

那么要实现这个计算过程,该如何操作呢?

2.2.4 Cross Entropy in Numpy

先看在Numpy中如何计算。

代码如下:

import numpy as npy = np.array([1, 0, 0])z = np.array([0.2, 0.1, -0.1])y_pred = np.exp(z) / np.exp(z).sum() #softmaxloss = (- y * np.log(y_pred)).sum()print(loss)  #0.9729189131256584

2.2.5 Cross Entropy in PyTorch

再看看在PyTorch中如何计算。

torch.nn.CrossEntropyLoss()相当于LogSoftmax+NLLLoss。代码如下:

import torchy = torch.LongTensor([0])#长整型张量z = torch.Tensor([[0.2, 0.1, -0.1]])criterion = torch.nn.CrossEntropyLoss()#相当于LogSoftmax+NLLLossloss = criterion(z, y)print(loss)  #tensor(0.9729)

上图的交叉熵损失就包含了softmax计算和右边的标签输入计算(即框起来的部分),所以在使用交叉熵损失的时候,神经网络的最后一层是不要做激活的,因为把它做成分布的激活是包含在交叉熵损失里面的,最后一层不要做非线性变换,直接交给交叉熵损失

Mini-Batch: batch_size=3

结合mini-batch,当batch size=3时有如下操作:

代码分析:

import torch
criterion = torch.nn.CrossEntropyLoss()
Y = torch.LongTensor([2, 0, 1])   #tensor([2, 0, 1])
Y_pred1 = torch.Tensor([[0.1, 0.2, 0.9],[1.1, 0.1, 0.2],[0.2, 2.1, 0.1]])
Y_pred2 = torch.Tensor([[0.8, 0.2, 0.3],[0.2, 0.3, 0.5],[0.2, 0.2, 0.5]])
l1 = criterion(Y_pred1, Y)
l2 = criterion(Y_pred2, Y)
print("Batch Loss1 = ", l1.data, "\nBatch Loss2=", l2.data)

输出结果:

Batch Loss1 =  tensor(0.4966)
Batch Loss2= tensor(1.2389)

3 Exercise 9-1: CrossEntropyLoss vs NLLLoss

练习:

ref:https://pytorch.org/docs/stable/nn.html#crossentropyloss

ref:https://pytorch.org/docs/stable/nn.html#nllloss

练习的解答之后会出(具体看评论)。

4 Back to MNIST Dataset

接下来我们回到MNIST数据集。

上述图像大小是28*28的,像素为784,图像对应右侧的28*28矩阵。

4.1 Implementation

接下来看代码如何实现,这里第4步加上测试。

4.1.0 Implementation – 0. Import Package

代码如下:

#0.导库
import torch#构建DataLoader的库
from torchvision import transformsfrom torchvision import datasetsfrom torch.utils.data import DataLoader#使用函数relu()的库
import torch.nn.functional as F#构建优化器的库
import torch.optim as optim

4.1.1 Implementation – 1. Prepare Dataset

第1步:准备数据集。

和之前相比,上述代码多了transform属性, transforms.ToTensor()是将PIL图像转化成Tensor

如上图所示,transform代码将0-255压缩到0-1,将单通道变成多通道(1x28x28)

代码如下:

#1.准备数据集
batch_size = 64transform = transforms.Compose([transforms.ToTensor(), #将PIL图像转化成Tensortransforms.Normalize((0.1307, ), (0.3081, ))   #正则化,归一化,0.1307是均值,0.3081是标准差,这两个值是根据所有数据集算出来的])train_dataset = datasets.MNIST(root='../dataset/mnist/',train=True,download=True,transform=transform)train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)test_dataset = datasets.MNIST(root='../dataset/mnist/',train=False,download=True,transform=transform)test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

4.1.2 Implementation – 2. Design Model

第2步:设计模型。这里激活层做了一些改变,改成ReLU,最后一层不做激活。输入是(N,1,28,28)4维的,但是需要转换,使用view()转变成一阶张量。

代码如下:

#2.设计模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.l1 = torch.nn.Linear(784, 512)self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 10)def forward(self, x):x = x.view(-1, 784)  x = F.relu(self.l1(x))x = F.relu(self.l2(x))x = F.relu(self.l3(x))x = F.relu(self.l4(x))return self.l5(x)   #注意最后一层不做激活model = Net()

4.1.3 Implementation – 3. Construct Loss and Optimizer

第3步:构造损失函数和优化器。

代码如下:

#3.构造损失和优化器
criterion = torch.nn.CrossEntropyLoss()optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

4.1.4 Implementation – 4. Train and Test

第4步:训练和测试过程。

代码如下:

#4.训练
def train(epoch):running_loss = 0.0for batch_idx, data in enumerate(train_loader, 0):inputs, target = dataoptimizer.zero_grad()# forward + backward + updateoutputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))# running_loss = 0.0#4.测试
def test():correct = 0total = 0with torch.no_grad():#测试时不会计算梯度for data in test_loader:images, labels = dataoutputs = model(images)_, predicted = torch.max(outputs.data, dim=1)  #沿着维度1取最大值的下标total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy on test set: %d %%' % (100 * correct / total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

老师的输出结果:

我的输出结果:

可以看到test的准确率在上升,但是到一定程度之后不再上升。因为全连接层对图像处理不太友好,后续做特征提取效果会好一些(人工的方法:例如傅里叶变换FFT、小波变换;自动的提取:CNN等)。

这一段MNIST数据集的完整代码如下(可跑通):

#0.导库
import torch
#构建DataLoader的库
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
#使用函数relu()的库
import torch.nn.functional as F
#构建优化器的库
import torch.optim as optim#1.准备数据集
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(), #将PIL图像转化成Tensortransforms.Normalize((0.1307, ), (0.3081, ))   #正则化,归一化,0.1307是均值,0.3081是标准差,这两个值是根据所有数据集算出来的])train_dataset = datasets.MNIST(root='../datasets/data/',train=True,download=False,transform=transform)train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)test_dataset = datasets.MNIST(root='../datasets/data/',train=False,download=False,transform=transform)test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)#2.设计模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.l1 = torch.nn.Linear(784, 512)self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 10)def forward(self, x):x = x.view(-1, 784)  x = F.relu(self.l1(x))x = F.relu(self.l2(x))x = F.relu(self.l3(x))x = F.relu(self.l4(x))return self.l5(x)   #注意最后一层不做激活model = Net()#3.构造损失和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)#4.训练过程
def train(epoch):running_loss = 0.0for batch_idx, data in enumerate(train_loader, 0):inputs, target = dataoptimizer.zero_grad()# forward + backward + updateoutputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))#4.测试过程
def test():correct = 0total = 0with torch.no_grad():#测试时不会计算梯度for data in test_loader:images, labels = dataoutputs = model(images)_, predicted = torch.max(outputs.data, dim=1)  #沿着维度1取最大值的下标total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy on test set: %d %%' % (100 * correct / total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

5 Exercise 9-2: Classifier Implementation

练习9-2:找到kaggle的这个数据集做多分类

Dataset ref:https://www.kaggle.com/c/otto-group-product-classification-challenge/data

(练习后续补上,请看评论。)

说明:记录学习笔记,如果错误欢迎指正!写文章不易,转载请联系我。

PyTorch深度学习实践概论笔记9-SoftMax分类器相关推荐

  1. 【Pytorch深度学习实践】B站up刘二大人课程笔记——目录与索引(已完结)

    从有代码的课程开始讨论 [Pytorch深度学习实践]B站up刘二大人之LinearModel -代码理解与实现(1/9) [Pytorch深度学习实践]B站up刘二大人之 Gradient Desc ...

  2. 【PyTorch深度学习实践 | 刘二大人】B站视频教程笔记

    资料 [参考:<PyTorch深度学习实践>完结合集_哔哩哔哩_bilibili] [参考 分类专栏:PyTorch 深度学习实践_错错莫的博客-CSDN博客] 全[参考 分类专栏:PyT ...

  3. 刘二大人 PyTorch深度学习实践 笔记 P6 逻辑斯蒂回归

    刘二大人 PyTorch深度学习实践 笔记 P6 逻辑斯蒂回归 P6 逻辑斯蒂回归 1.torchversion 提供的数据集 2.基本概念 3.代码实现 P6 逻辑斯蒂回归 1.torchversi ...

  4. 【PyTorch】PyTorch深度学习实践|视频学习笔记|P6-P9

    PyTorch深度学习实践 逻辑斯蒂回归及实现 背景与概念 基于分类问题中属性是类别性的,所以不能采取基于序数的线性回归模型,而提出了新的分类模型--逻辑斯蒂回归模型,输出每个样本在各个预测值上的概率 ...

  5. 《PyTorch深度学习实践》学习笔记 【2】

    <PyTorch深度学习实践>学习笔记 [2] 学习资源: <PyTorch深度学习实践>完结合集 二.线性模型 2.1 概念: 2.1.1 数据集和测试集 ​ 数据集拿到后一 ...

  6. 笔记|(b站)刘二大人:pytorch深度学习实践(代码详细笔记,适合零基础)

    pytorch深度学习实践 笔记中的代码是根据b站刘二大人的课程所做的笔记,代码每一行都有注释方便理解,可以配套刘二大人视频一同使用. 用PyTorch实现线性回归 # 1.算预测值 # 2.算los ...

  7. 《PyTorch深度学习实践》 课堂笔记 Lesson7 神经网络多维特征输入的原理推导与实现

    文章目录 1.为什么使用多维的特征输入 2. 多维特征向量输入推导 3.实现过程 3.1源代码 3.2训练结果 写在最后 1.为什么使用多维的特征输入 对于现实世界来说,影响一个事物发展的因素有很多种 ...

  8. PyTorch深度学习实践

    根据学习情况随时更新. 2020.08.14更新完成. 参考课程-刘二大人<PyTorch深度学习实践> 文章目录 (一)课程概述 (二)线性模型 (三)梯度下降算法 (四)反向传播 (五 ...

  9. 【Pytorch深度学习实践】B站up刘二大人之SoftmaxClassifier-代码理解与实现(8/9)

    这是刘二大人系列课程笔记的倒数第二个博客了,介绍的是多分类器的原理和代码实现,下一个笔记就是basicCNN和advancedCNN了: 写在前面: 这节课的内容,主要是两个部分的修改: 一是数据集: ...

最新文章

  1. 深度学习“三部曲”重磅资源、python、DL理论、工程实战全覆盖(附免费下载)...
  2. 《解释性机器学习》笔记(五):Rule Fit 规则拟合
  3. 拖链电缆 机器人电缆_尼龙拖链在机器中起着电缆的作用
  4. 问题类像程序员一样思考
  5. 数字图像处理 第一章 概述
  6. 办公室中有一台计算机连接打印机,办公室就一个打印机,怎么让多个电脑一起用...
  7. 事务未提交导致记录被锁的解决方法
  8. 【CSS】解决图片和盒子底部产生的缝隙问题
  9. 新xp系统如何链接网络连接服务器地址,xp系统如何设置宽带连接
  10. HTTP与HTTPS之间的联系与连接状态
  11. 关于大小端转换整理总结(包含原始方式、Qt方式)
  12. CTF之misc-图片隐写
  13. docekr unable to delete d38d835588d5 (must be forced) - image is referenced in multiple repositories
  14. 购买Apple移动硬盘
  15. 2022青海省农商银行(农信社)招聘每日一练及答案
  16. 2020最新免费网盘
  17. 会计 制造费用转生产成本
  18. Cow Pinball
  19. Apache Doris 技术调研
  20. KubeEdge1.10从零开始详细搭建教程

热门文章

  1. 红领巾心向党PPT模板
  2. 抖音神器---Java实现图片(Image)转字符(ASCII)图片
  3. JSP之数据库连接池·笔记
  4. Micro Python———MPU6050六轴传感器
  5. kswapd CPU占用率过高
  6. 屏幕键盘开启占用COM1的问题?
  7. VirtualBox 立即卸载此应用,因为它与Windows 10 不兼容
  8. 树莓派4B使用create_ap做无线热点(AP)
  9. 2022-2027年中国壁挂炉行业市场全景评估及发展战略规划报告
  10. %公式在计算机中怎么使用,在Excel 2013公式中使用函数并移动和复制——想象力电脑应用...