当前位置: 首页 > news >正文

python与pytroch相关

1.pytroch模型类

        PyTorch 是一个易学且清晰明了的深度学习库。本节讲解如何查看一个模型的结构。 首先,最简单创建模型的方式如下:

#导入必要的库
import torch.nn as nn
myNet=nn.Sequential(nn.Linear(2,10),#第一层(全连接层):接受两个输入特征,输出10个特征nn.ReLU(),#对第一层的输出进行非线性变换,增加网络的表达能力,对第一层的输出进行非线性变换,增加网络的表达能力nn.Linear(10,1)#将ReLU层的10个输出特征映射到1个输出特征nn.Sigmoid()#将第二层的输出转换为0到1之间的值,常用于二分类问题中将输出转换为概率。
)

一般来说,PyTorch 的模型都会定义成一个类,然后在主函数中直接实例化这个类。比如类是设计图,实例化就是按照这个设 计图做出来的实物。

#导入必要的库
import torch
import torch.nn as nn
import torch.nn.functional as F #torch.nn.functional 包含了一些函数式的接口,可以用来构建自定义的前向传播。
#开始定义模型类
class Network(nn.Module):#定义了一个名为 Network 的新类,它继承自 nn.Module。nn.Module 是PyTorch中所有神经网络模块的基类def __init __(self):#这行代码调用了父类 nn.Module 的构造函数。super(Network,self). __init __()#定义了一个名为 dis 的 nn.Sequential 模型self.dis=nn.Sequential(nn.Linear(2,32),#nn.Sequential 是一个容器,它按照它们在构造器中传递的顺序执行模块nn.LeakyReLU(0.2),#这是一种改进的ReLU函数,它允许负输入有一个小的非零输出,这有助于解决梯度消失问题。参数 0.2 指定了负斜率nn.Linear(32,32),nn.LeakyReLU(0.2),nn.Linear(32,1),nn.Sigmoid()#这是一个将输出值压缩到0和1之间的激活函数,通常用于二分类问题的输出层)#模型包含三个全连接层(nn.Linear)和两个 LeakyReLU 激活函数,最后是一个 Sigmoid 激活函数。每个 nn.Linear 层都指定了输入和输出的特征数量。def forward(self,x):#forward 方法定义了数据通过模型的前向传播路径。在这个方法中,输入数据 x 通过 dis 序列模型进行处理,然后返回处理后的结果x=self.dis(x)return x#梯度消失(Vanishing Gradients)是深度学习中常见的一个问题,特别是在训练深层神经网络时。这个问题指的是在反向传播过程中,梯度(误差的导数)随着层数的增加而迅速减小# 最终变得非常接近于零。当梯度非常小的时候,权重的更新也会非常小,导致网络学习速度极慢,甚至完全停止学习。

下面是一个标准的pytroch模型的定义:

#导入必要的库
import torch 
import torch.nn as nn
import torch.nn.functional as F
#开始定义模型类
class Network(nn.Module):## 开始定义模型类
class Network(nn.Module):def __init __(self):super(Network,self). init__()#__init__ 方法在创建类的新实例时被调用self.dis=nn.Sequential(#这里创建了一个 nn.Sequential 容器,它按照它们在构造器中被添加的顺序执行每个模块nn.Linear(2,32),#nn.Linear(2, 32) 创建了一个全连接层,它将输入的2维向量转换为32维的向量nn.LeakyReLU(0.2),#创建了一个LeakyReLU激活函数,它允许小的梯度值通过,参数0.2是负斜率。nn.Linear(32,32),nn.LeakReLU(0.2),nn.Linear(32,1),#nn.Linear(32, 1) 创建了一个全连接层,它将32维的向量转换为1维的向量。nn.Sigmoid()#nn.Sigmoid() 添加了一个Sigmoid激活函数,它将输出值压缩到0和1之间,通常用于二分类问题中。)
def forward(self,x):x=self.dis(x)return x
#在神经网络中,激活函数是用来增加网络的非线性特性的。没有激活函数,即使网络有很多层
# 它也只是一个简单的线性变换,无法解决复杂的非线性问题。

(1)必须要继承 nn.Module  所以假设在阅读一个新的PyTorch  编写的代码时,只需要找到nn.Module,  就可以知道代码中定义模型的地方了。

#实例化网络
Net=vetwor1()

该模型本质上就是一个函数, 一个映射关系,输入数据时可以根据这个函数关系计算出输出数据。现在创建一些输入数据

#创建一些数据
input=torch.FloatTensor(5,2)
print(input)

输入数据

output=net(input)

在实例化网络时:net=Network(),这个过程调用了Network  类中的__init_函数。

(2)在网络接收到输入数据input 时,实际上是调用了Network 类中的 forward 函数, 也可以说调用了net 这个实例的forward 函数;forward 函数中的x 其实就是输入数据 input,forward 函数return 回来的值就是 output 值。

class Network(nn.Module)def __init __(self):super(Network,self). __init__()self.dis1=nn.Sequential(nn.Linear(2,32),nn.LeakyReLU(0.2),nn.Linear(32,32),nn.LeakyReLU(0.2))self.dis2=nn.Sequential(nn.Linear(16,1),nn.Sigmoid())def forward(self,x):x=self.dis1(x)output1=x.view(-1,16)output2=self.dis2(output1)return output1,output2

 2.PyTorch data

        对于深度学习,整个流程比较重要的两个部分一个是之前讲的模型的定义,另外一个就 是数据的处理。模型其实对于数据的要求是比较高的, 一个是需要数据的质量高, 一个就是 要求数据的格式统一。

        例如, 一个图像分类的卷积模型的输入图片,假设模型输入要求大小为416像素的正方形图片。而原始图片是长方形或者尺寸大小不是416的图片,这样就需要对图片进行一些预处理,比方说在原始图片中剪裁出416的正方形部分或者把原始图片压缩到416像素大小。  这次主要讲解就是PyTorch 中另外两个类,DataLoader类和Dataset类。    

#训练模型for epoch in range(num_epoch)
#它用于将一个可迭代对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,通常用于for循环中for i,data in enumerate(loader):

        第一层循环就是要循环的 epoch  次数,第二层就是要讲的 DataLoader  了,从 DataLoader中用循环的方式不断取出来一个 batch的数据。可以把DataLoader看成[第一 batch  的数据,第二个 batch  的数据,第三个 batch 的数据....

#从dataloader中取数据
#dataloader的实例化
loader=DataLoader(dataset=set,batch size=2)#dataset为数据集

Dataset 就是定义每一个 batch 的数据的。例如:

from torch.utils.data import Dataset,DataLoader#导入必要的库
#Dataset 是一个抽象类,用于定义数据集的结构和如何访问数据。DataLoader 是一个迭代器
# 它封装了 Dataset 对象,并提供了批量获取数据、打乱数据、多线程加载等功能。
import os 
class MyDataset1(Dataset):def __init__(self):self.data=['我','爱','祖','国']def __getitem__(self,index):return self.data[index]def __len__(self):return len(self.data)#它返回数据集的总大小。这里它返回 self.data 列表的长度#实例化数据集类set=MyDataset1()loader=DataLoader(dataset=set,batch_size=2)#这里首先创建了 MyDataset1 类的一个实例 set,然后使用 DataLoader 来包装这个实例。#DataLoader 的 batch_size=2 参数指定了每个批次的数据项数量print("len(loader):",len(loader))#从dataloader中抽取batch数据for data in loader:print(data)
3.激活函数

        激活函数其实是神经网络可以拟合任意函数的灵魂。假设一个两输入、 一输出的全连接网络没有激活函数,那么每一层之间的关系都是wx+b  的形式。无论有多少层,每一层 有多少的神经元,最后总可以用y=Cx+cx+c 这样的公式表示。线性的堆积多少层都是线性的。然而在利用神经网络分类的时候,很多分类界限是非线性的。简单来说, 激活函数可以把线性的关系映射成非线性的,这样神经网络才有能力去逼近任意的函数。

        激活函数有几十种之多,这里主要介绍常见的几种激活函数。首先介绍PyTorch 深度学习库中已经封装好的激活函数:

import torch.nn as nn
import matplotlib.pyplot as plt#Matplotlib 的 pyplot 模块,它用于绘制图形
#随便定义一个画图函数
def plot(x,y,name=""):plt.plot(x,y,'r')#x 是横坐标数据,y 是纵坐标数据,name 是图形的标题。
#函数使用 Matplotlib 的 plot 函数绘制 x 和 y,设置坐标轴的范围,显示网格,并设置标题plt.xlim((-2,2))plt.ylim((-2,2))plt.grid()plt.title(name)
x=torch.arange(-2,2,0.01)
Activation=nn.ReLU()#这里创建了一个 ReLU 激活函数的实例
y=Activation(x)#应用 ReLU 激活函数到 x 上,得到 y
plot(x,y,'ReLU')#这里调用之前定义的 plot 函数,传入 x、y 和标题 'ReLU'。
plt.show()#这行代码调用 Matplotlib 的 show 函数,将绘制好的图形显示出来。

  四个经典的激活函数:

(1)ReLU:   线性整流单元。由图可以看出,大于零的值经过这个函数没有影响,小于0的值经过这个激活函数会变成0。数学表达:ReLU(x)=  max(0,x)

优点1:ReLU  的收敛速度快于Sigmoid/Tanh   (因为Sigmoid 激活函数的最大值只有 1,而ReLU 没有最大值的限制)。

优点2:ReLU  要求的计算量小,因为没有指数运算( Sigmoid  的数学表达)。

缺点:ReLU  对于小于0的数据的梯度是0(因为ReLU  的导数在x<0    的时候是0,而 不是因为ReLU  x<0   的时候为0)。梯度为0意味着不会再更新,不会再更新意味着梯 度一直是0,这样神经元就“坏死”了,没用了。避免这样情况发生的操作就是设置一个比较 小的学习率

(2)Sigmoid:    把输入压缩成0~1的值,负无穷映射0,正无穷映射1。数学表达:

优点:非线性的经典激活函数,而且压缩成0~1刚好体现了概率值。在图像分类任务 中,希望模型输出的正是输入图像属于每一个类别的概率。

缺点1:依然是梯度消失问题。与 ReLU  的坏死类似,当输入非常大或者非常小的时候,可以发现 Sigmoid  的导数近乎为0,这样就产生了梯度消失问题。

缺点2:不难发现,因为输出的数据是0~1,所以 Sigmoid 的输出不是0均值的(zero- centered,以0为中心),导致收敛速度缓慢。

缺点3:包含指数运算,计算量大。但是其实这个计算量相对于整个模型的计算,九牛 一毛,这个缺点其实不算什么问题

3.Tanh: 与 Sigmoid类似。数据的输出范围是[-1,1]。数学表达: 

优点:从图中看到,解决了Sigmoid  zero-centered的问题。

缺点:依然存在gradient   vanishing 的问题。

4.LeakyReLU:      ReLU  的改进版本,为了解决ReLU  的坏死问题,LeakyReLU  x<0  的时候用一个较小的斜率(图中的斜率是0.1,不过一般默认是0.01)。

优点:解决了ReLU  的坏死问题。

缺点:x<0 斜率的取值是  个问题。这里简单提及   PReLU 激活函数 ,这是一个可以根据训练过程,自动找到一个好的斜率的 LeakyReLU  换句话说,PReLU  x<0   部分的斜率也参与到了梯度下降中。

        以上就是常见的4种激活函数。最后再提一下 Softmax  激活函数这个不与上面的放在一起是因为这个函数的输入要求多个值, 一般用在多分类任务。数学表达式上。

损失函数

均 方 误  

均方误差(Mean   Squared   Error,MSE)非常经典,是真实值和估计值的差的平方的期望。数学公式是:

先设置两个变量:

a=torch.FloatTensor([1,1,1])
b=torch.FloatTensor([1,2,4])

在上面的两个变量a、b中 ,batch是3。来计算一下a 和b 的均方误差:

#定义loss函数
loss_function=nn.MSELoss()
#loss_function=nn.MSELoss(reduction='mean')
print(loss_function(a,b))

         就是说如果输入“reduction='sum'”,    那么会返回10,MSE 公式中求均值就会变成求 和,上式中就不会先乘以1/3。reduction默认是求均值, 一般使用的也是求均值的版本。

交叉熵

        交叉熵是最常见的Loss 函数,经常用来处理多分类问题,当然也 可以处理二分类问题。想象一个多分类的神经网络,这个网络输出层的节点个数应该是与分类任务的类别数量相等,假设这是一个三分类问题(猫、狗、鸟),有一个样本狗的图片,所以这个样本的分类真实值应该是1(如果是猫的话就是0,如果是鸟的话就是2)。

        Softmax 的意义就是把这些没有限制的值变成概率值,把模型打分的高低转换成图片 属于某一个类别的概率。图片被模型判断正确的概率越大,交叉熵越小。交叉熵是表明际输出的概率与期望输出的概率的距离,交叉熵越小,两个概率越接近。

        交叉熵CrossEntropy 就是完全等价于一个 Softmax+ 自然对数In+NLLLoss。 一般如果 Softmax  在模型中嵌入了,那就直接可以NLLLoss 作为损失函数。

#计算softmax
output=torch.FloatTensor([-1,0.5,2],[-1,0.5,2],[-1,0.5,3])
Softmax=nn.Softmax(dim=1)#dim=1 指定了 Softmax 函数沿着哪个维度(列)进行计算。在这个例子中,我们希望对每一行的元素进行 Softmax 计算,因此 dim=1
output=Softmax(output)#将 Softmax 函数应用于 output 张量,计算每一行的 Softma
print('做一个Softmax:\n{}'.format(output))
#求自然对数
output=torch.log(output)
print('做一个自然对数:\n{}'.format(output))
#计算NLLLoss
NLLLoss=nn.NLLLoss()
output=NLLLoss(output,torch.tensor([1,2]))
print('做一个NLLLoss:{}'.format())
#使用 PyTorch 框架中的 CrossEntropyLoss 函数来计算交叉熵损失
output=torch.FloatTensor([-1,0.5,2],[-1,0.5,3])
loss_function=nn.CrossEntropyLoss()#CrossEntropyLoss 需要两个参数:模型的输出(logits)和目标标签(ground truth labels)。
CE=loss_function(output,torch.tensor([1,2]))#这里调用 loss_function 计算交叉熵损失
#第一个参数是模型的输出 output,第二个参数是目标标签,这里使用 torch.tensor([1, 2]) 表示第一个样本的正确类别是索引 1(对应第二个元素),第二个样本的正确类别是索引 2(对应第三个元素)
print('用CrossEntropyLoss:{}'.format(CE))#这行代码打印出计算得到的交叉熵损失值

         在代码中可能会看到这样的代码,在训练的时候调用model.train()  告诉模型现在要开 始训练了,在测试或者验证的时候调用model.eval()告诉模型现在不训练了。

(1)model.train()是启用模型的 BatchNormalization Dropout层; (2)model.eval()    是限制模型的BatchNormalization  Dropout 层。

在学习了 BN  层之后,可以知道BN  算均值和方差是需要一整个 batch 的数据进行计算的。batch是指一次训练或推断中的一组数据样本。

BN的数学公式如下:

        gamma  beta是训练中学习的参数,在测试过程中,已经训练完成并且固定下来了, 那均值和方差就是用训练集的全部样本来计算均值和方差。Dropout层则更简单,如果是训练过程,就让一定量的神经元失活,即让这个神经元不 再输出内容,在测试过程中,Dropout  层失效,没有神经元失活。假设 Dropout     rate=0.2,就是会有20%的神经元失活,那么存活的80%的神经元输出 的值就要除以0.8来抵消有20%神经元失活的事实。

(1)model.train()       BN 层的训练,并且求取一个 batch 数据的均值和方差; Dropout层正常启用,并且存活的神经元输出值会经过处理来抵消Dropout 失活的影响。

(2)model.eval()限制 BN 层,参数不再学习,使用所有训练数据求取均值和方差; Dropout 禁止使用,不对神经元输出值做任何处理。

注意:一般BN 层和Dropout 层不同时使用。

Python的命令行库argparse
import argparse# 创建 ArgumentParser 对象,并设置描述
parser = argparse.ArgumentParser(description='这里一般是讲述代码是干什么的')
# 使用 add_argument 方法添加命令行参数:--name 和 --age
# 每个参数都有一个默认值(default),一个帮助信息(help),以及一个标识符(--name 或 --age)
parser.add_argument('--name', default='啥也没写', help='这里输入你的名字')
parser.add_argument('--age', default='不告诉你我几岁', help='这里输入你的年龄')# 解析命令行参数
args = parser.parse_args()# 打印解析后的参数值
print('你的名字:{}'.format(args.name))
print('你的年龄:{}'.format(args.age))

就算有了命令行库,也是可以照常运行代码的。不管遇到什么代码,只要输入“-help”就可以查询如何正确地使用这个命令行,并且查 询到每一个属性的help内容。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • linux 下一跳缓存,early demux(‌早期解复用)‌介绍
  • 探索PDF的奥秘:pdfrw库的神奇之旅
  • 32 配置多路由的静态路由
  • https和harbor仓库跟k8s
  • VsCode + Go + macOS 小白 demo运行
  • 浏览器自动化测试的利器:Cypress
  • AI大模型实战:pytorch安装
  • glsl着色器学习(七)
  • 从源码角度分析 Kotlin by lazy 的实现
  • accelerate一些类和函数说明二
  • 集合及映射
  • linux批量解压tar.gz文件
  • 动态规划-最大子数组和
  • STM32的CRC校验(基于HAL库)
  • c++面向对象程序设计中的二义性及解决办法--郭妍论文
  • 11111111
  • CentOS6 编译安装 redis-3.2.3
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • C语言笔记(第一章:C语言编程)
  • Docker容器管理
  • ES6系列(二)变量的解构赋值
  • git 常用命令
  • Golang-长连接-状态推送
  • IOS评论框不贴底(ios12新bug)
  • MD5加密原理解析及OC版原理实现
  • mysql 数据库四种事务隔离级别
  • MySQL用户中的%到底包不包括localhost?
  • React的组件模式
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 入口文件开始,分析Vue源码实现
  • 微服务框架lagom
  • 译米田引理
  • puppet连载22:define用法
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​插件化DPI在商用WIFI中的价值
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​水经微图Web1.5.0版即将上线
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #pragma pack(1)
  • #传输# #传输数据判断#
  • (11)MATLAB PCA+SVM 人脸识别
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (7)摄像机和云台
  • (Java入门)抽象类,接口,内部类
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (六)c52学习之旅-独立按键
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (三分钟)速览传统边缘检测算子
  • (四) Graphivz 颜色选择
  • (转)Google的Objective-C编码规范
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)