【笔记】深度学习入门:基于Python的理论与实现(五)

卷积神经网络

卷积神经网络(Convolutional Neural Network,CNN)

整体结构

CNN 中新出现了卷积层(Convolution 层)和池化层(Pooling 层),之前介绍的神经网络中,相邻层的所有神经元之间都有连接,这称为全 连接(fully-connected)

全连接层:
在这里插入图片描述
CNN层:
在这里插入图片描述

卷积层

全连接层存在的问题

数据的形状被“忽视”了。比如,输 入数据是图像时,图像通常是高、长、通道方向上的 3 维形状。但是,向全 连接层输入时,需要将 3 维数据拉平为 1 维数据,而卷积层可以保持形状不变。当输入数据是图像时,卷积层会以 3 维数据的形式接收输入数据,并同样以 3 维数据的形式输出至下一层。

CNN中,有时将卷积层的输入输出数据称为特征图(feature map)。其中,卷积层的输入数据称为输入特征图(input feature map),输出数据称为输出特征图(output feature map)。

卷积运算

卷积层进行的处理就是卷积运算。卷积运算相当于图像处理中的“滤波器运算”,例子:

将各个位置上滤波器的元素和输入的对应元素相乘,然后再求和(有时将这个计算称为乘积 累加运算),注意:这里的乘积不是矩阵的乘积,是对应元素两个的乘积,然后再都加起来! ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
在这里插入图片描述
偏置:
在这里插入图片描述

填充

在进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据(比 如 0 等),这称为填充(padding),使用填充主要是为了调整输出的大小

“幅 度为 1 的填充”是指用幅度为 1 像素的 0 填充周围,虚线里面的是0。
在这里插入图片描述

步幅

应用滤波器的位置间隔称为步幅(stride)

步幅为2 跳跃两个间隔的例子
在这里插入图片描述

对于填充和步幅,如何计算输出大小

假设输入大小为 (H, W),滤波器大小为 (FH, FW),输出大小为 (OH, OW),填充为 P,步幅为 S
在这里插入图片描述
如:输入大小:(28, 31);填充:2;步幅:3;滤波器大小:(5, 5)
在这里插入图片描述

3 维数据的卷积运算

通道方向上有多个特征图时,会按通道 进行输入数据和滤波器的卷积运算,并将结果相加,从而得到输出
在这里插入图片描述
在这里插入图片描述

结合方块思考

把 3 维数据表示为多维数组 时,书写顺序为(channel, height, width),比如,通道数为C、高度为H、 长度为 W 的数据的形状可以写成(C, H, W),滤波器也一样,要按(channel, height, width)的顺序书写。比如,通道数为 C、滤波器高度为 FH(Filter Height)、长度为 FW(Filter Width)时,可以写成(C, FH, FW)。
在这里插入图片描述

如果要在通道方向上也拥有多个卷积运算的输出就需要用到多个滤波器(权重),作为 4 维数据,滤波器的权重数据要按 (output_channel, input_ channel, height, width) 的顺序书写。比如,通道数为 3、大小为 5 × 5 的滤 波器有 20 个时,可以写成 (20, 3, 5, 5)。
在这里插入图片描述
进 一步追加偏置的加法运算处理
在这里插入图片描述

批处理

需要将在各层间传递的数 据保存为 4 维数据。具体地讲,就是按 (batch_num, channel, height, width) 的顺序保存数据
在这里插入图片描述

池化层

池化是缩小高、长方向上的空间的运算,比如,进行将2 × 2 的区域集约成 1 个元素的处理,缩小空间大小。

Max池(Max 池化”是获取最大值的运算),按步幅 2 进行 2 × 2 的 Max 池化时的处理顺序:
在这里插入图片描述
一般来说,池化的窗口大小会 和步幅设定成相同的值。比如,3 × 3 的窗口的步幅会设为 3,4 × 4 的窗口 的步幅会设为 4 等。

突出特点:对微小的位置变化具有鲁棒性(健壮),即输入数据发生微小偏差时,池化仍会返回相同的结果

卷积层和池化层的实现

4 维数组

# 10 个高为 28、长为 28、通道为 1 的数 据
>>> x = np.random.rand(10, 1, 28, 28) # 随机生成数据 
>>> x.shape
(10, 1, 28, 28)
# 如果要访问第 1 个数据的第 1 个通道的空间数据
>>> x[0, 0] # 或者x[0][0]

基于 im2col 的展开

如果老老实实地实现卷积运算,估计要重复好几层的 for 语句,我们不使用 for 语句,而是使 用 im2col (名 称 是“image to column”的 缩 写,翻 译 过 来 就 是“从 图像到矩阵”的意思) 这个便利的函数进行简单的实现。im2col 是一个函数,将输入数据展开以适合滤波器(权重),对 3 维的输入数据应用 im2col 后,数据转换为 2 维矩阵
在这里插入图片描述

对于输入数据,将应用滤波器的区域(3维方块)横向展开为1列。im2col会 在所有应用滤波器的地方进行这个展开处理。
在这里插入图片描述

而在实际的卷积运算中,滤波器的应用区域几乎都是重叠的。在 滤波器的应用区域重叠的情况下,使用 im2col 展开后,展开后的元素个数会 多于原方块的元素个数。因此,使用 im2col 的实现存在比普通的实现消耗更 多内存的缺点,之后就只需将卷积层的滤波器(权重)纵 向展开为1列,并计算2个矩阵的乘积即可
在这里插入图片描述

卷积层的实现

# input_data― 由(数据量,通道,高,长)的4维数组构成的输入数据 filter_h― 滤波器的高 filter_w― 滤波器的长 stride― 步幅 pad― 填充
im2col (input_data, filter_h, filter_w, stride=1, pad=0)# 卷积层实现
class Convolution:# W(滤波器)def __init__(self, W, b, stride=1, pad=0):self.W = Wself.b = b self.stride = stride self.pad = paddef forward(self, x):FN, C, FH, FW = self.W.shapeN, C, H, W = x.shapeout_h = int(1 + (H + 2*self.pad - FH) / self.stride) out_w = int(1 + (W + 2*self.pad - FW) / self.stride)col = im2col(x, FH, FW, self.stride, self.pad) # 滤波器的展开为二位数组,通过在 reshape 时指定为 -1,reshape 函数会自 动计算 -1 维度上的元素个数,以使多维数组的元素个数前后一致col_W = self.W.reshape(FN, -1).T out = np.dot(col, col_W) + self.b# transpose 会更改多维数组的轴的顺序out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) return out

池化层的实现

在这里插入图片描述

class Pooling:def __init__(self, pool_h, pool_w, stride=1, pad=0):self.pool_h = pool_h self.pool_w = pool_w self.stride = stride self.pad = paddef forward(self, x):N, C, H, W = x.shapeout_h = int(1 + (H - self.pool_h) / self.stride) out_w = int(1 + (W - self.pool_w) / self.stride)# 展开(1)展开输入数据col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h*self.pool_w)# 最大值(2)求各行的最大值out = np.max(col, axis=1)# 转换(3)转换为合适的输出大小out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)return out# 池化层的 backward 处理可以参考 ReLU 层的实现中使用的 max 的反向 传播

CNN 的实现

参数:

  • input_dim― 输入数据的维度:(通道,高,长)
  • conv_param― 卷积层的超参数(字典)。字典的关键字如下:
    filter_num― 滤波器的数量
    filter_size― 滤波器的大小
    stride― 步幅
    pad― 填充
  • hidden_size― 隐藏层(全连接)的神经元数量
  • output_size― 输出层(全连接)的神经元数量
  • weitght_int_std― 初始化时权重的标准差
class SimpleConvNet:# conv_param超参数def __init__(self, input_dim=(1, 28, 28),conv_param={'filter_num':30, 'filter_size':5, 'pad':0, 'stride':1},hidden_size=100, output_size=10, weight_init_std=0.01): filter_num = conv_param['filter_num']filter_size = conv_param['filter_size']filter_pad = conv_param['pad']filter_stride = conv_param['stride']input_size = input_dim[1]conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))# 权重参数的初始化self.params = {} self.params['W1'] = weight_init_std * \ np.random.randn(filter_num, input_dim[0],filter_size, filter_size) 					self.params['b1'] = np.zeros(filter_num)self.params['W2'] = weight_init_std * \ np.random.randn(pool_output_size,hidden_size)self.params['b2'] = np.zeros(hidden_size)self.params['W3'] = weight_init_std * \ np.random.randn(hidden_size, output_size)self.params['b3'] = np.zeros(output_size)# 生成必要的层self.layers = OrderedDict()self.layers['Conv1'] = Convolution(self.params['W1'],self.params['b1'], conv_param['stride'], conv_param['pad'])self.layers['Relu1'] = Relu()self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2) 		self.layers['Affine1'] = Affine(self.params['W2'],self.params['b2'])self.layers['Relu2'] = Relu() self.layers['Affine2'] = Affine(self.params['W3'],self.params['b3']) 	self.last_layer = softmaxwithloss()def predict(self, x):for layer in self.layers.values():x = layer.forward(x) return xdef loss(self, x, t):y = self.predict(x)return self.lastLayer.forward(y, t)# 基于误差反向传播法求梯度def gradient(self, x, t): # forwardself.loss(x, t)# backwarddout = 1dout = self.lastLayer.backward(dout)layers = list(self.layers.values()) layers.reverse()for layer in layers:dout = layer.backward(dout)# 设定grads = {}grads['W1'] = self.layers['Conv1'].dW grads['b1'] = self.layers['Conv1'].db grads['W2'] = self.layers['Affine1'].dW grads['b2'] = self.layers['Affine1'].db grads['W3'] = self.layers['Affine2'].dW grads['b3'] = self.layers['Affine2'].dbreturn grads

CNN 的可视化

探索 CNN 中到底进行了什么处理

第 1 层权重的可视化

学习前的滤波器是随机进行初始化的,所以在黑白的浓淡上 没有规律可循,但学习后的滤波器变成了有规律的图像。我们发现,通过学 习,滤波器被更新成了有规律的滤波器,比如从白到黑渐变的滤波器、含有块状区域(称为 blob)的滤波器等。右边的有规律的滤波器在“观察”边缘(颜色变化的分界线)和斑块(局部的块状区域)等,比如,左半 部分为白色、右半部分为黑色的滤波器的情况下,会对垂直 方向上的边缘有响应。
在这里插入图片描述

基于分层结构的信息提取

随着层次加深,提 取的信息(正确地讲,是反映强烈的神经元)也越来越抽象。下面例子中,第 1 层的神经元对边缘或斑块有响应,第 3 层对纹 理 有 响 应 , 第 5 层 对 物 体 部 件 有 响 应 , 最 后 的 全 连 接 层 对 物 体 的 类 别(狗 或 车)有 响应
在这里插入图片描述

具有代表性的 CNN

特别重要的两个网络,一个是在 1998 年首次被提出的 CNN 元祖 LeNet, 另一个是在深度学习受到关注的 2012 年被提出的 AlexNet。

LeNet

进行手写数字识别的网络,LeNet 有几个不同点。第一个不同点在于激活 函数。LeNet 中使用 sigmoid 函数,而现在的 CNN 中主要使用 ReLU 函数。 此外,原始的LeNet中使用子采样(subsampling)缩小中间数据的大小,而 现在的 CNN 中 Max 池化是主流。

AlexNet

AlexNet 叠有多个卷积层和池化层,最后经由全连接层输出结果。虽然结构上 AlexNet 和 LeNet 没有大的不同,但有以下几点差异。

  • 激活函数使用ReLU。
  • 使用进行局部正规化的LRN(Local Response Normalization)层。
  • 使用Dropout
    在这里插入图片描述

小结

  • CNN在此前的全连接层的网络中新增了卷积层和池化层。
  • 使用im2col函数可以简单、高效地实现卷积层和池化层。
  • 通过CNN的可视化,可知随着层次变深,提取的信息愈加高级。
  • LeNet和AlexNet是CNN的代表性网络。
  • 在深度学习的发展中,大数据和GPU做出了很大的贡献。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Linux Seccomp 简介

文章目录 一、简介二、架构三、Original/Strict Mode四、Seccomp-bpf五、seccomp系统调用六、Linux Capabilities and Seccomp6.1 Linux Capabilities6.2 Linux Seccomp 参考资料 一、简介 Seccomp(secure computing)是Linux内核中的一项计算机安全功能…

4. client-go 编程式交互

Kubernetes 系统使用 client-go 作为 Go 语言的官方编程式交互客户端库,提供对 Kubernetes API Server 服务的交互访问。Kubernetes 的源码中已经集成了 client-go 的源码,无须单独下载。client-go 源码路径为 vendor/k8s.io/client-go。 开发者经常使用…

四种经典限流算法讲解

1. 固定窗口限流算法 1.1 什么是固定窗口限流算法 固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是一种最简单的限流算法,其原理是在固定时间窗口(单位时间)内限制请求的数量。该算法将时间分成固定的窗口,并在每个窗…

【Java】双亲委派机制及其打破的相关知识笔记

目录 类的加载机制 类加载器 双亲委派模型机制 为什么要有双亲委派机制 如何打破双亲委派机制 类的加载机制 类加载过程是由Java虚拟机的类加载子系统完成的,它负责将字节码加载到内存中,并进行链接和初始化操作。类加载过程是Java中非常重要的一部…

六、防御保护---防火墙内容安全篇

六、防御保护---防火墙内容安全篇 一、IAE(Intelligent Awareness Engine)引擎二、深度检测技术(DFI和DPI)2.1 DPI -- 深度包检测技术2.1.1 基于“特征字”的检测技术2.1.2 基于应用网关的检测技术2.1.3 基于行为模式的检测技术 2.2 DFI -- 深…

163邮箱SMTP端口号及服务器地址详细设置?

163邮箱SMTP端口号是什么?163邮件SMTP设置教程? 除了基本的邮箱账号和密码外,还需要了解SMTP服务器地址和端口号,以及相应的设置。这些设置对于确保邮件能够顺利发送至关重要。下面,蜂邮EDM将详细介绍163邮箱SMTP端口…

RF自动化环境安装+自动化实例解析

RF定义: 通用型的 自动测试框架, 绝大部分的软件的的自动化系统都可以采用它。 特点: 测试数据文件(Test Data)对应一个个的测试用例。测试数据文件里面使用的功能小模块叫关键字,由测试库(T…

【八股文学习日记】集合概述

【八股文学习日记】集合概述 集合概述 Java 集合, 也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于Collection 接口&#…

重铸安卓荣光——双向滑块增强

痛点: 公司打算做安卓软件,最近在研究安卓,打算先绘制样式 研究发现安卓并不像前端有那么多组件库,甚至有些基础的组件都需要自己实现,记录一下自己实现的组件 成品展示 上面一条是谷歌提供的双向滑块,下面…

使用空闲电脑免费搭建一个私人的网盘

如果你也有一台空闲电脑,可以使用它来搭建一个私人的网盘。 这里使用的是飞梦云网盘; 服务端:下载 服务器文件使用hash校验进行储存,实现重复上传的文件秒传功能。 Fuse4Ui(虚拟分区工具):下…

精品基于SpringBoot的体育馆场地预约赛事管理系统的设计与实现-选座

《[含文档PPT源码等]精品基于SpringBoot的体育馆管理系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功! 软件开发环境及开发工具: Java——涉及技术: 前端使用技术&#…

雾锁王国服务器要开服务器吗?

雾锁王国要开服务器吗?可以使用官方服务器,也可以自己搭建多人联机服务器,更稳定不卡,畅玩开黑。阿腾云分享atengyun.com给大家目前阿里云和腾讯云均提供雾锁王国服务器和一键搭建程序,成本26元即可搭建一台自己的雾锁…

初识Maven

介绍: web后端开发技术ApacheMaven是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。安装:http://maven.apache.org/ Apache软件基金会,成立于19…

pdf转word文档怎么转?分享4种转换方法

pdf转word文档怎么转?在日常工作中,我们经常遇到需要将PDF文件转换为Word文档的情况。无论是为了编辑、修改还是为了重新排版,将PDF转为Word都显得尤为重要。那么,PDF转Word文档怎么转呢?今天,就为大家分享…

【web】nginx+php环境搭建-关键点(简版)

一、nginx和php常用命令 命令功能Nginxphp-fpm启动systemctl start nginxsystemctl start php-fpm停止systemctl stop nginxsystemctl stop php-fpm重启systemctl restart nginxsystemctl restart php-fpm查看启动状态systemctl status nginxsystemctl status php-fpm开机自启…

分布式锁的应用与疑惑

文章目录 一、为什么需要用分布式锁二、Redis实现分布式锁三、Zookeeper实现分布式锁 一、为什么需要用分布式锁 集群下,普通的锁,无法解决问题 集群下,保证安全需要使用分布式锁 二、Redis实现分布式锁 Redisson内部封装的RedLock实现分…

有哪些ai写作软件值得推荐?这篇文章告诉你

目前AI写作软件成为越来越多写作爱好者和专业作者的首选工具。随着人工智能技术的迅猛发展,在国内,也涌现出了许多实用且好用的AI写作神器。在本文中,我将为您介绍7个国内好用的AI写作软件,同时介绍它们的优点和使用特点。 一、爱…

RV32/64 特权架构 - 特权模式与指令

RV32/64 特权架构 - 特权模式与指令 1 特权模式2 特权指令2.1 mret(从机器模式返回到先前的模式)2.2 sret(从监管模式返回到先前的模式)2.3 wfi(等待中断)2.4 sfence.vma(内存屏障) …

高级语言期末2011级A卷(软件学院)

1.编写函数&#xff0c;判定正整数m和n&#xff08;均至少为2&#xff09;是否满足&#xff1a;数m为数n可分解的最小质因数&#xff08;数n可分解的最小质因数为整除n的最小质数&#xff09; 提示&#xff1a;判定m为质数且m是n的最小因数 #include <stdio.h> #include…

【C语言】linux内核ipoib模块 - ipoib_ib_post_receive

一、中文注释 用于以太网接口&#xff08;InfiniBand&#xff09;上的IP over IB&#xff08;IPoIB&#xff09;设备的Linux内核函数&#xff0c;负责将接收缓冲区&#xff08;一个包&#xff09;提交到网络设备的队列中等待数据到达。下面是中文注释版本的函数代码&#xff1…