pytoch人工神经网络基础:最简单的分类(softmax回归+交叉熵分类)

2023-05-16

softmax回归分类原理

对于回归问题,可以用模型预测值与真实值比较,用均方误差这样的损失函数表示误差,迭代使误差最小训练模型。

那么分类问题是否可以用线性回归模型预测呢。最简单的方法就是用softmax方法,softmax的原理:

  • 以in_features个特征,out_features个类别为例。比如用花瓣大小、生长位置、花瓣形状三个因素,判断荷花和梅花,则in_features为3,out_feautures为2。

模型为

y 1 = x 11 w 11 + x 12 w 12 + x 13 w 13 + b 1 y 2 = x 21 w 21 + x 22 w 22 + x 23 w 23 + b 2 y_1=x_{11}w_{11}+x_{12}w_{12}+x_{13}w_{13}+b_1 \\ y_2=x_{21}w_{21}+x_{22}w_{22}+x_{23}w_{23}+b_2 y1=x11w11+x12w12+x13w13+b1y2=x21w21+x22w22+x23w23+b2

  • out_features个分类,用输出值的大小表示分类, y 1 , y 2 y_1,y_2 y1,y2数值最大的那个表示输出分类。

比如:labels=[‘荷花’,‘梅花’]。输出 y 1 = 1 , y 2 = 3 y_1=1,y_2=3 y1=1,y2=3,则表示预测结果为梅花。输出 y 1 = 2 , y 2 = 1 y_1=2,y_2=1 y1=2,y2=1表示预测结果为荷花。即输出为 a r g m a x ( y i ) argmax(y_i) argmax(yi)

  • softmax函数把输出标准化,softmax(y_1,y_2)输出两个值:

o u t 1 = e x p ( y 1 ) ∑ e x p ( y i ) o u t 2 = e x p ( y 2 ) ∑ e x p ( y i ) out_1=\frac{exp(y_1)}{\sum{exp(y_i)}}\\ out_2=\frac{exp(y_2)}{\sum{exp(y_i)}}\\ out1=exp(yi)exp(y1)out2=exp(yi)exp(y2)

可以看出 o u t 1 + o u t 2 = 1 out_1+out_2=1 out1+out2=1,也就是说 o u t i out_i outi是一个合法的概率分布,并且输入值大小和概率大小一直。因此,通常就把softmax计算结果,叫做out_features个分类的预测概率。即: o u t i out_i outi为labels[i]的概率。

从以上原理可以看出,多少个分类模型就需要几个输出(即线型方程个数)。
理论上讲,二分类问题,一个线性方程就ok了。但是使用softmax方法就必须2个方程,因为要为每个分类单独计算概率。

通常softmax函数会同时计算N个样本的数据,即输入形状为(N,in_feature)。函数实现如下:

def softmax(x):
    '''计算形状为(N,in_features)的x的softmax'''
    x_exp=torch.exp(x)
    return x_exp/x_exp.sum(dim=-1,keepdim=True)

交叉熵损失函数

交叉熵的含义可以参考一文搞懂熵(Entropy),交叉熵(Cross-Entropy)从浅入深讲的非常通俗易懂。这里就不再详述了,这里仅简单的说明一下。

对于有out_features个类别分类的问题,可以用softmax函数把输出转换为概率。按照把正确分类对应的输出概率最大化,不断迭代就可以完成模型训练。通常我们不直接用最大化概率的方法,而是对概率进一步进行运算处理。

  • 取对数的负值。 − l o g ( p ) -log(p) log(p)。因为概率p为0-1之间值,因此计算结果为∞~0。结果最小时,概率最大。
  • 对于分类问题,通常真实概率是这样的 p t r u e = [ 1 , 0 , 0 , . . . ] 或 者 [ 0 , 1 , 0 , . . ] 或 者 [ 0 , 0 , . . . , 1 ] p_{true}=[1,0,0,...]或者[0,1,0,..]或者[0,0,...,1] ptrue=[1,0,0,...][0,1,0,..][0,0,...,1]结果只有一个值概率是1,其他值概率为0。 − l o g ( p ) p t r u e -log(p)p_{true} log(p)ptrue就是交叉熵损失函数。

假如softmax输出概率为 p = [ o u t 1 , o u t 2 ] p=[out_1,out_2] p=[out1,out2],真实概率为 p t r u e = [ 0 , 1 ] p_true=[0,1] ptrue=[0,1]则交叉熵函数算法为

-log(p)*p_true

假如softmax输出概率为 p = [ o u t 1 , o u t 2 ] p=[out_1,out_2] p=[out1,out2],真实标签用序号表示 l a b e l t r u e = 1 label_true=1 labeltrue=1(结果为第一个标签,即梅花),则交叉熵函数算法为

p_log=-log(p)
loss=p_log[label_true]

实际上softmax通常会一次计算很多个样本,形状通常为(N,out_feature),labels通常就是一个长度为N的数组,即每个样本只有一个结果,表示序号。因此交叉熵函数算法为:

def crossloss(y_softmax,y_label):#参数为torch.tensor类型
    '''根据softmax计算交叉熵。
    输入y为计算的N个样本的softmax概率,形状为(N,in_feautures)。
    y_label为真实标签,即每个样本真实分类的序号,形状为(N,)。'''
    log_softmax=-torch.log(y_softmax)
    index=y_label.view(-1,1) #转换为列形式
    entropy_arr=log_softmax.gather(dim=1,index=index) #label的值,即序号即概率为1,指选概率为1的值就是softmax的负对数的期望,即交叉熵。
    return entropy_arr.mean()

softmax回归分类实现

import torch
from torch import nn, optim
import matplotlib.pyplot as plt

# 准备数据

N=100
x_train1=torch.tensor([1,1])+torch.normal(mean=0, std=0.2, size=[N//2,2])
y_train1=torch.zeros(N//2,1,dtype=torch.long)
x_train2=torch.tensor([2,2])+torch.normal(mean=0, std=0.2, size=[N//2,2])
y_train2=torch.ones(N//2,1,dtype=torch.long)

x_train=torch.cat([x_train1, x_train2])
y_train=torch.cat([y_train1, y_train2])

# 显示数据
plt.scatter(x_train[:,0],x_train[:,1],c=y_train[:,0])
plt.colorbar()
plt.show()


# 建立模型

def softmax(x):
    '''计算形状为(N,in_featrues)的x的softmax'''
    x_exp=torch.exp(x)
    return x_exp/x_exp.sum(dim=-1,keepdim=True)

class Net(nn.Module):
    def __init__(self, in_features, out_features):
        super().__init__()
        self.layer1=nn.Linear(in_features,out_features)
                
    def forward(self, x):
        return softmax(self.layer1(x))
    
net = Net(2,2)

# 配置模型

def crossloss(y_softmax,y_label):
    '''根据softmax计算交叉熵。
    输入y为计算的N个样本的softmax概率,形状为(N,in_feautures)。
    y_true为真实标签,即每个样本真实分类的序号,形状为(N,)。'''
    log_softmax=-torch.log(y_softmax)
    label=y_label.view(-1,1) #转换为列形式
    entropy_arr=log_softmax.gather(dim=1,index=label) #label的值,即序号即概率为1,指选概率为1的值就是softmax的负对数的期望,即交叉熵。
    return entropy_arr.mean()

nn.init.normal_(net.layer1.weight, mean=0, std=0.1)
nn.init.constant_(net.layer1.bias, val=0)
optimizer = optim.SGD(net.parameters(),lr=0.03)


# 训练模型


for epoch in range(1001):
    y_predict = net(x_train)
    loss=crossloss(y_predict, y_train.view(-1)) #y_predict形状(N,2), y参数形状(N,)
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()
    
    if(epoch%100==0):
        print(f"epoch:{epoch}, loss:{loss.data.item()}")


# 查看结果

p = softmax(y_predict).data.numpy()
p1 = p[:,0]<p[:,1]
plt.scatter(x_train[:,0], x_train[:,1], c=p1) #直接用分类1的概率表示颜色绘制
plt.colorbar()
plt.show()

在这里插入图片描述

使用pytorch预定义函数实现softmax分类

pytorch内置了softmax和CrossEntropyLoss功能。

pytorch的softmax

pytorch中的softmax函数用法:

  • torch.softmax(input, dim=None, dtype=None)
    • input:输入数据,pytorch浮点数张量
    • dim:对哪个维度进行softmax计算,通常我们都是对dim=-1计算。
    • dtype:输出数据类型。

torch.softmax实际上是torch.nn.functional.softmax的别名。

>>> x=torch.arange(12,dtype=torch.float).view(4,3)
>>> x
tensor([[ 0.,  1.,  2.],
        [ 3.,  4.,  5.],
        [ 6.,  7.,  8.],
        [ 9., 10., 11.]])
>>> torch.softmax(x, dim=1)
tensor([[0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652]])

pytorch中softmax还可以作为层layer。因此nn模块中有一个Softmax类,根据Softmax类创建对象后可以当做函数用。

+nn.Softmax(dim=None):Softmax类构造函数只有一个参数dim


>>> layer=nn.Softmax(dim=-1)
>>> layer(x)
tensor([[0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652],
        [0.0900, 0.2447, 0.6652]])

pytorch的CrossEntropyLoss

pytoch中的交叉熵损失函数类,实际上包含了softmax运算,因此,使用CrossEntropyLoss时,就不需要再使用softmax函数了。

  • crossloss=CrossEntropyLoss():创建对象
  • crossloss(y_predict, y_true):计算交叉熵
    • y_predict:为模型前向传播计算得到的结果,形状为(N,out_features)
    • y_true:为N个样本的分类序号,形状为(N,)
import torch
from torch import nn, optim
import numpy as np
import matplotlib.pyplot as plt

准备数据

N=100
x_train1=torch.tensor([1,1])+torch.normal(mean=0, std=0.2, size=[N//2,2])
y_train1=torch.zeros(N//2,1,dtype=torch.long)
x_train2=torch.tensor([2,2])+torch.normal(mean=0, std=0.2, size=[N//2,2])
y_train2=torch.ones(N//2,1,dtype=torch.long)

x_train=torch.cat([x_train1, x_train2])
y_train=torch.cat([y_train1, y_train2])

# 显示数据
plt.scatter(x_train[:,0],x_train[:,1],c=y_train[:,0])
plt.colorbar()
plt.show()

建立模型

class Net(nn.Module):
    def __init__(self, in_features, out_features):
        super().__init__()
        self.layer1=nn.Linear(in_features,out_features)
        #nn.Softmax(dim=1)  #CrossEntropyLoss包含了softmax,log,和NLLloss
                
    def forward(self, x):
        return self.layer1(x)
    
net = Net(2,2)

配置模型

nn.init.normal_(net.layer1.weight, mean=0, std=0.1)
nn.init.constant_(net.layer1.bias, val=0)
crossloss = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.03)

训练模型

for epoch in range(1001):
    y_predict = net(x_train)
    loss=crossloss(y_predict, y_train.view(-1)) #y_predict形状(N,2), y参数形状(N,)
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()
    
    if(epoch%100==0):
        p = torch.softmax(y_predict,dim=-1).data.numpy()
        print(f"epoch:{epoch}, probability:{p[0]}, loss:{loss}")

查看结果

# 可视化显示

plt.scatter(x_train[:,0], x_train[:,1], c=p[:,0]) #直接用分类1的概率表示颜色绘制
plt.colorbar()
plt.show()
## 分别用0和1表示两个分类
p[p[:,0]>p[:,1]]=0
p[p[:,0]<p[:,1]]=1
plt.scatter(x_train[:,0], x_train[:,1], c=p[:,0]) #直接用分类1的概率表示颜色绘制
plt.colorbar()
plt.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pytoch人工神经网络基础:最简单的分类(softmax回归+交叉熵分类) 的相关文章

随机推荐

  • 树莓派VNC配置教程

    VNC可以实现连接到树莓派后 xff0c 用电脑直接控制树莓派 xff0c 下面是VNC配置教程 xff1a 首先在电脑端上安装VNC xff08 官网下载地址 xff09 xff1a xff08 选择对应的版本 xff0c 下载安装即可
  • 用VSCode优雅的写MySQL

    一 SQL的部署 首先是部署MySQL xff0c 本地的MySQL在官网上下载包后 xff0c 按照默认的安装即可 xff0c 我使用的腾讯云的 云MySQL xff0c 可以到腾讯云官网租用 在租好数据库后 xff0c 进入控制台 xf
  • 机器学习笔记 五:逻辑回归(Logistics Regression)及两个分类案例

    目录 1 前言2 实现过程2 1 数据可视化过程2 2 Sigmoid函数2 3 代价函数 xff08 costFunction xff09 2 4 其他设置2 5 梯度下降函数2 5 1 梯度下降结果 xff08 初始参数为0 xff09
  • 器:ubnutu系统完美克隆至新硬盘,系统备份迁移至新硬盘(机器)

    一切皆为文件 xff0c 这个理念真酷 xff01 很好 xff01 ubuntu16 04 系统备份还原迁移至新机器 亲测可用 xff0c 刚刚克隆完毕 1 打包整个系统 xff1a sudo su cd tar czvpf sys ba
  • tools:nerd font debian(ubuntu maybe the same)

    i get garbled in my nerdtree try to fix this bug down load this by yourself bug nerdtree 显示图标乱码 CSDN博客 download font by
  • Ubuntu 设置环境变量问题总结

    一 动态链接库问题 最近一直被 error while loading shared libraies 错误困扰 xff0c 于是简单的总结了一下Ubuntu 环境变量的设置问题 从下面几个方面来说 xff1a 1 系统默认库 1 xff0
  • Python之配置日志的几种方式(logging模块)

    作为开发者 xff0c 我们可以通过以下3种方式来配置logging 1 xff09 使用Python代码显式的创建loggers handlers和formatters并分别调用它们的配置函数 xff1b 2 xff09 创建一个日志配置
  • 硬盘分区、挂载及Ubuntu系统安装

    Linux发行版按照打包方式划分主要包括Debian系 基于Dpkg Red Hat系 基于RPM Slackware系等 xff0c 其中Debian系 Red Hat系是我们所常见的 xff0c 前者包括Ubuntu Debian GN
  • Ubuntu安装cuDNN

    一 官网下载与自己CUDA版本匹配的安装包 cudnn xff08 版本号 xff09 tgz 二 安装cuDNN tar xzvf cudnn xff08 版本号 xff09 tgz cuda Tab sudo cp cuda inclu
  • MySQL配置SSL访问-WEB配置JDBC支持SSL

    WEB配置JDBC支持SSL Connector J 可以使用 SSL 加密 JDBC 驱动程序和服务器之间通信的所有数据 xff08 初始握手除外 xff09 启用连接加密会带来性能损失 xff0c 其严重程度取决于多种因素 xff0c
  • MySQL配置SSL访问-ETL配置JDBC支持SSL

    创建用户 SSL TLS 选项 除了基于用户名和凭据的常规身份验证之外 xff0c MySQL 还可以检查 X 509 证书属性 要为 MySQL 帐户指定 SSL TLS 相关选项 xff0c 请使用REQUIRE指定一个或多个tls o
  • Python 使用docx库操作word文档中的表格单元格内容

    1 导入库 from docx import Document 2 加载word文档对象 doc 61 Document path 3 定位表格 获取所有表格对象 tables 61 doc tables 获取word中第一个表格对象 ta
  • 人工智能导论(6)——机器学习(Machine Learning)

    文章目录 一 概述二 重点内容三 思维导图四 重点知识笔记1 概述1 1 基本概念1 2 机器学习的分类 2 常见有监督学习算法2 1 线性回归2 2 多项式回归2 3 支持向量机2 4 k 最近邻分类2 5 朴素贝叶斯2 6 决策树2 7
  • Ubuntu 22.04 Anaconda和jupyter notebook安装问题

    安装Anaconda的安装问题是 xff1a conda command not found 在terminal 输入 vim bashrc conda 初始化在最末端 xff0c 把带 都删除即可 前提是 xff0c 安装时候已经设置了路
  • 人工智能导论(10)——机器人(Robot)

    文章目录 一 概述二 重点内容三 思维导图四 重点知识笔记机器人分类工业机器人服务机器人一般机器人智能机器人机器人与人工智能 一 概述 机器人是靠自身动力和控制能力来实现各种功能的一种机器 本文将人工智能 34 机器人 34 基础知识整理为
  • Numpy系列(八):函数库之5傅里叶变换函数

    Numpy系列目录 文章目录 一 简介二 思维导图三 傅里叶变换基础知识1 傅里叶级数2 复数形式傅里叶级数3 傅里叶变换4 离散傅里叶变换 四 Numpy快速傅里叶变换1 标准FFT1 1 一维离散FFT1 2 一维离散FFT反变换1 3
  • Matplotlib系列(五):三维绘图

    Matplotlib系列目录 文章目录 一 简介二 思维导图三 Matplotlib三维图形1 绘制3d图形2 基本三维图像2 1 3d折线图2 2 3d散点图2 3 3d柱形图2 4 3d火柴图2 5 3d误差图 3 三维曲面3 1 3d
  • Seaborn系列(三):分布统计绘图(distribution)

    Seaborn系列目录 文章目录 1 分布统计绘图API概述2 displot单变量分布图 直方图 核密度 累积分布 2 1 displot函数绘制单变量分布图2 2 displot直方图kde图同时叠加绘制2 3 displot绘图同时叠
  • pytorch人工神经网络基础:线性回归神经网络(nn.Module+nn.Sequential+nn.Linear+nn.init+optim.SGD)

    线性回归是人工神经网络的基础 xff0c 线性回归属于有监督的学习 xff0c 即根据有标签 xff08 已知结果的数据 xff09 拟合线性方程权重 xff0c 然后根据拟合的方程预测未知数据 通常步骤为 xff1a 准备数据 xff1a
  • pytoch人工神经网络基础:最简单的分类(softmax回归+交叉熵分类)

    softmax回归分类原理 对于回归问题 xff0c 可以用模型预测值与真实值比较 xff0c 用均方误差这样的损失函数表示误差 xff0c 迭代使误差最小训练模型 那么分类问题是否可以用线性回归模型预测呢 最简单的方法就是用softmax