CNN(卷积神经网络)详解

2023-05-16

CNN卷积神经网络详解

    • Why CNN
    • 局部感受野(local receptive fields)
    • 权值共享(Shared weights and biases)
    • 池化(Pooling)
    • 总的来看

Why CNN

首先回答这样一个问题,为什么我们要学CNN,或者说CNN为什么在很多领域收获成功?还是先拿MNIST来当例子说。MNIST数据结构不清楚的话自行百度。。

我自己实验用两个hidden layer的DNN(全连接深度神经网络)在MNIST上也能取得不错的成绩(98.29%)。下面是一个三个hidden layer的网络结构图
在这里插入图片描述
图1

全连接深度神经网络,顾名思义,每个神经元都与相邻层的神经元连接。在这个实验中,每个数字的image是2828,也就是784(=2828)个数值,每个数值对应一个像素值,值的大小反应像素点的强度。这就意味着我们网络的输入层有784个神经元。输出层呢?由于我们是预测0-9这几个数字,输出层当然就是10个神经元了。至于隐藏层节点的个数我们可以自行选定,本实验中选的是500.

我们想想为什么DNN在训练后能够正确地分类?那肯定是它学到了东西,学到什么东西呢?它学到了图片中的某些空间结构,不同数字它们的空间结构肯定是不一样的,而这样的空间结构就是由像素点与像素点之间的关系形成。我们再仔细看DNN输入层和第一个隐藏层,发现它对我们输入的784个像素点是同等对待的,也就是说它此时并没有考虑像素点与像素点之间的关系。有没有一个好点的模型能够考虑到这点呢?那就是CNN

CNN有三个几本思想,局部感受野(local receptive fields) 权值共享(shared weights) 池化(pooling)

局部感受野(local receptive fields)

刚刚我们在DNN中是把输入层784个神经元排成了一条长线,这里我们还原图片原来的样子(28*28),如下图

强迫症的同学就不要数每行每列几个了,我已经数过了是28了。。偷笑
在这里插入图片描述
图2

DNN中,我们会把输入层的每个神经元都与第一个隐藏层的每个神经元连接(看看盗图1)。而在CNN中我们这样做的,第一个隐藏层的神经元只与局部区域输入层的神经元相连。下图就是第一个隐藏层的某个神经元与局部区域输入层的神经元相连的情况。
在这里插入图片描述
图3

这里的局部区域就是局部感受野,它像一个架在输入层上的窗口。你可以认为某一个隐藏层的神经元学习分析了它”视野范围“(局部感受野)里的特征。图中一个隐藏层的神经元有5*5个权值参数与之对应。

我们移动这样一个窗口使它能够扫描整张图,每次移动它都会有一个不同的节点与之对应。我们从输入层左上角开始,如下
在这里插入图片描述
图4

然后,我们一个像素往右滑动一个像素,如下
在这里插入图片描述
图5

以此类推可以形成第一个隐藏层,注意我们的图片是2828的,窗口是55的,可以得到一个24*24(24=28-5+1)个神经元的隐藏层

这里我们的窗口指滑动了一个像素,通常说成一步(stride),也可以滑动多步,这里的stride也是一个超参,训练是可以根据效果调整,同样,窗口大小也是一个超参。

权值共享(Shared weights and biases)

上一节中提到一个隐藏层的神经元有55个权值参数与之对应。这里要补充下,这2424个隐藏层的神经元它们的权值和偏移值是共享的 用公式描述下

σ(b+∑l=04∑m=04wl,maj+l,k+m)
σ代表的是激活函数,如sigmoid函数等,b就是偏移值,w就是55个共享权值矩阵,我们用矩阵a表示输入层的神经元,ax,y表示第x+1行第y+1列那个神经元(注意,这里的下标默认都是从0开始计的,a0,0表示第一行第一列那个神经元)所以通过矩阵w线性mapping后再加上偏移值就得到公式中括号里的式子,表示的是隐藏层中第j+1行k+1列那个神经元的输入。有点晕的话就参照上面的图,图4就是j=k=0的情况,图5是j=0,k=1. 最后加上激活函数就表示该隐藏神经元的输出了。这部分原理和DNN是一样的,如果把w改成2828的矩阵就变成了全连接,就是DNN了。

我们能不能简化一下这个公式呢
a1=σ(b+w∗a0)
a1表示隐藏层的输出,a0表示隐藏层的输入,而∗就表示卷积操作(convolution operation) 这也正是卷积神经网络名字的由来。

由于权值共享,窗口移来移去还是同一个窗口,也就意味着第一个隐藏层所有的神经元从输入层探测(detect)到的是同一种特征(feature),只是从输入层的不同位置探测到(图片的中间,左上角,右下角等等),必须强调下,一个窗口只能学到一种特征!另外,窗口还有其他叫法:卷积核(kernal),过滤器(filter)。我们在做图像识别时光学习一个特征肯定是不够的,我们想要学习更多的特征,就需要更多的窗口。如果用三个窗口的话如下图
在这里插入图片描述
图6

窗口与窗口间的w和b是不共享的,三个窗口就表示有三个w矩阵和三个偏移值b,结果是从整张图片的各个位置学到三种不同的特征。到这里肯定有人会问,你说学到特征了,怎么证明学到了呀?现在我们用20个窗口来学习MNIST里的图片特征,我们只看20个窗口里的权值矩阵w,如果把这20个w画成20张黑白图,每张图片都是5*5(一个权值代表一个像素点),如下图所示
在这里插入图片描述
图7

盯着其中的一张看,白色区域表示权值比较小,说明窗口的这部分对输入层的神经元不敏感(responds less),相反黑色部分表示权值比较大,说明窗口的这部分对输入层的神经元敏感(responds more).每张图片都有明显的黑白区域,这也能够说明CNN确实学到一些和空间结构相关的特征。究竟学的是什么特征呢?这个很难回答清楚,此处暂不深究,更好理解的话可以参考 Visualizing and Understanding Convolutional Networks

权值共享还有一个很大的好处,就是可以大大减少模型参数的个数。我们的例子中,一个窗口参数个数是26(55+1),20个窗口就是520个参数,如果换成全连接的话就是785(2828+1)个参数,比CNN多了265个参数。可能你觉得265嘛,对计算机来说完全不算什么。如果我们是30个隐藏层的DNN的话(深度学习里很常见的),需要23550(785*30)个参数,是CNN的45倍多。。当然我们也不能光光去比较它们参数的个数,毕竟两个模型本质原理上就相差甚远,但是直觉上我们可以感受到,CNN可以依靠更少的参数来获得和DNN相同的效果,更少的参数就意味着更快的训练速度,这可是谁都想要的。

池化(Pooling)

CNN还有一个重要思想就是池化,池化层通常接在卷积层后面。池化这个词听着就很有学问,其实引入它的目的就是为了简化卷积层的输出。通俗地理解,池化层也在卷积层上架了一个窗口,但这个窗口比卷积层的窗口简单许多,不需要w,b这些参数,它只是对窗口范围内的神经元做简单的操作,如求和,求最大值,把求得的值作为池化层神经元的输入值,如下图,这是一个2*2的窗口
在这里插入图片描述
图8

值得注意的是,我们此时的窗口每次移动两步,采用的是求最大值的方法,所有称之为max-pooling,刚刚卷积层含有2424个神经元,经过池化后到池化层就是1212个神经元。通常卷积层的窗口是多个的,池化层的窗口也是多个的。简单来说,卷积层用一个窗口去对输入层做卷积操作,池化层也用一个窗口去对卷积层做池化操作。但是注意这两个操作的本质区别。下面来看一个用三个卷积窗口和跟随其后的池化窗口长啥样。
在这里插入图片描述
图9

怎么理解max-pooling呢?由于经过了卷积操作,模型从输入层学到的特征反映在卷积层上,max-pooling做的事就是去检测这个特征是否在窗口覆盖范围的区域内。这也导致了,它会丢失这种特征所在的精准位置信息,所幸的是池化层可以保留相对位置信息。而后者相比而言比前者更重要。不理解上面的话也没关系,但是需要记住池化层一个最大的好处:经过池化后,大大减少了我们学到的特征值,也就大大减少了后面网络层的参数(上图可以看出池化层的神经元数明显少于卷积层神经元数)。

max-pooling技术只是池化技术的一种,还有一种比较常用的是L2-pooling,与max-pooling唯一的区别就是在池化窗口扫过的区域里做的操作不是求最大值,而是所有神经元平方后求和再开根号,这和我们L2正则对权值参数的操作是一样的。实际操作中,这两种方式都是比较常用的。池化操作方式的选择也是我们调参工作的一部分,我们可以根据validation data集来调节,选择更好的池化操作。

总的来看

介绍完CNN的三个几本思想概念后我们把它串起来看下。
在这里插入图片描述
图10
从左往右依次是输入层,卷积层,池化层,输出层。输入层到卷积层,卷积层到池化层已经详细介绍过了。池化层到输出层是全连接,这和DNN是一样的。
整体上把我CNN的网络架构,其实和DNN很相似,都是一层一层组合起来的,层与层之间的行为也是有对应的权值w和偏移值b决定的,并且它们的目的也是一致的:通过training data来学习网络结构中的w和b,从而能把输入的图片正确分类。很简单吧。

到此为之,CNN的基本原理大致介绍完毕了,如果只需对CNN做大致了解的话上面的内容我想应该足够了。下面主要介绍下其数学原理了,想看可以去原文章看。
原文链接:https://blog.csdn.net/m0_37490039/article/details/79378143

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

CNN(卷积神经网络)详解 的相关文章

  • Single SPI、Dual SPI、Qaud SPI

    博主目前已经用上了 QSPI
  • USB 学习路线

    梳理了一下 USB 的学习路线图 xff0c 供大家参考 xff1a
  • keil5 SW 下载提示 internal command error

    博主手焊板子 xff0c 箭头处 10R 焊接成了 10K xff0c 导致 VDDA 和 VSSA 电压异常 xff0c 下载报错
  • Socket通信(TCP/IP)原理与eclipse实践

    网络上的两个程序通过一个双向的通信连接实现数据的交换 xff0c 这个连接的一端称为一个socket 建立网络通信连接至少要一对端口号 socket socket本质是编程接口 API xff0c 对TCP IP的封装 xff0c TCP
  • C++ WinSock2.h与ws2def.h重定义问题

    在用Visual Studio做开发时 xff0c 代码改动后编译出现大量莫名其妙的错误 xff0c 如下 xff1a 最终解决方法如下 xff1a 如果是win32使用VS原始IDE构建的程序 xff1a 在vs的项目属性设置中找到C C
  • 该主机 CPU 类型不支持虚拟化性能计数器,模块“VPMC”启动失败,未能启动虚拟机。

    该主机 CPU 类型不支持虚拟化性能计数器 模块 VPMC 启动失败 未能启动虚拟机 解决办法 xff1a 点击 虚拟机 设置 选择处理器 右边的三个框框全部去掉 xff0c 不要勾选 xff0c 再次启动虚拟机即可 如果是因为没有开启主机
  • 判断系统是大端还是小端

    文章目录 大端与小端判断大端 小端的三种方式直接观察变量的内存值强制转换 xff1a 将 amp int转换为char 使用联合体union进行判断 大端与小端 大端模式 xff1a 指数据的高字节保存在内存的低地址中 xff0c 低字节保
  • void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)的一些理解

    GPIO TypeDef GPIOA BASE 表示将GPIOA BASE强制转换为指针类型的结构体 xff0c define GPIOA GPIO TypeDef GPIOA BASE 表示用 GPIO TypeDef GPIOA BAS
  • OTT-TV网络电视EPG录制和EPG抓取解决方案

    EPG是Electrical Program Guide xff0c 也就是电子节目单 这个名词的出现和OTT TV或者说IPTV紧密相关 EPG功能是频道化电视以 频道 时间 方式提供一段时间内的所有电视节目信息 xff0c 实现业务浏览
  • ROS noetic 安装编译Cartographer踩坑记录

    ROS noetic 安装编译Cartographer踩坑记录 安装编译工具 span class token function sudo span span class token function apt get span update
  • 用PWM控制舵机(以是stm32为例)

    因为做校创需要用到舵机 xff0c 以前知道大致的理论 xff0c 因此看了一些帖子 xff0c 总结一下被以后查看 什么是PWM波 PWM就是脉冲宽度调制 xff0c 也就是占空比可变的脉冲波形 pwm的占空比 xff0c 就是指高电平保
  • 算法时间复杂度的计算

    一 算法时间复杂度定义 在进行算法分析时候 语句总的执行次数T n 是关于问题规模n的函数 进而分型T n 随着n的变化情况并确定T n 的数量级 算法的时间复杂度 也就是算法的时间度量记作 T n 61 O f n 它表示随着问题规模n的
  • 三角形最小路径和(JS)--自底向上解决(动态规划)

    题目描述 xff1a 给定一个三角形 xff0c 找出自顶向下的最小路径和 每一步只能移动到下一行中相邻的结点上 例如 xff0c 给定三角形 xff1a 2 3 4 6 5 7 4 1 8 3 自顶向下的最小路径和为 11 xff08 即
  • leetcode42--接雨水(JS)

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图 xff0c 计算按此排列的柱子 xff0c 下雨之后能接多少雨水 上面是由数组 0 1 0 2 1 0 1 3 2 1 2 1 表示的高度图 xff0c 在这种情况下 xff0c 可以
  • 自定义组件继承的组件基类React.Component是什么

    我们平时写React组件时都要继承一个父类 xff0c 那就是React Component 也会用到props state和setState xff0c 我们只是会使用它 xff0c 然而不知道它们怎么来的 xff0c 既要知其然也要知其
  • Java 在二维坐标系绘制矩形、圆形、多边形

    最近遇到一个需求 xff0c 大概要求是 xff1a 根据前端传递的参数 xff0c 在Java侧绘制虚拟的二维封闭图形 xff0c 判断各个图形间是否有交集 在java awt包下有个名为Shape的接口 xff0c 可以实现在二维坐标系
  • Uncaught (in promise) TypeError: Cannot read property 'data' of undefined

    最近在学习Redux的时 xff0c 自己写了个Demo xff0c 用fetch异步调用接口时返回这个脑壳疼的问题 问题 xff1a 问题排查 xff1a 一步一步在控制台打印 xff0c 并检测类型 xff0c 发现控制台打印undef
  • Ajax、fetch、axios的区别与优缺点

    背景 前端的技术发展速度非常的快 xff0c 异步请求也是其重要的体现之一 xff0c 从最早的原生XHR xff0c 再到JqueryAjax的统治时代 xff0c 再到近来 xff0c fetch axios等技术也开始出现并大量投入使
  • 什么是 Promise.allSettled() !新手老手都要会?

    什么是 Promise allSettled xff01 新手老手都要会 xff1f Promise allSettled 方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise x
  • 一份稳进Shopee的简历长啥样?

    小伙伴们好 xff0c 我是Eason 简历是求职流程的第一步 xff0c 是很关键的一环 Eason在做Shopee招聘工作时 xff0c 收到了投递的1000 43 的简历 xff0c 简历也修改过50多次 xff0c 最近也帮10多个

随机推荐

  • Vue项目中较优雅地封装Echarts

    场景 1 Echarts 1 使用时 xff0c 都需要写一堆的 option xff0c 如果每个图表都要写一个 xff0c 一个文件里面的代码量是很大的 2 不方便复用 需求 1 方便复用 2 展示类的图表 xff0c 数据与业务 样式
  • React系列--JSX到底是什么东西

    JSX 简介 JSX的全称是 Javascript and XML xff0c React发明了JSX xff0c 它是一种可以在JS中编写XML的语言 JSX更像一种模板 xff0c 类似于Vue中的 template 为什么使用JSX
  • https请求+basic认证

    目录 1 工具类 SSLClient 2 工具类HttpsClientUtil 3 使用 1 工具类 SSLClient 此类可绕过https证书 import org apache http conn ClientConnectionMa
  • 自旋锁的原理及使用

    什么是自旋锁 是指当一个线程在获取锁的时候 xff0c 如果锁已经被其它线程获取 xff0c 那么该线程将循环等待 xff0c 然后不断的判断锁是否能够被成功获取 xff0c 直到获取到锁才会退出循环 获取锁的线程一直处于活跃状态 xff0
  • 实验11 多线程

    1 设有一个银行账户 xff0c 里面有2000元钱 该账户归tom和jack两个人共同所有 每个人每 次可以取100元钱 编写一个类BankAccount表示银行账户 xff0c void withdraw int count 方法表 示
  • stm32 esp8266 ota升级-自建mqtt和文件服务器全量升级

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • rk1126开发板开发记录—SDK环境准备和系统烧录

    序言 最近在弄rk系列的开发板 xff0c 手上正好有一台rk1126的板子 xff0c 因为之前很少接触到嵌入式的东西 xff0c 所以在模型部署的同时遇到了很多坑 xff0c 在此期间也有很多收获 xff0c 习惯性的用文章记录一下开发
  • linux 应用层串口调试函数

    tcgetattr函数与tcsetattr函数 xff08 获取终端信息 xff09 波特率的设置通常使用cfsetospeed和cfsetispeed函数来完成
  • 安装MySQl 8.0遇到的问题及解决方法

    一 官网下载最新版本mysql xff0c 安装完成后 xff0c 安装SQLyog 二 在 C Program Files MySQL MySQL Server 8 0目录中查找是否存在 my ini文件 xff0c 如不存在 xff0c
  • Cmakelists.txt添加.h和.cpp文件

    文件目录结构是这样 代码都是最基本的代码 仅仅是个小的demo cmakelists txt里面的内容 span class token comment cmake的版本要求 span cmake minimum required span
  • 【tcpdump命令使用总结】

    1 tcpdump说明 linux系统的tcpdump命令用来分析数据包分析工具 xff0c 相似的工具有wireshark等 xff0c wireshark使用见 wireshark报文解析ping baidu com 执行tcpdump
  • 使用graphviz+pycallgraph绘制python调用关系图

    绘制python代码调用关系图 前言1 工具安装1 1 安装graphviz1 2 安装pycallgraph2 可视化调用关系 参考文献 前言 一个 python project 中往往包含很多 py 文件 python文件中又会包含很多
  • 用树莓派实现人脸识别打卡门禁系统

    用树莓派实现人脸识别打卡门禁系统的构建 背景功能硬件效果源码摄像头测试代码录入信息人脸识别 结论 背景 源于实习公司的人脸识别打卡系统 xff0c 完成之前的项目后正好没有事情干 xff0c 于是想到了这个 xff0c 公司的这个打卡系统操
  • 一个多功能智能小车的想法

    其实一直以来都有这个想法 xff0c 但是一直没有付出行动 xff0c 学了一些专业知识之后就有了一个想法 xff0c 制作一个智能的 xff0c 非常炫酷的并且看起来就很不普通的一个机器人 xff0c 比如像机器人总动员里的瓦力 xff1
  • “2020 博客之星”年度总评选 TOP 200 名单已出,速来认领!

    经过为期半个月的激烈角逐 xff0c 2020博客之星海选投票已正式落下帷幕 成功的程序员离不开技术之路的踽踽独行 xff0c 同时也离不开社区同盟的鼎力拥趸 以下博主们在此次票选中获得了强有力的支持 xff0c 为他们一整年的技术输出添上
  • 三自由度机械臂的三维设计

    三自由度机械臂的三维设计 背景底座设计机械臂设计关节连接方式底座与机械臂的连接方式效果 背景 写本篇文章的时候只是模型设计完成以及部分零件进行了采购 xff0c 最终是否能实现不能确定 xff0c 某些图片过于辣眼 xff0c 请多担待 继
  • 气动爬行机器人设计

    气动爬行机器人设计 简介项目规则想法原理电控原理腿部机构转向机构其他结构 结语 简介 最近在学校做一个气动的爬行机器人 xff0c 算是一个二级项目 xff0c 虽然名义上有分组 xff0c 但是基本上是我自己在做 xff0c 觉得有些东西
  • ImportError: cannot import name 'Flask'解决方法

    在写bug的时候发现了这么一个错误 xff0c ImportError cannot import name Flask xff0c 自己建一个test脚本 xff0c 代码复制过去后发现可以运行 xff0c 经检查发现脚本文件的名称可能和
  • python lambda表达式详解

    64 python lambda表达式详解 1 lambda简介 先来看一段代码示例 xff1a 第一行是lambda声明 xff0c x y相当于传入的参数 xff0c 整个函数会返回x 43 y的值 lambda作为一个表达式 xff0
  • CNN(卷积神经网络)详解

    CNN卷积神经网络详解 Why CNN局部感受野 local receptive fields 权值共享 Shared weights and biases 池化 Pooling 总的来看 Why CNN 首先回答这样一个问题 xff0c