简易机器学习笔记(八)关于经典的图像分类问题-常见经典神经网络LeNet
前言
图像分类是根据图像的语义信息对不同类别图像进行区分,是计算机视觉的核心,是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层次视觉任务的基础。图像分类在许多领域都有着广泛的应用,如:安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。
这里简单讲讲LeNet
我的推荐是可以看看这个视频,可视化的查看卷积神经网络是如何一层一层地抽稀获得特征,最后将所有的图像展开成一个一维的轴,再通过全连接神经网络预测得到一个最后的预测值。
手写数字识别 1.4 LeNet-5-哔哩哔哩
计算过程
前置知识:
- 步长 Stride & 加边 Padding
卷积后尺寸=(输入尺寸-卷积核大小+加边像素数)/步长 + 1
默认Padding = ‘valid’ (丢弃),strides = 1
正式计算
- 卷积层1:
第一层我们给定的图像时32 * 32,使用六个5 x 5的卷积核,步长为1
第一层中没有加边,那么卷积后的尺寸就是(32 - 5 + 0 )/1 + 1 =28,那么输出的图像就是 28*28的边长
在第一层中,由于我们使用了六个卷积核,我们得到的输出为:62828,可以理解为一个六层厚的图像
- 池化层1:
我们在池化层内在2x2的图像内选取了一个最大值或者平均值,也就是图片整体缩水到原先的二分之一,所以我们得到池化层的输出为 6 x 14 x 14
- 卷积层2:
还是按照公式,卷积后尺寸=(输入-卷积核+加边像素数)/步长 + 1,这个时候输入为6 x 14 x 14,这一次我们给定了16个卷积核,得到输出后的尺寸为(14 - 5 + 0)/1 + 1 = 10,得到输出为161010
关于这个16个卷积核是怎么来的,可以见图:
问了下组里的大佬,大佬说这个卷积核数目和层数很多是经验值,即你寻求更多或者更少的卷积核数目或者层数,实际效果不一定有经验值更好,反正都是离散值,就随便试试就行了。
其中:卷积输出尺寸nout:nin为输入原图尺寸大小;s是步长(一次移动几个像素);p补零圈数,
我们这里输入的值
- 池化层2
得到 输出后尺寸为16 * 5 * 5
- 全连接层1:
输入为16 * 5 * 5 ,有120个5*5卷积核,步长为1,输出尺寸为(5 - 5 + 0)/1 + 1 =1,这时候输出的就是一条直线的一维输出了
- 全连接层2:
输入为120,使用了84个神经元,
- 输出层
输入84,输出为10
比如我们如图所示,在代码中是这样的:
# 导入需要的包
import paddle
import numpy as np
from paddle.nn import Conv2D, MaxPool2D, Linear## 组网
import paddle.nn.functional as F
from paddle.vision.transforms import ToTensor
from paddle.vision.datasets import MNIST
#定义LeNet网络结构# 定义 LeNet 网络结构
class LeNet(paddle.nn.Layer):def __init__(self, num_classes=1):super(LeNet,self).__init__()#创建卷积层和池化层#创建第一个卷积层self.conv1 = Conv2D(in_channels=1,out_channels=6,kernel_size=5)self.max_pool1 = MaxPool2D(kernel_size=2,stride=2)#尺寸的逻辑:池化层未改变通道数,当前通道为6#创建第二个卷积层self.conv2 = Conv2D(in_channels=6,out_channels=16,kernel_size=5)self.max_pool2 = MaxPool2D(kernel_size=2,stride=2)#创建第三个卷积层self.conv3 = Conv2D(in_channels=16,out_channels=120,kernel_size=4)# 尺寸的逻辑:输入层将数据拉平[B,C,H,W] -> [B,C*H*W]# 输入size是[28,28],经过三次卷积和两次池化之后,C*H*W等于120self.fc1 = Linear(in_features=120, out_features=64)# 创建全连接层,第一个全连接层的输出神经元个数为64, 第二个全连接层输出神经元个数为分类标签的类别数self.fc2 = Linear(in_features=64, out_features=num_classes)# 网络的前向计算过程def forward(self, x):x = self.conv1(x)# 每个卷积层使用Sigmoid激活函数,后面跟着一个2x2的池化x = F.sigmoid(x)x = self.max_pool1(x)x = F.sigmoid(x)x = self.conv2(x)x = self.max_pool2(x)x = self.conv3(x)# 尺寸的逻辑:输入层将数据拉平[B,C,H,W] -> [B,C*H*W]x = paddle.reshape(x, [x.shape[0], -1])x = self.fc1(x)x = F.sigmoid(x)x = self.fc2(x)return x
# 飞桨会根据实际图像数据的尺寸和卷积核参数自动推断中间层数据的W和H等,只需要用户表达通道数即可。
# 下面的程序使用随机数作为输入,查看经过LeNet-5的每一层作用之后,输出数据的形状。# 输入数据形状是 [N, 1, H, W]
# 这里用np.random创建一个随机数组作为输入数据
x = np.random.randn(*[3,1,28,28])
x = x.astype('float32')# 创建LeNet类的实例,指定模型名称和分类的类别数目
model = LeNet(num_classes=10)# 通过调用LeNet从基类继承的sublayers()函数,
# 查看LeNet中所包含的子层
print(model.sublayers())
x = paddle.to_tensor(x)for item in model.sublayers():#item是LeNet类中的一个子层#查看经过子层之后的输出数据形状try:x = item(x)except:x = paddle.reshape(x, [x.shape[0], -1])x = item(x)if len(item.parameters())==2:# 查看卷积和全连接层的数据和参数的形状,# 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数bprint(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape)else:# 池化层没有参数print(item.full_name(), x.shape)# 设置迭代轮数
EPOCH_NUM = 5
#定义训练过程
def train(model,opt,train_loader,valid_loader):print("start training ... ")model.train()for epoch in range(EPOCH_NUM):for batch_id, data in enumerate(train_loader()):img = data[0]label = data[1] #计算模型输出# 计算模型输出logits = model(img)# 计算损失函数loss_func = paddle.nn.CrossEntropyLoss(reduction='none')loss = loss_func(logits, label)avg_loss = paddle.mean(loss)if batch_id % 2000 == 0:print("epoch: {}, batch_id: {}, loss is: {:.4f}".format(epoch, batch_id, float(avg_loss.numpy())))#反向传播avg_loss.backward()opt.step()opt.clear_grad()model.eval()accuracies = []losses = []for batch_id, data in enumerate(valid_loader()):img = data[0]label = data[1]# 计算模型输出logits = model(img)pred = F.softmax(logits)# 计算损失函数loss_func = paddle.nn.CrossEntropyLoss(reduction='none')loss = loss_func(logits, label)acc = paddle.metric.accuracy(pred, label)accuracies.append(acc.numpy())losses.append(loss.numpy())print("[validation] accuracy/loss: {:.4f}/{:.4f}".format(np.mean(accuracies), np.mean(losses)))model.train()# 保存模型参数paddle.save(model.state_dict(), 'mnist.pdparams') # 创建模型
model = LeNet(num_classes=10)
# 设置迭代轮数
EPOCH_NUM = 5
# 设置优化器为Momentum,学习率为0.001
opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters())
# 定义数据读取器
train_loader = paddle.io.DataLoader(MNIST(mode='train', transform=ToTensor()), batch_size=10, shuffle=True)
valid_loader = paddle.io.DataLoader(MNIST(mode='test', transform=ToTensor()), batch_size=10)
# 启动训练过程
train(model, opt, train_loader, valid_loader)
相关文章:

简易机器学习笔记(八)关于经典的图像分类问题-常见经典神经网络LeNet
前言 图像分类是根据图像的语义信息对不同类别图像进行区分,是计算机视觉的核心,是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层次视觉任务的基础。图像分类在许多领域都有着广泛的应用,如:安防领域的人脸识别和…...

pytest conftest通过fixture实现变量共享
conftest.py scope"module" 只对当前执行的python文件 作用 pytest.fixture(scope"module") def global_variable():my_dict {}yield my_dict test_case7.py import pytestlist1 []def test_case001(global_variable):data1 123global_variable.u…...

系列五、搭建Naco(集群版)
一、搭建Naco(集群版) 1.1、前置说明 (1)64位Red Hat7 Linux 系统; (2)64位JDK1.8;备注:如果没有安装JDK,请参考【系列二、Linux中安装JDK】 (3&…...

JavaScript中alert、prompt 和 confirm区别及使用【通俗易懂】
✨前言✨ 本篇文章主要在于,让我们看几个与用户交互的函数:alert,prompt 和confirm的使用及区别 🍒欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍒博主将持续更新学习记录收获&…...

【GoLang入门教程】Go语言几种标准库介绍(四)
编程语言的未来? 文章目录 编程语言的未来?前言几种库fmt库 (格式化操作)关键函数:示例 Go库标准库第三方库示例 html库(HTML 转义及模板系统)主要功能:示例 总结专栏集锦写在最后 前言 上一篇,我们介绍了debug、enco…...
面试算法:快速排序
题目 快速排序是一种非常高效的算法,从其名字可以看出这种排序算法最大的特点就是快。当表现良好时,快速排序的速度比其他主要对手(如归并排序)快2~3倍。 分析 快速排序的基本思想是分治法,排序过程如下…...

航空业数字化展翅高飞,开源网安专业服务保驾护航
某知名航空公司是中国首批民营航空公司之一,运营国内外航线200多条,也是国内民航最高客座率的航空公司之一。在数字化发展中,该航空公司以数据驱动决策,通过精细化管理、数字创新和模式优化等方式,实现了精准营销和个…...

SpringBoot学习(三)-员工管理系统开发(重在理解)
注:此为笔者学习狂神说SpringBoot的笔记,其中包含个人的笔记和理解,仅做学习笔记之用,更多详细资讯请出门左拐B站:狂神说!!! 本文是基于狂神老师SpringBoot教程中的员工管理系统从0到1的实践和理解。该系统应用SpringB…...

2 Windows网络编程
1 基础概念 1.1 socket概念 Socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。Socket本质上是一个抽象层,它是一组用于网络通信的API,包括了一系列…...

uniapp选择android非图片文件的方案踩坑记录
这个简单的问题我遇到下面6大坑,原始需求是选择app如android的excel然后读取到页面并上传表格数据json 先看看效果 uniapp 选择app excel文件读取 1.uniapp自带不支持 uniapp选择图片和视频非常方便自带已经支持可以直接上传和读取 但是选择word excel的时候就出现…...

前端发开的性能优化 请求级:请求前(资源预加载和预读取)
预加载 预加载:是优化网页性能的重要技术,其目的就是在页面加载过程中先提前请求和获取相关的资源信息,减少用户的等待时间,提高用户的体验性。预加载的操作可以尝试去解决一些类似于减少首次内容渲染的时间,提升关键资…...

B01、类加载子系统-02
JVM架构图-英文版 中文版见下图: 1、概述类的加载器及类加载过程 1.1、类加载子系统的作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engi…...

用PHP搭建一个绘画API
【腾讯云AI绘画】用PHP搭建一个绘画API 大家好!今天我要给大家推荐的是如何用PHP搭建一个绘画API,让你的网站或应用瞬间拥有强大的绘画能力!无论你是想要让用户在网页上绘制自己的创意,还是想要实现自动绘画生成特效,这…...

西安人民检察院 | OLED翻页查询一体机
产品:55寸OLED柔性屏 项目时间:2023年12月 项目地点:西安 在2023年12月,西安人民检察院引入了OLED翻页查询一体机,为来访者提供了一种全新的信息查询方式。 这款一体机采用55寸OLED柔性屏,具有高清晰度、…...

superset利用mysql物化视图解决不同数据授权需要写好几次中文别名的问题
背景 在使用superset时,给不同的人授权不同的数据,需要不同的数据源,可视化字段希望是中文,所以导致不同的人需要都需要去改表的字段,因此引入视图,将视图中字段名称设置为中文 原表数据 select * from …...

输入输出流
1.输入输出流 输入/输出流类:iostream---------i input(输入) o output(输出) stream:流 iostream: istream类:输入流类-------------cin:输入流类的对象 ostream类…...

IOS:Safari无法播放MP4(H.264编码)
一、问题描述 MP4使用H.264编码通常具有良好的兼容性,因为H.264是一种广泛支持的视频编码标准。它可以在许多设备和平台上播放,包括电脑、移动设备和流媒体设备。 使用caniuse查询H.264兼容性,看似确实具有良好的兼容性: 然而…...

Pycharm恢复默认设置
window 系统 找到下方目录-->删除. 再重新打开Pycharm C:\Users\Administrator\.PyCharm2023.3 你的不一定和我名称一样 只要是.PyCharm*因为版本不同后缀可能不一样 mac 系统 请根据需要删除下方目录 # Configuration rm -rf ~/Library/Preferences/PyCharm* # Caches …...
简单计算器实现,包括两个数
正在加载中... 简单计算器实现,包括两个数 ❤ 厾罗 简单计算器实现,包括两个数 以下代码用于实现简单计算器实现,包括两个数基本的加减乘除运算: 实例(Python 3.0) # Filename : test.py # author by : www.dida100.com …...

竞赛保研 基于机器视觉的手势检测和识别算法
0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...