【paddle深度学习高层API七日打卡营】三岁水课第二天——卷积神经网络和手写数字识别(一)

简介: 【paddle深度学习高层API七日打卡营】三岁水课第二天——卷积神经网络和手写数字识别(一)

大家好,这里是三岁,别的不会,擅长白话,今天就是我们的白话系列,内容是paddle2.0新出的高程API,在这里的七日打卡营0基础学习,emmm我这个负基础的也来凑凑热闹,那么就开始吧~~~~

注:以下白话内容为个人理解,如有不同看法和观点及不对的地方欢迎大家批评指正!


课程传送门

书写数字识别(神经网络)项目传送门

卷积神经网络基础项目传送门


什么是十二生肖分类



基于实践对网络进行拓展


2021020510334889.png



通过数据集在网络中不断的进行训练然后经过调参,得到一个比较理想的模型

白话:你上课老师教你认十二生肖,最后你基本上认识了,你所学习到的知识就相当于是模型。


拓展:一个图片认知不是很简单?so easy 妈妈再也不担心我不会深度学习!

等等,你看到的是一张图,而计算机看到的是像素点是0-255的一个值(或者是处理以后的值),这个时候会出现一种神奇的东西叫做语义鸿沟!


20210205104429309.png

  • 注:上图源于AI小鸭学院—小白逆袭大神课程

这样子我们就可以想象机器学习分类比我们更难!


典型的分类问题有哪些



  • 按照分类场景分


2021020510474686.png


paddle.vision.datasets中paddle自带了一些经典数据集就包括了Cifar10、Cifar100、MNIST(手写分类识别)


20210205104856462.png20210205105227409.png


2021020510530064.png


  • 这些都是深度学习领域古老但是经典的分类数据集了(手写的请参考第一天的课程)
  • 按照分类类别分
    二分类,多分类,多标签分类……


20210205105756625.png


图像分类原理



20210205110146390.png


计算机的视角:


20210205110253582.png


一张彩色的图片涉及到了一个通道的问题,彩色的是三通道,代表着这个图里面的c(相对应第三维度的值)

这里面的w,h相对应图片的宽度和高度,就是传说中的像素比如(2828)(800800)

白话:


这个东西这么理解呢,说实话很抽象,

大家看一个平面像不像是长方形,w和h对应的是长方形的长和宽,c相对应长方体的高,

假设该图的像素是2828的那么我们就可以理解为是长,宽,高分别是2828*3的立方体(只是举例)

那么用paddleTensor表示就是(3, 28, 28)(依次是高维度到底维度)(相对应高,宽,长)


计算机的工作:

计算机对上面的数据进行分析,查看里面的一些特征,然后通过特征分析各种东西的比例。

可以理解为你在玩猜猜猜的游戏,通过一些特征猜到一个结果。


计算机的绊脚石


image.png



这些丢是对计算机的一种考验,也是对深度学习的一种考验和挑战


卷积神经网络



20210205112007251.png


原始信号—>发现边缘和方向—>不断抽象—>不断抽象


发展史


20210205112236191.png


开山鼻祖:CNN


20210205112823341.png


网络详解

卷积操作

单通道卷积

y = w * x + b (x是输入,y是输出,w是卷积核,b是贝叶斯)


1933c55f1aac081d9bd018bb1ee01f53.png


在这里面涉及连个概念,计算和步长


计算

大家找找规律就ok


20210205122057507.png


步长


以上图为例:步长就是1,他的间隔就是一个像素(单位),以此类推

经过计算以后就得到了一个特征提取以后得到的特征核


得到的结果大小


20210205123438373.png


以上面例子为例:


w=3(xw)+0(20)-2(f-w)/1+1=2
h=3(xh)+0(2
0)-2(f-h)/1+1=2


所以得到的结果是2*2的结果


多通道卷积


071ce3ff52b47e7177614bd6043d7f02.png


这里多通道对应的卷积核也是相应维度的,分别计算出对应维度的结果如何把对应位置的加起来就是最后输出的降维结果

1101 = 805 + 271 + 25

这里三通道的数据经过一个卷积核得到了一个单通道的表示


多通道输出


602a0b74cbf7eacfbe38a8fc246753f0.png


通过多个卷积核得到多个特征然后再堆叠得到一个多通道的输出

Batch

卷积核信息不变,卷积操作会多一定的倍数(和样本数有关)。


fc400481c66f48fd92c4a0001a584728.png


这个和上面的一样多个输入和多个卷积核通过卷积生成图

填充操作( Padding的由来):


角落边缘的像素,只被一个过滤器输出所使用,因为它位于这个3×3的区域的一角。但如果是在中间的像素点,就会有许多3×3的区域与之重叠。

所以那些在角落或者边缘区域的像素点在输出中采用较少,意味着你丢掉了图像边缘位置的许多信息。

那么出现的一个解决办法就是填充操作,在原图像外围以0进行填充,在不影响特征提取的同时,增加了对边缘信息的特征提取。

另外一个好处是,我们在做卷积操作时,每经过一次卷积我们的输入图像大小就会变小,最后经过多次卷积可能我们的图像会变得特别小,我们不希望图像变小的话就可以通过填充操作。


ba052bf46749a8bce8af98230abf7fd0.png

白话:就是边缘的一些内容有可能就只被收集了一次特征,但是中心的确有多次,那么边上的信息数据就会丢失或者木有那么的清晰,这个是如果填充空白的数据那么就可以比较好的解决问题,同时可以解决图像变小带来的某些时候不必要的麻烦


池化层

池化是使用某一位置的相邻输出的总体统计特征代替网络在该位置的输出,其好处是当输入数据做出少量平移时,经过池化函数后的大多数输出还能保持不变。比如:当识别一张图像是否是人脸时,我们需要知道人脸左边有一只眼睛,右边也有一只眼睛,而不需要知道眼睛的精确位置,这时候通过池化某一片区域的像素点来得到总体统计特征会显得很有用。由于池化之后特征图会变得更小,如果后面连接的是全连接层,能有效的减小神经元的个数,节省存储空间并提高计算效率。


池化的作用

池化层是特征选择和信息过滤的过程,过程中会损失一部分信息,但是会同时会减少参数和计算量,在模型效果和计算性能之间寻找平衡,随着运算速度的不断提高,慢慢可能会有一些设计上的变化,现在有些网络已经开始少用或者不用池化层。


2f71628bf06dc9ab55dc311446be8717.png


池化的步长和卷积核的大小有关,默认长度为2


平均池化(Avg Pooling)

对邻域内特征点求平均


  • 优缺点:能很好的保留背景,但容易使得图片变模糊
  • 正向传播:邻域内取平均
  • 反向传播:特征值根据领域大小被平均,然后传给每个索引位置


最大池化(Max Pooling)

对邻域内特征点取最大


  • 优缺点:能很好的保留一些关键的纹理特征,现在更多的再使用Max Pooling而很少用Avg Pooling
  • 正向传播:取邻域内最大,并记住最大值的索引位置,以方便反向传播
  • 反向传播:将特征值填充到正向传播中,值最大的索引位置,其他位置补0


计算结果的大小公示


a536c057562d21e72a60e39c44401644.png

b780176cc92d2d50bb96870b6f3c6cd7.png


激活函数

Sigmoid


cf3f229a1ae2357dc08961e29486e5f5.png


Tanh


ff56f140d1feeb1de13aae2cfbc76be4.png


Sigmoid和Tanh激活函数有共同的缺点:即在z很大或很小时,梯度几乎为零,因此使用梯度下降优化算法更新网络很慢。


ReLU


6ca8571514cbbe784a4770aceab234d9.png


Relu目前是选用比较多的激活函数,但是也存在一些缺点,在z小于0时,斜率即导数为0。

为了解决这个问题,后来也提出来了Leaky Relu激活函数,不过目前使用的不是特别多。


手写数字识别



问题定义


图像分类,使用LeNet-5网络完成手写数字识别图片的分类。


# 导入第三方库
import paddle
import numpy as np
import matplotlib.pyplot as plt
paddle.__version__  # 判断版本

‘2.0.0’


数据准备


  • 数据加载与预处理


20210205113954602.png

# 数据预处理
import paddle.vision.transforms as T
# 数据预处理,TODO:找一下提出的原论文看一下(归一化处理)
transform = T.Normalize(mean=[127.5], std=[127.5])
# 训练数据集
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
# 验证数据集
eval_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
print('训练样本量:{},测试样本量:{}'.format(len(train_dataset), len(eval_dataset)))


训练样本量:60000,测试样本量:10000


这里的处理方式和昨天的是一样,先定义transform(一个归一化处理,把数据归一到(-1,1)的区间)


  • 数据查看


20210205114818336.png

print('图片:')
print(type(train_dataset[0][0]))
print(train_dataset[0][0])
print('标签:')
print(type(train_dataset[0][1]))
print(train_dataset[0][1])
# 可视化展示
plt.figure()
plt.imshow(train_dataset[0][0].reshape([28,28]), cmap=plt.cm.binary)
plt.show()


这里和第一天的数据也是一样的,就是解释了train_dataset和昨天理解的其实是一样的,一个[0]取的是整个生成器的第一个值,第二个[0]取的是image

train_dataset[0]里面的内容是(image,lable)


模型选择和开发

  • 网络结构定义

我们选用LeNet-5网络结构。

LeNet-5模型源于论文“LeCun Y, Bottou L, Bengio Y, et al. Gradient-based learning applied to document recognition[J]. Proceedings of the IEEE, 1998, 86(11): 2278-2324.”,

论文地址:https://ieeexplore.ieee.org/document/726791


4a5b3f033d32b75503c754a43e08c39c.png


论文模型
  • 代码解析


20210205132916996.png


import paddle.nn as nn
network = nn.Sequential(
    nn.Conv2D(in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=0),  # C1 卷积层
    nn.Tanh(),
    nn.AvgPool2D(kernel_size=2, stride=2),  # S2 平局池化层
    nn.Sigmoid(),   # Sigmoid激活函数
    nn.Conv2D(in_channels=6, out_channels=16, kernel_size=5, stride=1, padding=0),  # C3 卷积层
    nn.Tanh(),
    nn.AvgPool2D(kernel_size=2, stride=2),  # S4 平均池化层
    nn.Sigmoid(),  # Sigmoid激活函数
    nn.Conv2D(in_channels=16, out_channels=120, kernel_size=5, stride=1, padding=0), # C5 卷积层
    nn.Tanh(),
    nn.Flatten(),
    nn.Linear(in_features=120, out_features=84), # F6 全连接层
    nn.Tanh(),
    nn.Linear(in_features=84, out_features=10) # OUTPUT 全连接层
)


nn.Tanh():激活函数

nn.Flatten():数据拉平

  • 模型可视化



2021020513345087.png


Sequential(新的技术)


  • 代码解析


20210205134920283.png


import paddle.nn as nn
network_2 = nn.Sequential(
    nn.Conv2D(in_channels=1, out_channels=6, kernel_size=3, stride=1, padding=1),  # 卷积
    nn.ReLU(),  # 激活函数
    nn.MaxPool2D(kernel_size=2, stride=2),  # 最大池化
    nn.Conv2D(in_channels=6, out_channels=16, kernel_size=5, stride=1, padding=0),
    nn.ReLU(),
    nn.MaxPool2D(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(in_features=400, out_features=120),  # 400 = 5x5x16,输入形状为32x32, 输入形状为28x28时调整为256
    nn.Linear(in_features=120, out_features=84),
    nn.Linear(in_features=84, out_features=10)
)


模型可视化


20210205135751207.png


  • 这个地方把数据进行了修改使其贴合我们的实践(手写数字识别)


类继承方式书写


20210205141443198.png


class LeNet(nn.Layer):
    """
    继承paddle.nn.Layer定义网络结构
    """
    def __init__(self, num_classes=10):
        """
        初始化函数
        """
        super(LeNet, self).__init__()
        # 卷积
        self.features = nn.Sequential(
            nn.Conv2D(in_channels=1, out_channels=6, kernel_size=3, stride=1, padding=1),  # 第一层卷积
            nn.ReLU(), # 激活函数
            nn.MaxPool2D(kernel_size=2, stride=2),  # 最大池化,下采样
            nn.Conv2D(in_channels=6, out_channels=16, kernel_size=5, stride=1, padding=0), # 第二层卷积
            nn.ReLU(), # 激活函数
            nn.MaxPool2D(kernel_size=2, stride=2) # 最大池化,下采样
        )
        # 全连接
        self.fc = nn.Sequential(
            nn.Linear(400, 120),  # 全连接
            nn.Linear(120, 84),   # 全连接
            nn.Linear(84, num_classes) # 输出层
        )
    def forward(self, inputs):
        """
        前向计算
        """
        y = self.features(inputs)
        y = paddle.flatten(y, 1)  # 拉平成一维
        out = self.fc(y)
        return out
network_3 = LeNet()  # 实例化类


模型可视化


20210205141820634.png


  • 这个地方和上面Sequential的卷积网络一样只是实现的方法不一样
    在注释里面已经标注了每一部分的意义


网络结构代码实现


network_4 = paddle.vision.models.LeNet(num_classes=10)


paddle.vision.models.LeNet():LeNet模型


20210205142451612.png


模型的可视化


20210205142548683.png


模型训练和优化


20210205142710722.png


# 模型封装
model = paddle.Model(network_4)
# 模型配置
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()), # 优化器
              paddle.nn.CrossEntropyLoss(), # 损失函数
              paddle.metric.Accuracy()) # 评估指标
# 启动全流程训练
model.fit(train_dataset,  # 训练数据集
          eval_dataset,   # 评估数据集
          epochs=5,       # 训练轮次
          batch_size=64,  # 单次计算数据样本量
          verbose=1)      # 日志展示形式


评估预测,保存,再训练,保存预测模型


# 评估
result = model.evaluate(eval_dataset, verbose=1)
print(result)
# 进行预测操作
result = model.predict(eval_dataset)
# 保存模型
model.save('finetuning/mnist')
# 继续调优
from paddle.static import InputSpec
network = paddle.vision.models.LeNet(num_classes=10)
# 模型封装,为了后面保存预测模型,这里传入了inputs参数
model_2 = paddle.Model(network, inputs=[InputSpec(shape=[-1, 1, 28, 28], dtype='float32', name='image')])
# 加载之前保存的阶段训练模型
model_2.load('finetuning/mnist')
# 模型配置
model_2.prepare(paddle.optimizer.Adam(learning_rate=0.0001, parameters=network.parameters()),  # 优化器
                paddle.nn.CrossEntropyLoss(), # 损失函数
                paddle.metric.Accuracy()) # 评估函数
# 模型全流程训练
model_2.fit(train_dataset,  # 训练数据集
            eval_dataset,   # 评估数据集
            epochs=2,       # 训练轮次
            batch_size=64,  # 单次计算数据样本量
            verbose=1)      # 日志展示形式
# 保存用于后续推理部署的模型
model_2.save('infer/mnist', training=False)


这部分和第一天的数据基本一样,可以查看第一天的数据进行学习

由于篇幅过长,下面的内容放在第二篇。

第二篇传送门


这里是三岁,飞桨社区最菜的小白

我在AI Studio上获得黄金等级,点亮7个徽章,来互关呀~

CSDN首页

如果喜欢记得关注呦!!!

目录
相关文章
|
3月前
|
传感器 人工智能 算法
AI计算机视觉笔记二十七:YOLOV8实现目标追踪
本文介绍了使用YOLOv8实现人员检测与追踪的方法。通过为每个人员分配唯一ID,实现持续追踪,并可统计人数,适用于小区或办公楼出入管理。首先解释了目标检测与追踪的区别,接着详细描述了使用匈牙利算法和卡尔曼滤波实现目标关联的过程。文章提供了基于IOU实现追踪的具体步骤,包括环境搭建、模型加载及追踪逻辑实现。通过示例代码展示了如何使用YOLOv8进行实时视频处理,并实现人员追踪功能。测试结果显示,该方法在实际场景中具有较好的应用潜力。
|
3月前
|
机器学习/深度学习 人工智能 测试技术
AI计算机视觉笔记二十五:ResNet50训练部署教程
该项目旨在训练ResNet50模型并将其部署到RK3568开发板上。首先介绍了ResNet50网络,该网络由何恺明等人于2015年提出,解决了传统卷积神经网络中的退化问题。项目使用车辆分类数据集进行训练,并提供了数据集下载链接。环境搭建部分详细描述了虚拟环境的创建和所需库的安装。训练过程中,通过`train.py`脚本进行了15轮训练,并可视化了训练和测试结果。最后,项目提供了将模型转换为ONNX和PT格式的方法,以便在RK3568上部署。
|
4月前
|
数据采集 自然语言处理 测试技术
CMU&清华新作:让LLM自己合成数据来学习,特定任务性能同样大幅提升
【8月更文挑战第24天】近期研究提出SELF-GUIDE,一种创新方法,旨在通过大型语言模型(LLMs)自动生成特定任务数据并用于自我微调,以克服其在特定任务上的性能局限。SELF-GUIDE分为三个阶段:数据合成、模型微调及性能评估。通过向目标LLM提供适当提示生成高质量合成数据,并用于微调以提升特定任务表现。实验证明,该方法在Natural Instructions V2等多个基准测试中显著提升了分类与生成任务性能。SELF-GUIDE不仅有效提高性能,还具备高数据效率,减少对外部数据依赖。然而,生成数据质量受限于LLM能力,且并非适用于所有任务。
71 4
|
4月前
|
机器学习/深度学习 数据采集 TensorFlow
从零到精通:TensorFlow与卷积神经网络(CNN)助你成为图像识别高手的终极指南——深入浅出教你搭建首个猫狗分类器,附带实战代码与训练技巧揭秘
【8月更文挑战第31天】本文通过杂文形式介绍了如何利用 TensorFlow 和卷积神经网络(CNN)构建图像识别系统,详细演示了从数据准备、模型构建到训练与评估的全过程。通过具体示例代码,展示了使用 Keras API 训练猫狗分类器的步骤,旨在帮助读者掌握图像识别的核心技术。此外,还探讨了图像识别在物体检测、语义分割等领域的广泛应用前景。
38 0
|
机器学习/深度学习 数据采集 人工智能
给爆火的Llama 2划重点,Huggingface机器学习科学家写了篇分析文章
给爆火的Llama 2划重点,Huggingface机器学习科学家写了篇分析文章
235 1
|
机器学习/深度学习 人工智能 算法
【ICLR 2018】模型集成的TRPO算法【附代码】
【ICLR 2018】模型集成的TRPO算法【附代码】
|
机器学习/深度学习 数据可视化 算法
【paddle深度学习高层API七日打卡营】三岁水课第三天——面部关键点识别
【paddle深度学习高层API七日打卡营】三岁水课第三天——面部关键点识别
155 1
【paddle深度学习高层API七日打卡营】三岁水课第三天——面部关键点识别
|
机器学习/深度学习 自然语言处理 数据可视化
泛化神器 | 李沐老师新作进一步提升模型在多域多的泛化性,CV和NLP均有大幅度提升(文末获取论文)
泛化神器 | 李沐老师新作进一步提升模型在多域多的泛化性,CV和NLP均有大幅度提升(文末获取论文)
258 0
|
机器学习/深度学习 人工智能 运维
ECCV 2022 Oral | 无需微调即可推广,上交大、上海人工智能实验室等提出基于配准的少样本异常检测框架
ECCV 2022 Oral | 无需微调即可推广,上交大、上海人工智能实验室等提出基于配准的少样本异常检测框架
144 0
|
存储
一个框架统一Siamese自监督学习,清华、商汤提出简洁、有效梯度形式,实现SOTA
一个框架统一Siamese自监督学习,清华、商汤提出简洁、有效梯度形式,实现SOTA
125 0