【笔记】深度学习入门:基于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://www.hqwc.cn/news/497185.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MATLAB】MVMD_ MFE_SVM_LSTM 神经网络时序预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 MVMD_MFE_SVM_LSTM神经网络时序预测算法结合了多变量多尺度分解(MVMD)、多尺度特征提取(MFE)、支持向量机(SVM)和长…

NFS服务器挂载失败问题

问题 mount.nfs: requested NFS version or transport protocol is not supported背景:现在做嵌入式开发,需要在板端挂载服务器,读取服务器文件。挂载中遇到该问题。 挂载命令长这样 mount -t nfs -o nolock (XXX.IP):/mnt/disk1/zixi01.ch…

Apache Bench(ab )压力测试

目录 参数说明示例1:压力测试示例2:测试post接口post数据文件该如何编写? apr_pollset_poll: The timeout specified has expired (70007)apr_socket_recv: Connection reset by peer (104)参考 参数说明 官方文档参考这里。 ab -c 100 -n …

搭建 LNMP 架构

一 理论知识 (一)架构图 (二)CGI 由来 最早的Web服务器只能简单她响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html文件,但是后期随着网站功能增多网站开…

[CSS]文字旁边的竖线以及布局知识

场景:文字前面常见加竖线。 .center-title { 常见内容color: #FFF;font-family: "Source Han Sans CN";font-size: 50px;font-style: normal;font-weight: 700;line-height: normal;position: relative; 要定位left: 16px; 这里是想拉开间距margin-b…

【React架构 - Scheduler中的MessageChannel】

前序 我们都知道JS代码是在浏览器5个进程(下面有介绍)中渲染进程中的Js引擎线程执行的,其他还有GUI渲染线程、定时器线程等,而页面的布局和绘制是在GUI线程中完成的,这些线程之间是互斥的,所以在执行Js的同时会阻塞页面的渲染绘制…

网络爬虫的危害,如何有效的防止非法利用

近年来,不法分子利用“爬虫”软件收集公民隐私数据案件屡见不鲜。2023年8月23日,北京市高级人民法院召开北京法院侵犯公民个人信息犯罪案件审判情况新闻通报会,通报侵犯公民个人隐私信息案件审判情况,并发布典型案例。在这些典型案…

从零开始手写RPC框架(1)

学习java后端也有一段时间了,在网上寻一些教程和github上的开源库,学习从零开始手写一个RPC,学习各位大牛的代码适当修改,并贴上自己的一些见解和注释。 目录 RPC简介RPC和HttpClient的区别和共同点常见RPC框架 RPC框架设计常见序…

知识付费APP软件开发流程

现在在网上学习知识大部分免费的很多,付费也站一部分。也有些人会利用稀少的资源进行付费推广,在以后的发展中付费的趋势将会越来越严重,毕竟别人辛苦制作的知识很轻松的就被别人拿去卖了就会出现付出和收入不成正比。知识付费的APP软件也将会…

Git自动忽略dll文件的问题

检查了半天发现是sourcetreee的全局忽略文件导致, 从里面删除dll即可。 我是干脆直接删了全局忽略,太恶心了,如下: #ignore thumbnails created by windows Thumbs.db #Ignore files build by Visual Studio *.exe .vsconfig .s…

C#,动态规划(DP)金矿问题(Gold Mine Problem)的算法与源代码

1 金矿问题(Gold Mine Problem) 给定一个N*M尺寸的金矿,每个点都有一个非负数表示当前点所含的黄金数目,最开始矿工位于第一列,但是可以位于任意行。矿工只能向右,右上,右下三个方向移动。问该…

Java项目:29 基于SpringBoot+thymeleaf实现的图书管理系统

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 基于SpringBootthymeleaf实现的图书管理系统分为管理员、读者两个登录角色,一共是8个功能模块 管理员权限 图书管理: 添加图…