激活函数Relu对精度和损失的影响研究

news2024/12/28 20:11:33

1 问题

在学习深度学习的过程中,欲探究激活函数Relu对精度和损失的影响。

2 方法

测试设置激活函数时和没有设置激活函数时网络的性能。

控制其余变量:

  • Beach_size=128

  • optimizer = torch.optim.SGD

  • 网络为三层全连接网络(784->512->10)

  • 训练周期=50

测试代码如下

from torchvision import datasets
from torchvision.transforms import ToTensor
from torch import nn
import torch
from torch.utils.data import DataLoader
import torch.nn.functional as F
import matplotlib.pyplot as plt
from collections import defaultdict
# (5)定义三层全连接网络
# (5.1)创建一个新的类继承nn.Module
class MyNet(nn.Module):
   # (5.2) 定义网络有哪些层,这些层都作为成员变量
   def __init__(self) -> None:
       super().__init__()
       # 第一层,第一个全连接层Full Connection(FC)
       # in_features表示该层的前面一层神经元个数
       # out_features表示当前这的一层神经元个数
       # 对应图里面layer2
       self.fc1 = nn.Linear(in_features=784, out_features=512)  # in_features就是这一层的输入是多少纬的向量,
       # 对应layer3 也是就输出层
       self.fc2 = nn.Linear(in_features=512, out_features=10)  # feature特征
   # (5.3) 定义数据在网络中的流动 x就表示输入
   # x - 28*28的图像
   def forward(self, x):
       x=torch.flatten(x,1)
       x = self.fc1(x)  # 输出:512,Layer 2
       # x=F.relu(x)
       out = self.fc2(x)  # 输出:10,Layer 3
       return out
#(7)训练网络
#loss_list:记录每一个周期的平均loss数据
def train(dataloader,net,loss_fn,optimizer):
   size = len((dataloader.dataset))
   epoch_loss=0.0
   batch_num=len(dataloader)#有多少个batch
   net.train()
   correct = 0 #准确率
   #一个batch一个batch的训练网络
   for batch_ind, (X,y) in enumerate(dataloader):
       X,y=X.to(device),y.to(device) #gpu上运行X,y
       pred = net(X)
       #衡量y与y_hat之前的loss
       #y:128 ,pred:128*10 CrossEntropyLoss处理的
       loss=loss_fn(pred,y)
   #基于loss信息利用优化器从后向前更新网络的全部参数
       optimizer.zero_grad()
       loss.backward()
       optimizer.step()
       # print(f"batch index: {ind},loss:{loss.item()}")#item()方法将单个tensor转化成一个数字
       epoch_loss+=loss.item() #每一个batch产生一个loss
       correct+=(pred.argmax(1)==y).type(torch.float).sum().item()
       #f-str
       if batch_ind % 100==0:
           print(f'[{batch_ind+1 :>5d} / {batch_num :>5d}], loss:{loss.item()}')
   #统计一个周期的平均loss
   avg_loss=epoch_loss/batch_num
   avg_accurcy = correct / size
   return  avg_accurcy,avg_loss
def test(dataloder,net,loss):
   size=len(dataloder.dataset)
   batch_num = len(dataloder)
   net.eval()
   losses=0
   correct = 0
   with torch.no_grad():
       for X,y in dataloder:
           X,y = X.to(device),y.to(device)
           pred = net(X)
           loss = loss_fn(pred,y)
           losses+=loss.item() #一个batch产生一个loss
           correct+=(pred.argmax(1) ==y).type(torch.int).sum().item()
   accuracy = correct / size
   avg_loss = losses /batch_num
   print(f'accuracy is {accuracy*100}%')
   return accuracy,avg_loss
#数据的获取
class getData:
   def __init__(self):
       self.train_ds = datasets.MNIST(
           root='data',
           download=True,
           train=True,
           transform=ToTensor(),  # 将原始的数据格式(PIL)转换为Tensor格式
       )
       # 测试集:评估模型的性能/效果
       self.text_ds = datasets.MNIST(
           root='data',
           download=True,
           train=False,
           transform=ToTensor(),
       )
       # print(train_ds[0])
       # print(text_ds[0])
       # (3)
       self.train_loader = DataLoader(
           dataset=self.train_ds,
           batch_size=128,  # 将60000个数据分成每一段的大小是128
           shuffle=True,  # 每一次我去拿那个128的数据都是打乱的,不是有序的。1-60000 打乱数据的次序,一般用于训练集,不需要在测试集
       )
       # (4)
       # 训练集共有469个batch  469*128
       # print("训练集的batch{}".format(len(train_loader)))
       self.test_loader = DataLoader(
           dataset=self.text_ds,
           batch_size=128,
       )
if __name__=='__main__':
   #(0)测试机器是否支持GPU
   batch_size=128
   device='cuda' if torch.cuda.is_available() else 'cpu'
   # print(device)
   train_ds = datasets.MNIST(
       root='data',
       download=True,
       train=True,
       transform=ToTensor(),  # 将原始的数据格式(PIL)转换为Tensor格式
   )
   # 测试集:评估模型的性能/效果
   text_ds = datasets.MNIST(
       root='data',
       download=True,
       train=False,
       transform=ToTensor(),
   )
  #(1.1)将训练集划分为训练集+验证集
   train_ds,val_ds= torch.utils.data.random_split(train_ds,[50000,10000])
   # (3)
   train_loader = DataLoader(
       dataset=train_ds,
       batch_size=batch_size,  # 将60000个数据分成每一段的大小是128
       shuffle=True,  # 每一次我去拿那个128的数据都是打乱的,不是有序的。1-60000 打乱数据的次序,一般用于训练集,不需要在测试集
   )
   val_loder = DataLoader(
       dataset=val_ds,
       batch_size=batch_size,
   )
   # (4)
   # 训练集共有469个batch  469*128
   # print("训练集的batch{}".format(len(train_loader)))
   test_loader = DataLoader(
       dataset=text_ds,
       batch_size=batch_size,
   )
   #(6)网络的输入、输出以及测试网络的性能(不经过任何训练的网络)
   net=MyNet().to(device)#to()GPU上运行该网络
   #网络训练模型
   #X, 真实的标签y, 网络预测的标签y_hat
   #目标: y_hat越来越接近y
   #算法:mini-bacth 梯度下降
   #优化器
   #具体实现梯度下降算法的传播
   #SGD随机梯度下降学习度
   #y=ax+b
   optimizer=torch.optim.SGD(net.parameters(),lr=0.15)
   #损失函数
   #衡量yy与y_hat之前的差异
   loss_fn=nn.CrossEntropyLoss()
   #训练一下
   # train(train_loader,net,loss_fn,optimizer)
   #一个周期表示一个完整的训练集
   #训练100个周期epoch
   train_loss=[] #记录所有周期的平均loss
   train_acc_list,train_loss_list,val_acc_list,val_loss_list=[],[],[],[]
   #找出周期内最好的模型
   #评价标准:验证集的精度
   best_acc=0
   for epoch in range(50):
       print('-'*50)
       print(f'eopch:{epoch+1}')
       train_accuracy,train_loss=train(train_loader,net,loss_fn,optimizer)
       val_accuracy,val_loss =test(train_loader,net,loss_fn)
       print(f'train acc:{train_accuracy},train_val:{train_loss}')
       train_acc_list.append(train_accuracy)
       train_loss_list.append(train_loss)
       val_acc_list.append(val_accuracy)
       val_loss_list.append(val_loss)
       if val_accuracy > best_acc:
           best_acc = val_accuracy
           #保存当前模型
           torch.save(net.state_dict(),'model_best.pth')
   #(7)评估模型`
   #加载最好的模型
   net.load_state_dict(torch.load('model_best.pth'))
   print('the best val_acc is:')
   test(test_loader,net,loss_fn)
   plt.figure()
   ax1=plt.subplot(121)
   plt.plot([i for i in range(len(train_acc_list))],train_acc_list,ls='-',c='b')
   plt.title('accuracy')
   plt.xlabel('epoch')
   plt.ylabel('number')
   ax = plt.subplot(122)
   plt.plot([i for i in range(len(train_loss_list))], train_loss_list, ls='-', c='b')
   plt.title('loss')
   plt.xlabel('epoch')
   plt.ylabel('number')
   plt.show()

最后无激活函数时结果如图所示:

bdc16d6aac994d9e1dea463d1e7f3514.png

有激活函数时结果如图所示:

1db0c6cde0262c88c69a7ee701ef3ddd.png

3 结语

通过实验发现,在未使用激活函数时,通过不断地训练模型,模型的准确率和损失率都时比较稳定地上升和下降,但是在上升和下降地过程中会出现抖动地情况,但是使用激活函数之后,模型的准确率和损失率就会上升和下降的非常平滑,更有利于实验的进行,以及对模型行为的预测。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/526596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

systemctl针对service类型的配置文件

文章目录 systemctl针对service类型的配置文件systemctl配置文件相关目录简介systemctl配置文件的设置项目简介两个vsftpd运行的实例多重的重复设置方式:以getty为例将tty数量由6个降低为4个暂时新增vsftpd到1212端口 自己做个服务 systemctl针对service类型的配置文…

事件循环Event Loop

什么是事件循环(event loop) 主线程不断的从消息队列中获取消息,执行消息,这个过程被称为事件循环,在javaScript中就是采用事件循环来解决单线程带来的问题 线程和进程 进程:计算机已经运行的程序&#…

睿智的目标检测66——Pytorch搭建YoloV8目标检测平台

睿智的目标检测66——Pytorch搭建YoloV8目标检测平台 学习前言源码下载YoloV8改进的部分(不完全)YoloV8实现思路一、整体结构解析二、网络结构解析1、主干网络Backbone介绍2、构建FPN特征金字塔进行加强特征提取3、利用Yolo Head获得预测结果 三、预测结…

GOOGLE|只有大模型才能理解你举的例子(In-context learning)是什么

一、概述 title:LARGER LANGUAGE MODELS DO IN-CONTEXT LEARNING DIFFERENTLY 论文地址:https://arxiv.org/abs/2303.03846 参考:https://www.xiaohongshu.com/user/profile/5f01057f0000000001003c91/640aa237000000001303d871 1.1 Moti…

Java高阶数据结构 图补充-拓扑排序

拓扑排序 文章目录 Java高阶数据结构 & 图补充-拓扑排序1. 什么是拓扑排序2. 拓扑排序算法思想-卡恩算法3. 拓扑排序代码实现3.1 遍历链表计算入度3.2 挑选一个入度为0的顶点3.3 输出顶点3.4 判断循环结束是否为全-13.4 *kahn*方法3.5 测试 Java高阶数据结构 & 图补充…

python内置函数,推导式

abs:取绝对值 data abs(-10) pow:次方 data pow(2,5) sum:求和 num_list p[1,2,10,20] res sum(num_list) divmod取商和余数: v1,v2 divmod&…

第七届福州大学信息安全竞赛——shellcode1 绕过strlen检查,绕过沙箱检查,执行orw shellcode拿到flag

题目自取: 链接:https://pan.baidu.com/s/1HrMqh-lX-mkfueVeLzoEJg 提取码:oyel 介绍下这可恶的沙箱机制 这是一道非常让人蛋疼的题目,之前我只听说过沙箱,但是并没有自己实际接触过沙箱这个保护机制,大…

基于PKI的物联网安全服务体系建设

文章目录 1. PKI 概况1.1 PKI 简介1.2 CA 介绍1.2.1 CA证书包含主要内容1.2.1 CA 的工作原理1.2.2 主流的CA机构 1.4 PKI 应用场景 2. PKI 在物联网领域中的应用2.1 物联网PKI架构包含组件2.2 物联网PKI证书链 3. 创建自签CA证书3.1 自签名根证书创建3.2 创建云平台证书3.3 创建…

甘肃非煤矿山电子封条 智慧矿山 opencv

甘肃非煤矿山电子封条 智慧煤矿接入国家矿山安全平台是通过pythonopencv网络模型,甘肃非煤矿山电子封条pythonopencv网络模型对关键位置(回风井口、运人井口、车辆出入口)对现场人员行为、数量、穿戴着装及设备状态各数据进行实时监控分析。p…

【连续介质力学】特征值和特征向量问题

特征值和特征向量问题 二阶张量和一个向量(单位向量 n ^ ′ \hat n n^′)的点积会得到一个向量,也就是说,将一个二阶张量投影到某个方向所得到的向量的方向实际上与 n ^ ′ \hat n n^′ 的方向不一样: 特征值和特征向…

IDEA添加.gitignore忽略不需要提交的文件

问题 git上传的时候,我们已经将 xxx 文件添加到了.gitignore 中,但是在push 后,远程仓库还是会显示此文件,比如我们在.gitignore文件当中添加了不需要提交的target目录,但是提交的时候,还是会被提交。 原因…

2023.5.14总结

这周平时在刷蓝桥杯的题目,周天打了一场2021年陕西省的省赛的重现赛。 重现赛我们没打满,打了三个小时,A了四个,不过应该也差不多了。 登录—专业IT笔试面试备考平台_牛客网 以前没学过数论分块,今天学了学。对于一些向…

Hadoop上传及下载数据流程

网络拓扑及机架感知 网络拓扑 节点距离:两个节点到达共同父节点的距离和 机架感知 ( 副本节点的选择 ) 例如:500个节点,上传数据my.tar.gz,副本数为3, 根据机架感知,副本数据…

防止攻击者对您使用合法工具

恶意行为者越来越多地利用合法工具来实现其目标,其中包括禁用安全措施、横向移动和传输文件。使用常用工具可以让攻击者逃避检测。 虽然端点产品可以将定制工具或恶意软件标记为恶意软件,但商业上可用的工具通常被组织标记为干净或列入允许列表。 这让…

MacBook Pro合上盖子不休眠的问题简单分析

15年款的MacBook Pro每次不用的时候都是直接合上盖子(开着一堆程序)系统会自动休眠,但是升级了新系统Sierra之后就发现合上盖子竟然没有休眠(第二次打开盖子后发现掉了50%多的电,而且温度比较高)&#xff0…

软考A计划-真题-分类精讲汇总-第十一章(多媒体基础)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

MySQL只有information_schema一个数据库

背景:centos新安装的mysql数据库。使用DbEaver连接mysql库时,发现左边不显示表。使用命令框mysql -uroot回车登录时,发现只能看到information_schema一个数据库了。 原因:   因为mysql数据库的user表里,存在用户名为…

Julia入门-1、使用C++调用Julia脚本语言

文章目录 0、开发环境1、测试Julia环境2、调用Julia脚本语言准备3、使用C++调用Julia脚本语言(1)使用C++调用简单的Julia脚本语言(2)使用C++调用复杂的Julia脚本语言0、开发环境 操作系统: ①Windows 10 开发编译器: ①VS 2015 Professional ②VS Code + julia-vscode插件(…

《计算机网络—自顶向下方法》 第六章Wireshark实验:IP 协议分析

IP 协议(Internet Protocol),又译为网际协议或互联网协议,是用在 TCP/IP 协议簇中的网络层协议。主要功能是无连接数据报传送、数据报路由选择和差错控制。IP 协议是 TCP/IP 协议族的核心协议,其主要包含两个方面&…

Spring Boot 配置文件总结

前言 Spring Boot 中提供一个全局的配置文件:application.properties,这个配置文件的作用就是,允许我们通过这个配置文件去修改 Spring Boot 自动配置的默认值。 Spring Boot 支持两种格式的配置文件:application.properties 和…