深度学习--PyTorch框架&优化器&激活函数

一、深度学习常用 的框架

1.Caffe

优点:只需要配置文件即可搭建深度神经网络模型

缺点:安装麻烦,缺失很多新网络模型,近几年几乎不更新

2.TensorFlow

Google公司开发:

1.x版本:缺点:代码比较冗余,上手有难度

2.x版本:收购了keras,代码不兼容1.x版本

3.Keras

在tensorflow基础上做了封装,优点:简化代码难度

4.PyTorch

Facebook公司开发:

优点:上手极容易,直接套用模板

二、PyTorch安装

在我之前所写的博客中有提到,详情可以看

https://blog.csdn.net/2301_77717128/article/details/156355662?spm=1001.2014.3001.5501

三、PyTorch框架

利用mnist数据集实现神经网络的图像识别。

四、优化器

1.批量梯度下降法(Batch Gradient Descent)BGD

使用全样本数据计算梯度,例如一个batch_size=64,计算出64个梯度值

好处:收敛次数少。

坏处:每次迭代需要用到所有数据,占用内存大耗时大

2.随机梯度下降法(Stochastic Gradient Descent)SDG

从64个样本中随机抽出一组,训练后按梯度更新一次

优点:速度快。

缺点:可能陷入局部最优,搜索起来比较盲目,并不是每次都朝着最优的方向

3.小批量梯度下降法(Mini-batch Gradient Descent)

将训练数据集分成小批量用于计算模型误差和更新模型参数。

是批量梯度下降法和随机梯度下降法的结合

4.自适应矩估计(Adaptive Moment Estimation) Adam
5.动量梯度下降(Momentum Gradient Descent)
6.AdaGrad
7.RMSprop
8.AdamW
9.Adadelta

五、激活函数

1.梯度消失

如果连乘的因子大部分小于1,最后乘积的结果可能趋于0,也就是梯度消失,后面的网络层的参数不发生变化.

2.梯度爆炸

如果连乘的因子大部分大于1,最后乘积可能趋于无穷,这就是梯度爆炸

3.造成原因

梯度反向传播中的连乘效应。对于更普遍的梯度消失问题,可以考虑以下方案解决:

用ReLU、tanh、P-ReLU、R-ReLU、Maxout等替代sigmoid函数。

ReLU:如果激活函数的导数是1,那么就没有梯度消失问题

代码运用

python 复制代码
import torch
import torchvision
import torchaudio

print(torch.__version__)#1.X
print(torchvision.__version__)#1.X
print(torchaudio.__version__)
'''mnist包含70.000张手写数字图像:60.000张用于训练,10.000张用于测试
图像是灰度的,28x28像素的,并且居中的,以减少预处理和加快运行
'''
import torch
from torch import nn#导入神经网络模块,
from torch.utils.data import DataLoader#数据包管理工具,打包数据
from torchvision import datasets # 封装了很多与图像相关的模型,数据集
from torchvision.transforms import ToTensor
#数据转换,张量,将其他类型的数据转换为tensor张量,numpy array

'''下载训练数据集(包含训练图片+标签)'''
training_data= datasets.MNIST( #跳转到函数的内部源代码,pycharm 按下ctrl +鼠标点击
root="data",#表示下载的手写数字 到哪个路径。60000
train=True,#读取下载后的数据 中的 训练集
download=True,#如果你之前已经下载过了,就不用再下载
transform=ToTensor(),#张量,图片是不能直接传入神经网络模型
)#对于pytorch库能够识别的数据一般是tensor张量

# datasets.MNIST的参数:
# root(string):表示数据集的根目录
# train(bool,optional):如果为true,则从trainingpt创建数据集,否则从test.pt创建数据集
# download(bool,optional):如果为true,则从internet下载数据集并将其放入根目录,如果数据集已经下载,则不会再次下载
# transform(callable,optional):接收pil图片并返回转换后版本图片的转换函数

'''下载测试数据集(包含训练图片+标签)'''
test_data = datasets.MNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),#Tensor是在深度学习中提出并广泛应用的数据类型,它与深度学习框架(如 PyTorch、TensorFlow)紧密集成,方便进行神经网络的训练和)
)#NumPy 数组只能在CPU上运行。Tensor可以在GPU上运行,这在深度学习应用中可以显著提高计算速度。
print(len(training_data))

'''展示手写字图片,把训练数据集中前19000张图片展示一下'''
from matplotlib import pyplot as plt
figue=plt.figure()
for i in range(9):
    img,label=training_data[i+59000]#提取第59000张图片

    figue.add_subplot(3,3,i+1)#图像窗口中创建多个小窗口,小窗口用于显示图片
    plt.title(label)
    plt.axis("off")#plt.show()#显示矢量
    plt.imshow(img.squeeze(),cmap="gray")#plt.imshow()将NumPy数组data中的数据显示为图像,并在图形窗口中显示该图像
    a=img.squeeze()# img.squeeze()从张量imng中去掉维度为1的。如果该维度的大小不为1则张量不会改变。#cmap="gray"表示使用灰度色彩映射来显示图像。
# plt.show()

'''创建数据dataloader(数据加载器)
batch_size:将数据集分成多分,每一份为batch------size个数据
优点:可以减少内存的使用,提高训练速度'''
train_dataloader = DataLoader(training_data, batch_size=64)
#64张图片为一个包,更换批次的大小也可以调整最后准确率(2的指数)
test_dataloader = DataLoader(test_data, batch_size=64)
for X,y in test_dataloader:#X是表示打包好的每一个数据包
    print(f"Shape of X[N,C,H,W]:{X.shape}")
    print(f"Shape of y:{y.shape} {y.dtype}")
    break
'''判断当前设备是否支持GPU,其中mps是苹果m系列芯片的GPU'''#返回cuda,mps,cpu m1,m2,集显cpu+gpu rtx3060
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else 'cpu'
print(f"Using {device} device")#字符串格式化。CUDA驱动软件的功能,pytorch能够去执行cuda的命令,cuda通过GPU指令集去控制GPU
#神经网络的模型也需要传入到GPU,1个batchsize的数据集也需要传入GPU才可以进行训练

'''定义神经网络 类的继承'''
class NeuralNetwork(nn.Module):#通过调用类的形式来使用神经网络,神经网络的模型,nn.module
    def __init__(self):#python的基础关于类,self类自己本身
        super().__init__()#继承的父类初始化
        self.a = 10
        self.flatten=nn.Flatten()#展开,创建一个展开对象flatten
        self.hidden1=nn.Linear(28*28,out_features=128)#第一个参数:有多少个神经元传入进来,第二个参数:有多少个数据
        self.hidden2=nn.Linear(in_features=128,out_features=256)
        self.hidden3=nn.Linear(in_features=256,out_features=512)
        self.out=nn.Linear(in_features=512,out_features=10)#输出必须和标签的类别相同,输入必须是上一层的神经元个数
        self.dropout=nn.Dropout(0.2)
    def forward(self,x):#前向传播,你要告诉他数据的流向,视神经网络层连接起来,函数名称不能改。
        # x= self.flatten(x)#图像进行展开
        # x= self.hidden1(x)
        # x= torch.sigmoid(x)#激活函数,torch使用的relu函数relu:tanh
        # x= self.hidden2(x)
        # x= torch.sigmoid(x)
        # x= self.out(x)
        x= self.flatten(x)#图像进行展开
        x= torch.relu(self.hidden1(x))#图像进行展开
        x= self.dropout(x)
        x= torch.relu(self.hidden2(x))#激活函数,torch使用的relu函数relu:tanh
        x= self.dropout(x)
        x= torch.relu(self.hidden3(x))
        x= self.out(x)
        return x

model =NeuralNetwork().to(device)#把刚刚创建的模型传入到GpU
print(model)

def train(dataloader,model,loss_fn,optimizer):
    model.train()#告诉模型,我要开始训练,模型中w进行随机化操作,已经更新w,在训练过程中,w会被修改的
#pytorch提供2种方式来切换训练和测试的模式,分别是:model.train()和model.eval()
#一般用法是:在训练开始之前写上model.trian(),在测试时写上model.eval()
    batch_size_num=1#统计训练的batch数量
    for X,y in dataloader:#其中batch为每一个数据的编号
        X,y = X.to(device),y.to(device)  # 把训练数据集和标签传入cpu或GPU
        pred = model.forward(X)#.forward可以被省略,父类中已经对此功能进行了设置,
        loss = loss_fn(pred,y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        loss_value = loss.item()
        if batch_size_num %100==0:
            print(f"loss:{loss_value:>7f} [number:{batch_size_num}]")
        batch_size_num +=1

def test (dataloader,model,loss_fn):
    '''测试函数'''
    size=len(dataloader.dataset)
    num_batchs=len(dataloader)
    model.eval()
    test_loss, correct = 0,0
    with torch.no_grad():
        for X,y in dataloader:
            X,y = X.to(device),y.to(device)
            pred = model.forward(X)
            test_loss += loss_fn(pred,y).item()  # test_loss是会自动累加每一个批次的损失值
            correct +=(pred.argmax(1)== y).type(torch.float).sum().item() # 标量
            a=(pred.argmax(1)== y) # dim=1表示每一行中的最大值对应的索引号,dim=日表示每一列中的最大值对应的索引号
            b=(pred.argmax(1)== y).type(torch.float)

    test_loss /= num_batchs
    correct /= size

    print(f"结果: \n Accuracy :{(100*correct)}%,Avg loss:{test_loss}")
loss_fn=nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)#尝试不同的值可以确保最后的准确率
#SGD改为Adom优化器(通常效果更好)
# train(train_dataloader,model,loss_fn,optimizer)
# test(test_dataloader,model,loss_fn)

epochs=10
for t in range(epochs):
    print(f"Epoch{t+1}\n开始训练")
    train(train_dataloader,model,loss_fn,optimizer)
print("训练结束!")
test(test_dataloader,model,loss_fn)

当训练结果准确率不高时,可以通过调整优化器来实现

相关推荐
sww_10262 小时前
智能问数系统(三):生成数据报告
人工智能·html5
夜勤月2 小时前
数据中台的最后一块拼图:利用 MCP 统一企业所有异构数据源,打造 AI 原生数据底座
人工智能
永霖光电_UVLED2 小时前
Enphase 开启首台基于氮化镓(GaN)微逆变器的量产
人工智能·神经网络·生成对抗网络
The Open Group2 小时前
AI 时代的架构挑战:用标准化方法驾驭智能化复杂性
大数据·人工智能·架构
忆~遂愿2 小时前
告别听歌枷锁 R3PLAY + cpolar 实现真正的听歌自由
人工智能
o(╥﹏╥)2 小时前
Learn how Gen AI 学习笔记
人工智能·笔记·学习
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-教学管理与用户管理模块联合回归测试文档
java·前端·数据库·人工智能·spring boot
Knight_AL2 小时前
一文讲透 Java 中transient的用处(结合 Flink 理解)
java·python·flink
独行soc2 小时前
2026年渗透测试面试题总结-5(题目+回答)
android·网络·python·安全·web安全·渗透测试