一、神经网络

神经网络(Neural Network)是一种受生物神经系统(尤其是大脑神经元连接方式)启发的机器学习模型,是深度学习的核心基础。它通过模拟大量 “人工神经元” 的互联结构,学习数据中的复杂模式和规律,从而实现分类、预测、生成等任务。

本项目采用的是全连接神经网络(Fully Connected Network)

每一层的神经元与下一层所有神经元连接。

应用:简单分类 / 回归任务(如房价预测、鸢尾花分类)。

大概模型如下图所示:

1.输入层(Input Layer): 

  1. 接收原始数据(如图像的像素值、文本的词向量),不进行计算,仅传递数据。

  2. 神经元数量 = 输入数据的维度(例如:28*28 的彩色图像输入层有 28*28=784个神经元)。

2.隐藏层(Hidden Layer)

  1. 位于输入层和输出层之间,负责提取数据的特征(如边缘、纹理、语义等)。
  2. 共有2层,其中第一层设置了250个节点,第二层设置了200层。

3.输出层(Output Layer)

  1. 输出模型的最终结果(如分类任务的类别概率、回归任务的预测值)。
  2. 神经元数量 = 任务目标的维度(10 类分类任务输出层有 10 个神经元)。

4.激活函数

激活函数是神经网络能拟合复杂模式的关键,其核心作用是引入非线性变换(否则多层网络等价于单层线性模型)。本项目所使用的激活函数是relu函数:

\text{ReLU}(z) = \max(0, z)

5.计算损失(Loss Calculation)

  1. 损失函数(Loss Function)衡量预测结果与真实标签的差距(例如:分类任务用交叉熵损失,回归任务用均方误差)。
  2. 损失越小,模型预测越准。

在 PyTorch 中,CrossEntropyLoss是用于分类任务的常用损失函数,尤其适用于多类别分类(也可用于二分类)。它的设计非常灵活,内部集成了log_softmaxNLLLoss的功能,简化了模型输出与损失计算的流程。

CrossEntropyLoss = NLLLoss(log_softmax(logits), targets)

NLLLoss(y, \hat{y})=-\frac{1}{N}ylog \hat{y}

log\, softmax=log\frac{e^{y_{i}}}{\sum {j} e^{y_{j}}}

6.正则化

用于防止模型过拟合,提高泛化能力。

L2 正则化(Ridge Regression):倾向于减小参数值

  • 参数平滑性:L2 正则化会使参数值变小,但不会完全为 0,从而使模型更加平滑。
  • 几何解释:L2 的约束区域是一个圆形,与损失函数的等高线相交时,参数更可能落在非零的位置。

在损失函数中添加参数的平方和作为惩罚项:损失函数= 原始损失 +\lambda \sum_{i} w_i^2

7.优化器

Adam(Adaptive Moment Estimation)是深度学习中最流行的优化算法之一,结合了 Adagrad 和 RMSProp 的优点,能够自适应地调整每个参数的学习率。它在实践中表现出色,广泛应用于各种神经网络训练任务。

二、代码

网络模型

单独新建一个Python文件用于存储网络模型,其中定义了两个隐藏层,都使用全连接神经网络,第一个隐藏层有250个节点,第二隐藏层有200个节点,从最后一个隐藏层到输出层同样使用全连接神经网络

self.fc1=nn.Linear(28*28,250)
self.fc2=nn.Linear(250,200)
self.fc3=nn.Linear(200,10)

 前两层(输入层->第一个隐藏层->第二个隐藏层)都使用relu激活函数,第二个隐藏层到输出层暂不使用激活函数,这样做可以减少loss的计算误差

x =F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)

 完整代码如下:

class network1(nn.Module):def __init__(self):super(network1, self).__init__()self.fc1=nn.Linear(28*28,250)self.fc2=nn.Linear(250,200)self.fc3=nn.Linear(200,10)def forward(self, x):x =F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.fc3(x)return x

训练模型

工具模块

import torchvisionfrom model import *
from torch import nn
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import DataLoader

数据处理,将图片数据转换成tensor数据类型

trans=torchvision.transforms.Compose([torchvision.transforms.ToTensor()
])

 导入数据,并获取数据长度

train_dataset=torchvision.datasets.MNIST("./data",train=True,transform=trans,download=True)
test_dataset=torchvision.datasets.MNIST("./data",train=False,transform=trans,download=True)train_data_size=len(train_dataset)
test_data_size=len(test_dataset)

加载数据,并设置批量大小为64,设置 打乱数据顺序,因为数据集大小不能被64整除,设置丢弃多余数据

train_dataloader=DataLoader(train_dataset,batch_size=64,shuffle=True,drop_last=True)
test_dataloader=DataLoader(test_dataset,batch_size=64,shuffle=True,drop_last=True)

声明网络模型变量,设置损失函数,使用adam优化,设置l2正则

model=network1()loss_fn=nn.CrossEntropyLoss()learning_rate=1e-2
l2_lambda=1e-5
optimizer=torch.optim.Adam(model.parameters(),lr=learning_rate,weight_decay=l2_lambda)

 设置训练过程中可能用到的变量

total_train_step=0
total_test_step=0
epoch=50

  创建SummaryWriter,指定日志保存目录

writer=SummaryWriter("./mini_logs")

 在迭代器中取出数据和标签,将数据展成一维的,使其符合网络模型的输入,将其放入模型中

    for data in train_dataloader:imgs,targets=dataimgs=torch.reshape(imgs,(64,-1))outputs=model(imgs)

计算损失值

loss = loss_fn(outputs, targets)
total_train_loss+=loss

 计算准确率

accuracy = ((outputs.argmax(1) == targets).sum())
total_train_accuracy += accuracy
total_train_step+=1

更新梯度,进行参数优化

optimizer.zero_grad()
loss.backward()
optimizer.step()

 输出训练数据,并将训练误差和准确率添加到tensorboard上

# 100轮输出一次,防止数据太多        if total_train_step % 100 == 0:print('训练次数:{},Loss:{}'.format(total_train_step, loss.item()))  print("整体训练集上的Loss为:{}".format(total_train_loss))print("整体训练集上的正确率为:{}".format(total_train_accuracy / train_data_size))writer.add_scalar("Loss/train_loss", total_train_loss, total_test_step)#使用test_step是为了对齐测试误差,下同writer.add_scalar("Ac/train_accuracy", total_train_accuracy / train_data_size, total_test_step)

 在test数据集上测试参数效果,过程与训练过程相似,需要注意的是,在测试过程中可以不计算梯度,加快计算效率

total_test_loss=0total_test_accuracy=0with torch.no_grad():for data in test_dataloader:imgs,targets=dataimgs = torch.reshape(imgs, (64, -1))outputs=model(imgs)loss=loss_fn(outputs,targets)total_test_loss+=lossaccuracy = ((outputs.argmax(1) == targets).sum())total_test_accuracy += accuracyprint("整体测试集上的Loss为:{}".format(total_test_loss))print("整体测试集上的正确率为:{}".format(total_test_accuracy / test_data_size))writer.add_scalar("Loss/test_loss", total_test_loss, total_test_step)writer.add_scalar("Ac/test_accuracy", total_test_accuracy / test_data_size, total_test_step)

最后保存模型并关闭SummaryWriter

torch.save(model,"minst_weight/net_{}.pth".format(i))print("模型已保存")writer.close()

 完整代码如下:

import torchvisionfrom model import *
from torch import nn
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import DataLoadertrans=torchvision.transforms.Compose([torchvision.transforms.ToTensor()
])train_dataset=torchvision.datasets.MNIST("./data",train=True,transform=trans,download=True)
test_dataset=torchvision.datasets.MNIST("./data",train=False,transform=trans,download=True)train_data_size=len(train_dataset)
test_data_size=len(test_dataset)train_dataloader=DataLoader(train_dataset,batch_size=64,shuffle=True,drop_last=True)
test_dataloader=DataLoader(test_dataset,batch_size=64,shuffle=True,drop_last=True)model=network1()loss_fn=nn.CrossEntropyLoss()learning_rate=1e-2
l2_lambda=1e-5
optimizer=torch.optim.Adam(model.parameters(),lr=learning_rate,weight_decay=l2_lambda)total_train_step=0
total_test_step=0
epoch=50writer=SummaryWriter("./mini_logs")for i in range(epoch):print('--------第{}轮训练开始--------'.format(i))total_train_loss = 0total_train_accuracy=0for data in train_dataloader:imgs,targets=dataimgs=torch.reshape(imgs,(64,-1))outputs=model(imgs)loss = loss_fn(outputs, targets)total_train_loss+=lossaccuracy = ((outputs.argmax(1) == targets).sum())total_train_accuracy += accuracytotal_train_step+=1optimizer.zero_grad()loss.backward()optimizer.step()if total_train_step % 100 == 0:print('训练次数:{},Loss:{}'.format(total_train_step, loss.item()))  # 100轮输出一次,防止数据太多print("整体训练集上的Loss为:{}".format(total_train_loss))print("整体训练集上的正确率为:{}".format(total_train_accuracy / train_data_size))writer.add_scalar("Loss/train_loss", total_train_loss, total_test_step)#使用test_step是为了对齐测试误差,下同writer.add_scalar("Ac/train_accuracy", total_train_accuracy / train_data_size, total_test_step)total_test_loss=0total_test_accuracy=0with torch.no_grad():for data in test_dataloader:imgs,targets=dataimgs = torch.reshape(imgs, (64, -1))outputs=model(imgs)loss=loss_fn(outputs,targets)total_test_loss+=lossaccuracy = ((outputs.argmax(1) == targets).sum())total_test_accuracy += accuracyprint("整体测试集上的Loss为:{}".format(total_test_loss))print("整体测试集上的正确率为:{}".format(total_test_accuracy / test_data_size))writer.add_scalar("Loss/test_loss", total_test_loss, total_test_step)writer.add_scalar("Ac/test_accuracy", total_test_accuracy / test_data_size, total_test_step)total_test_step += 1torch.save(model,"minst_weight/net_{}.pth".format(i))print("模型已保存")writer.close()

训练结果如下图所示:

可以看到在test数据集上,该模型的准确率还是非常高的

模型测试

在网页上随便截取几张手写数字,测试一下其效果,效果可能与test数据集测试的效果相差较大,是因为网上的数据与训练的数据相差太大,所以这个实验可能并没有什么参考价值,可以练练手

数据描述:在网上截取了0-9的图片,并命名为img_0这种格式

第一步:获取数据

    image_path= 'imgs/img_{}.png'.format(i)image=Image.open(image_path)

第二步:数据预处理,将彩色图转为灰度图,裁剪其尺寸为28*28,然后将其转换成tensor数据类型

image=image.convert("L")trans=torchvision.transforms.Compose([torchvision.transforms.Resize((28,28)),torchvision.transforms.ToTensor()])image=trans(image)

第三步:可以查看一下处理完的数据,由于add_image要求数据是三维的,所以需要先处理一下数据

    image=torch.reshape(image,(1,28,-1))writer=SummaryWriter("mini_show")writer.add_image("{}".format(i),image)writer.close()

第四步:加载模型,并输出训练结果

    image=torch.reshape(image,(1,-1))model=torch.load('minst_weight/net_40.pth')model.eval()with torch.no_grad():output=model(image)print('{}预测的值是:{}'.format(i,output.argmax(1).item()))

完整代码如下: 

import torch
import torchvision
from PIL import Image
from torch.utils.tensorboard import SummaryWriterfrom model import *
for i in range(10):image_path= 'imgs/img_{}.png'.format(i)image=Image.open(image_path)image=image.convert("L")trans=torchvision.transforms.Compose([torchvision.transforms.Resize((28,28)),torchvision.transforms.ToTensor()])image=trans(image)image=torch.reshape(image,(1,28,-1))writer=SummaryWriter("mini_show")writer.add_image("{}".format(i),image)writer.close()image=torch.reshape(image,(1,-1))model=torch.load('minst_weight/net_40.pth')model.eval()with torch.no_grad():output=model(image)print('{}预测的值是:{}'.format(i,output.argmax(1).item()))

截取并预处理后的图片: 

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C/C++安全编程]_[中级]_[如何避免出现野指针]

场景 在Rust里不会出现野指针的情况,那么在C里能避免吗? 说明 野指针是指指向无效内存地址的指针,访问它会导致未定义行为,可能引发程序崩溃、数据损坏或安全漏洞。它是 C/C 等手动内存管理语言中的常见错误,而 Rust…

机器学习基础:从数据到智能的入门指南

一、何谓机器学习​ 在我们的日常生活中,机器学习的身影无处不在。当你打开购物软件,它总能精准推荐你可能喜欢的商品;当你解锁手机,人脸识别瞬间完成;当你使用语音助手,它能准确理解你的指令。这些背后&a…

steam游戏搬砖项目超完整版实操分享

大家好,我是阿阳,今天再次最详细的给大家综合全面的分析讲解下steam搬砖,可以点击后面跳转往期文章了再次解下阿阳网客:关于steam游戏搬砖项目,我想说!最早是21年5月份公开朋友圈,初次接触是在2…

vue2 面试题及详细答案150道(21 - 40)

《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs&…

原生前端JavaScript/CSS与现代框架(Vue、React)的联系与区别(详细版)

原生前端JavaScript/CSS与现代框架(Vue、React)的联系与区别,以及运行环境和条件 目录 引言原生前端技术概述 JavaScript基础CSS基础 现代框架概述 Vue.jsReact 联系与相似性主要区别对比运行环境和条件选择建议总结 引言 在现代Web开发中&…

基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现

基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 摘要 本文设计并实现了一种基于机器视觉的迈克耳孙干涉环自动计数系统。该系统…

设计模式笔记(1)简单工厂模式

最近在看程杰的《大话设计模式》,在这里做一点笔记。 书中主要有两个角色: 小菜:初学者,学生; 大鸟:小菜表哥,大佬。 也按图中的对话形式 01 简单工厂模式 要求:使用c、Java、C#或VB…

Vue3 学习教程,从入门到精通,Vue 3 声明式渲染语法指南(10)

Vue 3 声明式渲染语法指南 本文将详细介绍 Vue 3 中的声明式渲染语法,涵盖所有核心概念,并通过一个完整的案例代码进行演示。案例代码中包含详细注释,帮助初学者更好地理解每个部分的功能和用法。 目录 简介声明式渲染基础 文本插值属性绑…

React hooks——useReducer

一、简介useReducer 是 React 提供的一个高级 Hook,用于管理复杂的状态逻辑。它类似于 Redux 中的 reducer 模式,适合处理包含多个子值、依赖前一个状态或逻辑复杂的状态更新场景。与 useState 相比,useReducer 提供更结构化的状态管理方式。…

SEO中关于关键词分类与布局的方法有那些

前边我们说到关键词挖掘肯定很重要,但如何把挖掘出来的关键词用好更为重要,下边我们就来说说很多seo刚入行的朋友比较头疼的关键词分类问题,为了更直观的感受搭配了表格,希望可以给大家一些帮助!SEO优化之关键词分类​挖掘出的关键…

考研最高效的准备工作是什么

从性价比的角度来说,考研最高效的准备工作是什么呢? 其实就是“卷成绩”。 卷学校中各门课程的成绩,卷考研必考的数学、英语、政治和专业课的成绩。 因为现阶段的考研,最看重的仍然是你的成绩,特别是初试成绩。 有了…

【Linux】基于Ollama和Streamlit快速部署聊天大模型

1.环境准备 1.1 安装Streamlit 在安装Streamlit之前,请确保您的系统中已经正确安装了Python和pip。您可以在终端或命令行中运行以下命令来验证它们是否已安装 python --version pip --version一旦您已经准备好环境,现在可以使用pip来安装Streamlit了。…

Jetpack - ViewModel、LiveData、DataBinding(数据绑定、双向数据绑定)

一、ViewModel 1、基本介绍 ViewModel 属于 Android Jetpack 架构组件的一部分,ViewModel 被设计用来存储和管理与 UI 相关的数据,这些数据在配置更改(例如,屏幕旋转)时能够幸存下来,ViewModel 的生命周期与…

Go并发聊天室:从零构建实战

大家好,今天我将分享一个使用Go语言从零开始构建的控制台并发聊天室项目。这个项目虽然简单,但它麻雀虽小五脏俱全,非常适合用来学习和实践Go语言强大的并发特性,尤其是 goroutine 和 channel 的使用。 一、项目亮点与功能特性 …

疯狂星期四第13天运营日报

网站运营第13天,点击观站: 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 昨日访问量 昨天大概60个ip, 同比上个星期是高点的,但是与星期四差别还是太大了。😂 昨日搜索引擎收录情况 百度依旧0收录 …

吴恩达《AI for everyone》第二周课程笔记

机器学习项目工作流程以Echo/Alexa(语音识别AI)作为例子解释: 1. collect data 收集数据——人为找很多人说 Alexa,并录制音频;并且还会让一群人说其他词语,比如hello 2. train model 训练模型——用机器学…

uniapp props、$ref、$emit、$parent、$child、$on

1. uniapp props、ref、ref、ref、emit、parent、parent、parent、child、$on 1.1. 父组件和子组件 propsPage.vue导入props-son-view.vue组件的时候,我们就称index.vue为父组件依次类推,在vue中只要能获取到组件的实例,那么就可以调用组件的属性或是方法进行操作 1.2. pr…

4、ubuntu | dify创建知识库 | 上市公司个股研报知识库

1、创建知识库步骤 创建一个知识库并上传相关文档主要涉及以下五个关键步骤: 创建知识库:首先,需要创建一个新的知识库。这可以通过上传本地文件、从在线资源导入数据或者直接创建一个空的知识库来实现。 指定分段模式:接下来是…

Kubernetes中为Elasticsearch配置多节点共享存储

在Kubernetes中为Elasticsearch配置多节点共享存储(ReadWriteMany)需结合存储后端特性及Elasticsearch架构设计。 由于Elasticsearch默认要求每个节点独立存储数据(ReadWriteOnce),直接实现多节点共享存储需特殊处理。 ​​方案一:使用支持ReadWriteMany的存储后端(推荐…

SpringBoot热部署与配置技巧

配置文件SpringBoot 的热部署Spring为开发者提供了一个名为spring-boot-devtools的模块来使SpringBoot应用支持热部署&#xff0c;提高开发者的开发效率&#xff0c;无需手动重启SpringBoot应用相关依赖&#xff1a;<dependency> <groupId>org.springframework.boo…