学习《TensorFlow实战Google深度学习框架》(九)LeNet-5模型

2023-10-27

6.4 经典卷积网络模型

6.4.4 LeNet-5模型

LeNet-5模型是Yann LeCun教授于1998年在论文Gradient-based learning applied to document recognition中提出的,它是第一个成功应用于数字识别问题的卷积神经网络。在MNIST数据集上,LeNet-5模型可以达到大约99.2%的正确率。

LeNet-5模型的架构

在这里插入图片描述

  • 第一层、卷积层
    这一层的输入就是原始的图像像素,LeNet-5模型接收的输入层大小为32×32×1。第一个卷积层的卷积核尺寸为5×5×1,有六个,不使用全0填充,步长为1。因为没有使用全0填充,所以这一层的输出的尺寸为32-5+1=28,深度为6。这一个卷积层总共有5×5×1×6+6=156个参数,其中6个偏置项参数。因为下一层节点矩阵有28×28×6=4704个节点,每个节点和5×5=25个当前层节点相连,所以本层卷积层总共有4704×(25+1)=122304个连接。
  • 第二层、池化层
    这一层的输入为第一层的输出,是一个28×28×6的节点矩阵。本层采用的过滤器大小为2×2,长和宽的步长均为2,所以本层的输出矩阵大小为14×14×6。
  • 第三层、卷积层
    本层的输入矩阵大小为14×14×6,使用的卷积核尺寸为5×5×6,个数为16。本层不使用全0填充,步长为1。本层的输出矩阵大小为10×10×16。按照标准的卷积层,本层应该有5×5×6×16+16=2416个参数,10×10×16×(25+1)=41600个连接。
  • 第四层、池化层
    本层的输入矩阵大小为10×10×16,采用的过滤器大小为2×2,步长为2。本层输出矩阵尺寸为5×5×16。
  • 第五层、全连接层
    本层的输入矩阵大小为5×5×16,在LeNet-5模型的论文中将这一层成为卷积层,但是因为卷积核的大小就是5×5,所以和全连接层没有区别,在之后的TensorFlow程序实现中也会将这一层看成全连接层。本层的输出节点个数为120,也就是说有120个卷积核,总共有5×5×16×120+120=48120个参数。
  • 第六层、全连接层
    本层的输入节点个数为120个,输出节点个数为84个,总共参数为120×84+84=10164个。
  • 第七层、全连接层
    本层的输入节点个数为84个,输出节点个数为10个,总共参数为84×10+10=850个。
    下面给出一个TensorFlow的程序来实现一个类似LeNet-5模型的卷积神经网络来解决MNIST数字识别问题。

源代码

# 调整输入数据格式,输入一个四维矩阵
x = tf.placeholder(tf.float32, [
    mnist_train.BATCH_SIZE,
    mnist_inference.IMAGE_SIZE,
    mnist_inference.IMAGE_SIZE,
    mnist_inference.NUM_CHANNELS],
                   name='x-input')

# 类似地将输入的训练数据格式调整为一个四维矩阵,并将这个调整后的数据传入sess.run过程
reshaped_xs = np.reshape(xs, (mnist_train.BATCH_SIZE,
                              mnist_inference.IMAGE_SIZE,
                              mnist_inference.IMAGE_SIZE,
                              mnist_inference.NUM_CHANNELS))

然后实现类似LeNet-5的前向传播过程

# mnist_inference.py
# -*- coding: utf-8 -*-
# @Time    : 2019/3/15 20:58
# @Author  : Chord
import tensorflow as tf;

# 定义神经网络结构相关参数
INPUT_NODE = 784
OUTPUT_NODE = 10

# 定义输入图像尺寸和通道数
IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10

# 第一层卷积层的尺寸和卷积核数量
CONV1_NUM = 32
CONV1_SIZE = 5
# 第二层卷积层的尺寸和卷积核数量
CONV2_NUM = 64
CONV2_SIZE = 5
# 全连接层节点个数
FC_SIZE = 512

# 定义卷积神经网络的前向传播过程。这里添加了一个新的参数train,用于区分训练过程和测试
# 过程。在这个程序中将用到dropout方法dropout可以进一步提升模型可靠性并防止过拟合,
# dropout过程只在训练时使用
def inference(input_tensor, train, regularizer):
    # 声明第一层卷积层的变量并实现前向传播过程。这个过程通过使用不同命名空间来隔离不
    # 同层的变量,这可以让每一层中的变量命名只需要考虑在当前层的作用,而不需要担心重
    # 名的问题。和标准LeNet-5模型不大一样,这里定义的卷积层输入为28×28×1的原始MNIST
    # 图片像素。因为卷积层中使用了全0填充,所以输出为28×28×32的矩阵
    with tf.variable_scope('layer1-conv1'):
        conv1_weights = tf.get_variable(
            "weight", [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_NUM],
            initializer=tf.truncated_normal_initializer(stddev=0.1)
        )
        conv1_biases = tf.get_variable(
            "bias", [CONV1_NUM], initializer=tf.constant_initializer(0.0)
        )

        # 使用32个5×5的卷积核,步长为1,且使用全0填充
        conv1 = tf.nn.conv2d(
            input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME'
        )
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))

    # 实现第二层池化层的前向传播过程。这里选用最大池化层,池化层过滤器的边长为2,使用全0
    # 填充且步长为2.这一层的输入时上一层的输出,也就是28×28×32的矩阵。输出为14×14×32的矩阵
    with tf.name_scope('layer2-pool1'):
        pool1 = tf.nn.max_pool(
            relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME'
        )

    # 声明第三层卷积层的变量并实现前向传播过程,输入为14×14×32,输出为7×7×64
    with tf.variable_scope('layer3-conv2'):
        conv2_weights = tf.get_variable(
            "weight", [CONV2_SIZE, CONV2_SIZE, CONV1_NUM, CONV2_NUM],
            initializer=tf.truncated_normal_initializer(stddev=0.1)
        )
        conv2_biases = tf.get_variable(
            "bias", [CONV2_NUM], initializer=tf.constant_initializer(0.0)
        )
        # 64个5×5的卷积核,步长为1,全0填充
        conv2 = tf.nn.conv2d(
            pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME'
        )
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

    # 实现第四层池化层的前向传播过程。这一层和第二层的结构是一样的。输入14×14×64,输出7×7×64
    with tf.name_scope('layer4-pool2'):
        pool2 = tf.nn.max_pool(
            relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME'
        )

    # 将第四层池化层的输出转化为第五层全连接层的输入格式。第四层的输出为7×7×64的矩阵,然而第五层
    # 全连接层需要的输入格式为向量,所以在这里需要将这个7×7×64的矩阵拉直成一个向量。pool2.get_shape
    # 函数可以得到第四层输出矩阵的维度为不需要手工计算。注意因为每一层的神经网络的输入输出都为一个batch
    # 的矩阵,所以这里得到的维度也包含了一个batch中数据的个数
    pool_shape = pool2.get_shape().as_list()

    # 计算将矩阵拉直成响亮之后的长度,这个长度就是矩阵长宽与深度的乘积
    # 注意这个pool_shape[0]为一个batch中数据的个数
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]

    # 通过tf.reshape函数将第四层的输出变成一个batch的向量
    reshaped = tf.reshape(pool2, [pool_shape[0], nodes])

    # 声明第五层全连接层的变量并实现前向传播过程。这一层的输入时拉直后的一组向量,向量长度为3136,
    # 输出是一组长度为512的向量。这一层引入了fropout的概念。fropout在训练时会随机将部分节点的输出改为0。
    # dropout可以避免过拟合问题,从而使得模型在测试数据上的效果更好。
    # dropout一般只在全连接层而不是卷积层或池化层使用
    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable(
            "weight", [nodes, FC_SIZE],
            initializer=tf.truncated_normal_initializer(stddev=0.1)
        )
        # 只有全连接层的权重需要加入正则化
        if (regularizer!=None):
            tf.add_to_collection('losses', regularizer(fc1_weights))
        fc1_biases = tf.get_variable(
            'bias', [FC_SIZE], initializer=tf.constant_initializer(0.1)
        )

        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
        if (train):
            fc1 = tf.nn.dropout(fc1, 0.5)

        # 声明第六层全连接层的变量并实现前向传播过程。这一层输入为一组长度为512的向量,输出为一组长度为10的向量。
        # 这一层通过Softmax之后就得到了最后的分类结果
        with tf.variable_scope('layer6-fc2'):
            fc2_weights = tf.get_variable(
                "weight", [FC_SIZE, NUM_LABELS],
                initializer=tf.truncated_normal_initializer(stddev=0.1)
            )
            if (regularizer!=None):
                tf.add_to_collection('losses', regularizer(fc2_weights))
            fc2_biases = tf.get_variable(
                'bias', [NUM_LABELS], initializer=tf.constant_initializer(0.1)
            )
            logit = tf.matmul(fc1, fc2_weights) + fc2_biases



        # 返回第六层的输出
        return logit;
# 初始学习率为0.8
After 1 training step(s), loss on training batch is 8.06673.
After 1001 training step(s), loss on training batch is 904.366.
After 2001 training step(s), loss on training batch is 774.32.
After 3001 training step(s), loss on training batch is 664.866.
After 4001 training step(s), loss on training batch is 572.533.
感觉就是学习率太大给整歪了,试图减小学习率,然后发现损失降低了很多,而且一点点减小
# 降低学习率为0.1
After 1 training step(s), loss on training batch is 7.05461.
After 1001 training step(s), loss on training batch is 0.734978.
After 2001 training step(s), loss on training batch is 0.671189.
After 3001 training step(s), loss on training batch is 0.621566.
After 4001 training step(s), loss on training batch is 0.589219.

类似的修改了mnist_eval的输入部分,就可以测算正确率了

# 学习率0.8
After 4001 training step(s), validation accuracy = 0.06
# 学习率0.1
After 4001 training step(s), validation accuracy = 0.99

输入层→(卷积层+→池化层?)+→全连接层+

  • “卷积层+”表示一层或多层卷积层,一般最多连续使用三层卷积层。
  • “池化层?”表示没有或者一层池化层,池化层虽然可以减少参数防止过拟合问题,但是在部分论文中也发现可以直接通过调整卷积层步长来实现同样的效果。
  • “(卷积层+→池化层?)+”表示括号内作为组合,可以连续出现多次。
  • “全连接层+”表示多层全连接层。

如LeNet-5模型为如下结构,输入层→卷积层→池化层→卷积层→池化层→全连接层→全连接层→输出层。

下表展示了VGGNet论文Very Deep Convolutional Networks for Large-Scale Image Recognition中作者尝试过的不同卷积神经网络架构。
在这里插入图片描述
convX-Y表示卷积的边长为X,个数为Y。
VGGNet的卷积核边长一般是3或者1。
一般卷积核的大小不会超过5。
在卷积核的数量上,大部分卷积神经网络都采用逐层递增的方式。
池化层的配置相对简单,一般都是采用最大池化层。
池化层的过滤器边长一般为2或者3,步长也一般为2或者3。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习《TensorFlow实战Google深度学习框架》(九)LeNet-5模型 的相关文章

  • 大龄单身,这些人真作。

    大家好 我是北妈 0 前些天想办法给一亲戚弟弟介绍个妹子 弟29 妹子28 两人基本恋爱0经验 皇帝不急太监急 今天两人见面 随问之 弟弟答曰 还可以 就是不知说啥 妹子答曰 还可以 到感觉不太合适 感觉不太爱说话 自己就不太爱说话 想找一
  • 关联分析——关联规则应用及案例

    数据挖掘最早使用的方法是关联分析 主要应用于零售业 其中最有名的是售货 篮分析 帮助售货商制定销售策略 数据挖掘是从海量的数据里寻找有价值的信息和数据 数据挖掘中常用的算法有 关联规则分析法 解决事件之间的关联问题 决策树分类法 对数据 和
  • 大数据--python远程连接Hive

    步骤 启动metastore 启动hiveserver2 使用beeline进行连接测试 查看地址等是否能够成功连接 确认无误可以跳过 使用python连接hive 粗暴的文件配置以及完整操作见文末 一 启动hiveserver2 1 配置
  • springboot应用无故停止运行killed解决方法

    最近使用springboot开发了一个ip代理的程序 今天放到阿里云服务器上运行 多次出现应用运行突然停止的问题 使用free h 查看内存使用完全正常 重新运行监视CPU使用也正常 没有出现堆内存溢出 栈内存异常 内存异常等信息 百思不得
  • 电力系统故障分类数据生成模型(基于simulink仿真批量生成故障数据)

    电力系统是发电 输电 配电和利用系统的组合 简而言之 电力系统是任何电气系统的心脏 在电力系统中 故障或故障电流是任何异常电流 由于此类故障 整个系统可能会损坏并最终崩溃 这项工作的目的是将故障自动分类为 11 个故障类别之一 其中包括平衡

随机推荐

  • 彻底弄懂二叉树的先序、中序、后序三种遍历与做题

    最近有同学考计算机二级不懂树遍历的计算 就找上我解惑 作为老好人的博主的我 但是义不容辞的上来阐述了一番 先来官方的概念 树的遍历 是指对树中所有结点信息的访问 即依次对树中每个结点的访问一次且仅访问一次 分为 先序遍历 后序遍历 层次遍历
  • java ip地址转数字,java版ip地址与整数的互相转换

    在工作中可能会遇到将ip地址转为long型的整数 或者将十进制整数转换为ip地址的情况 下面介绍一种转换的方法 一 将ip地址转成long数值 将IP地址转化成整数的方法如下 1 通过String的split方法按 分隔得到4个长度的数组
  • 被骗几十万总结出来的Ddos攻击防护经验!

    转载地址 http www ijiandao com safe cto 15952 html 本人从事网络安全行业20年 有15年防ddos攻击防护经验 被骗了很多回 都说能防300G 500G 买完就防不住了 本文当然重点给大家说明 dd
  • Flask4:methods=[‘POST‘, ‘GET‘]

    从服务器上获取数据 用GET请求 前端把数据发给服务器 用POST请求 在 app route上 添加methods参数 这个参数是一个列表类型 可以传递多个 右键页面 检查 中
  • Vue3/ Vue3 和 Vue2 生命周期函数不同点 总结、Vue2 和 Vue3 里面父组件的生命周期顺序

    一 Vue3 x 和 Vue2 x 生命周期函数不同点 总结 Vue2 vue3 beforeCreate gt setup 开始创建组件之前执行 created gt setup 开始创建组件之前执行 beforeMount gt onB
  • 【满分】【华为OD机试真题2023 JS】简单的解压缩算法

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 简单的解压缩算法 知识点栈 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 现需要实现一种算法 能将一组压缩字符串还原成原始字符串 还原规则如下 1 字符后面加数
  • 高并发短信平台实现

    01 短信介绍 在项目介绍的时候 已经定义了austin项目的核心功能 发送消息 我认为 短信是在一整个消息推送平台里最重要的一个消息类型了 毕竟关联了很多重要的业务场景 想想我们日常使用APP时的场景 验证码 登录注册 支付等等重要场景
  • matplotlib 绘制Sigmoid函数,Tanh函数,ReLU函数

    import numpy as np import matplotlib pyplot as plt def sigmoid x return 1 1 np exp x def tanh x return np exp x np exp x
  • python global函数用法及常用的 global函数代码

    Python中的 global函数是用于在程序中定义变量的函数 在我们实际的开发中 我们可能会用到 global函数来定义变量 但是我们在这里就不具体介绍它的用法了 global函数定义变量的方法 global函数使用参数a来指定变量在程序
  • 外卖点餐系统小程序 PHP+UniAPP

    一 介绍 本项目是给某大学餐厅开发的外面点餐系统 该项目针对校内的学生 配送由学校的学生负责配送 因此 该项目不同于互联网的外卖点餐系统 该系统支持属于 Saas 系统 由平台端 商家端 用户端 以及配送端组成 其中 平台端 商家端是由基于
  • 520七夕表白,还不懂浪漫?4套代码教会你如何深情表白【建议收藏】❤️

    马上又到了脱单的黄金时刻 七夕啦 如果你有喜欢的女孩子 一定要趁着这个时候把喜欢说出口 但是该不会还有人表白在学校的操场上摆着爱心蜡烛抱一束花喊一堆人来围观吧 No 请你立刻马上放弃这个计划 毫无心意不说 对于女孩子来说是真的很社死啊 PS
  • linux 查看java安装目录

    这本阿里P8撰写的算法笔记 再次推荐给大家 身边不少朋友学完这本书最后加入大厂 Github 疯传 史上最强悍 阿里大佬 LeetCode刷题手册 开放下载了 获取java安装路径前要判断是否已经安装成功java 执行命令 java 1 U
  • 清晰图解,一图看懂图卷积GCN、时空图卷积ST-GCN

    目录 1 前言 2 普通卷积与图卷积 2 1 普通卷积 2 2 图卷积 3 ST GCN图卷积的代码解读 4 图卷积的缺陷 5 参考文献 6 联系方式 1 前言 本文为我阅读论文 Spatial Temporal Graph Convolu
  • 微信小程序API~GET

    框架提供丰富的微信原生API 可以方便的调起微信提供的能力 如获取用户信息 本地存储 支付功能等 1 wx on 开头的 API 是监听某个事件发生的API接口 接受一个 CALLBACK 函数作为参数 当该事件触发时 会调用 CALLBA
  • libmysqlclient.so.15: cannot open shared object file: No such file or directory

    libmysqlclient so 15 cannot open shared object file No such file or directory 分类 mysql服务器管理优化 2009 06 02 16 11 26769人阅读
  • DC系列漏洞靶场-渗透测试学习复现(DC-6)

    DC 6是一个易受攻击的实验环境 最终目的是让攻击者获得root权限 并读取flag DC 6使用的操作系统为Debian 64位 靶场下载链接 1 http www five86 com downloads DC 6 zip 2 http
  • P2141 [NOIP2014 普及组] 珠心算测验

    题目描述 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术 珠心算训练 既能够开发智力 又能够为日常生活带来很多便利 因而在很多学校得到普及 某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法 他随机生成一个正整数集合
  • HTML之表格篇——表格的嵌套

    表格的嵌套一方面是为使页面 贴子 的外观更为漂亮 利用表格嵌套来编辑出复杂而精美的效果 另一方面是出于布局需要 用一些嵌套方式的表格来做精确的编排 或者二者兼而有之 熟练地掌握表格的嵌套技巧并不是很困难的 只要你思路清晰 对表格的整体嵌套构
  • Shiro源码分析之ShiroFilterFactoryBean

    创建核心Filter 同其他框架一样 都有个切入点 这个核心Filter就是拦截所有请求的 通过web xml中配置的Filer进入 执行init方法获取这个instance 调用下面的createInstance方法创建核心Filter
  • 学习《TensorFlow实战Google深度学习框架》(九)LeNet-5模型

    文章目录 6 4 经典卷积网络模型 6 4 4 LeNet 5模型 LeNet 5模型的架构 源代码 6 4 经典卷积网络模型 6 4 4 LeNet 5模型 LeNet 5模型是Yann LeCun教授于1998年在论文Gradient