第六章.卷积神经网络(CNN)—卷积层(Convolution)池化层(Pooling)
第六章.卷积神经网络(CNN)
6.1 卷积层(Convolution)&池化层(Pooling)
1.整体结构
以5层神经网络的实现为例:
1).基于全连接层(Affine)的网络
全连接层:相邻层的所有神经元之间都有连接
2).常见的CNN的网络
3).全连接层存在的问题
数据的形状容易被“忽视”了,比如输入的数据是图像时,图像通常是高,长,通道方向上的3维形状,但是,全连接层输入时,需要将3维数据拉平为1维数据,所以无法利用与形状相关的信息。
2.卷积层
卷积层可以保持形状不变,当输入数据是图像时,卷积层会以3维数据的形式接受输入数据,并同样以3维数据的形式输出至下一层,因此在CNN中可以正确理解图像等具有形状的数据。
1).卷积运算
-
一维数据的卷积计算
示例:填充为0,步幅为1的卷积运算
-
三维数据的卷积计算
示例:填充为0,步幅为1的卷积运算
计算方式:
通道方向有多特征图时,会按通道进行输入数据和滤波器的卷积运算,并结果相加,从而得到输出。注意:
①.在三维数据的卷积运算中,输入数据和滤波器的通道数必须设置为相同的值。(在本例中同时设置为3) -
结合方块来思考卷积计算
图像描述:
每个通道只有一个偏置,这里偏置的形状为(FN,1,1),滤波器的输出结果形状为(FN,OH,OW),这两个方块相加,要对滤波器的输出结果按通道加上相同的偏置。 -
卷积计算的批处理
注意:
①.网络间传递的是四维数据,对这N个数据进行了卷积运算,也就是说,批处理将N次的处理汇总成1次进行。
2).填充&步幅
-
填充
①.定义:
在进行卷积层处理之前,有时需要向输入数据的周围填入固定的数据(比如填充值0等),这称为填充。
②.目的:
主要是为了调整输出的大小,因为每次在进行卷积运算时都会缩小空间,那么在某个时刻输出大小就有可能变为1,导致无法在进行卷积运算,为了避免出现这种情况,就要使用填充 -
步幅
①.定义:
应用滤波器的位置间隔称为步幅。(之前的应用都是步幅为1,下面的应用步幅为2)
3).计算输出核的大小
假设输入大小为(H,W),滤波大小为(FH,FW),输出大小为(OH,OW),填充为P,步幅为S,输出大小为:
注意:
①.所设定的值必须使式(H+2P-FH)/S
和(W+2P-FW)/S
分别可以整除,当输入大小无法整除时,需要采取报错等对策。有的深度学习框架,当值无法除尽时,有时会向最接近的整数四舍五入,不进行报错而继续进行。
4).实现扩展
①.CNN处理4维数据时,卷积运算的实现看上去会很复杂,可以使用im2col(图像转化成矩阵)这个技巧,问题会变得很简单。
②.im2col函数会将输入数据展开以适合滤波器(权重)。具体来说,对于输入数据,将应用滤波器的区域(3维方块)横向展开为一列。
③.卷积运算的滤波器处理细节:使用im2col函数展开输入数据后,将卷积层的滤波器纵向展开为一列,计算两个矩阵的乘积,最后转化(reshape)为输出数据大小。
5).卷积层的实现
import numpy as np# 从图像到矩阵
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):N, C, H, W = input_data.shapeout_h = (H + 2 * pad - filter_h) // stride + 1out_w = (W + 2 * pad - filter_w) // stride + 1img = np.pad(input_data, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant')col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))for y in range(filter_h):y_max = y + stride * out_hfor x in range(filter_w):x_max = x + stride * out_wcol[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N * out_h * out_w, -1)return col# 从矩阵到图像
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):N, C, H, W = input_shapeout_h = (H + 2 * pad - filter_h) // stride + 1out_w = (W + 2 * pad - filter_w) // stride + 1col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)img = np.zeros((N, C, H + 2 * pad + stride - 1, W + 2 * pad + stride - 1))for y in range(filter_h):y_max = y + stride * out_hfor x in range(filter_w):x_max = x + stride * out_wimg[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]return img[:, :, pad:H + pad, pad:W + pad]class Convolution:def __init__(self, W, b, stride=1, pad=0):self.W = Wself.b = bself.stride = strideself.pad = pad# 中间数据(backward时使用)self.x = Noneself.col = Noneself.col_W = None# 权重和偏置参数的梯度self.dW = Noneself.db = None# 正向传播def forward(self, x):FN, C, FH, FW = self.W.shapeN, C, H, W = x.shapeout_h = int((H + 2 * self.pad - FH) / self.stride) + 1out_w = int((W + 2 * self.pad - FW) / self.stride) + 1col = im2col(x, FH, FW, self.stride, self.pad)col_W = self.W.reshape(FN, -1).Tout = np.dot(col, col_W) + self.bout = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)self.x = xself.col = colself.col_W = col_Wreturn out# 反向传播def backward(self, dout):FN, C, FH, FW = self.W.shapedout = dout.transpose(0, 2, 3, 1).reshape(-1, FN)self.db = np.sum(dout, axis=0)self.dW = np.dot(self.col.T, dout)self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)dcol = np.dot(dout, self.col_W.T)dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)return dx
3.池化层
池化是缩小高,长方向上的空间运算。
1).池化的处理方法
示例:填充为0,步幅为2的池化
-
Max池化:(本书中所说的池化层是Max池化)
方式:从目标区域中取最大值
-
Average池化:
方式:从目标区域中取均值
2).池化层的特征
-
没有要学习的参数:
池化层和卷积层不同,没有要学习的参数。池化只是从目标区域中选出最大值(或均值)。 -
通道数不发生改变:
经过池化运算,输入数据和输出数据的通道数不发生变化,计算是按通道独立进行的。
-
对微小的位置变化具有鲁棒性(健壮):
输入数据发生微小偏差时,池化仍会返回相同的结果。示例:输入数据在高方向上只偏离一个像素时:
3).池化层的实现步骤
①.展开输入数据:
②.求各行的最大值:
③.转换为合适的输出大小:
4).池化层的实现
import numpy as np# 从图像到矩阵
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):N, C, H, W = input_data.shapeout_h = (H + 2 * pad - filter_h) // stride + 1out_w = (W + 2 * pad - filter_w) // stride + 1img = np.pad(input_data, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant')col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))for y in range(filter_h):y_max = y + stride * out_hfor x in range(filter_w):x_max = x + stride * out_wcol[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N * out_h * out_w, -1)return col# 从矩阵到图像
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):N, C, H, W = input_shapeout_h = (H + 2 * pad - filter_h) // stride + 1out_w = (W + 2 * pad - filter_w) // stride + 1col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)img = np.zeros((N, C, H + 2 * pad + stride - 1, W + 2 * pad + stride - 1))for y in range(filter_h):y_max = y + stride * out_hfor x in range(filter_w):x_max = x + stride * out_wimg[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]return img[:, :, pad:H + pad, pad:W + pad]class Pooling:def __init__(self, pool_h, pool_w, stride=1, pad=0):self.pool_h = pool_hself.pool_w = pool_wself.stride = strideself.pad = padself.x = Noneself.arg_max = None# 正向传播def 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)col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)col = col.reshape(-1, self.pool_h * self.pool_w)arg_max = np.argmax(col, axis=1)out = np.max(col, axis=1)out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)self.x = xself.arg_max = arg_maxreturn out# 反向传播def backward(self, dout):dout = dout.transpose(0, 2, 3, 1)pool_size = self.pool_h * self.pool_wdmax = np.zeros((dout.size, pool_size))dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()dmax = dmax.reshape(dout.shape + (pool_size,))dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)return dx
相关文章:

第六章.卷积神经网络(CNN)—卷积层(Convolution)池化层(Pooling)
第六章.卷积神经网络(CNN) 6.1 卷积层(Convolution)&池化层(Pooling) 1.整体结构 以5层神经网络的实现为例: 1).基于全连接层(Affine)的网络 全连接层:相邻层的所有神经元之间都有连接 2).常见的CNN的网络 3).全连接层存在的问题 数据的形状容易被…...

c/c++开发,无可避免的模板编程实践(篇六)
一、泛型算法 1.1 泛型算法概述 c标准库不仅包含数据结构(容器、容器适配器等),还有很多算法。数据结构可以帮助存放特定情况下需要保存的数据,而算法则会将数据结构中存储的数据进行变换。标准库没有给容器添加大量的功能函数&am…...

【Java】Spring核心与设计思想
文章目录Spring核心与设计思想1. Spring是什么1.1 什么是容器1.2 什么是IOC1.2.1 传统程序开发1.2.2 控制反转式程序开发1.2.3 对比总结规律1.3 理解Spring IOC1.4 DI概念说明Spring核心与设计思想 1. Spring是什么 我们通常所说的Spring指的是Spring Framework(S…...

组合实现多类别分割(含实战代码)
来源:投稿 作者:AI浩 编辑:学姐 摘要 segmentation_models_pytorch是一款非常优秀的图像分割库,albumentations是一款非常优秀的图像增强库,这篇文章将这两款优秀结合起来实现多类别的图像分割算法。数据集选用CamVid…...

从红队视角看AWD攻击
AWD的权限维持 攻防兼备AWD模式是一种综合考核参赛团队攻击、防御技术能力、即时策略的比赛模式。在攻防模式中,参赛队伍分别防守同样配置的虚拟靶机,并在有限的博弈时间内,找到其他战队的薄弱环节进行攻击,同时要对自己的靶机环…...

龙腾万里,福至万家——“北京龙文化促进协会第九届龙抬头传承会”在京举办
2023年2月21日(农历2月初二)上午9:00点至下午13:00,由北京龙文化促进协会主办、传世经典(北京)文化发展有限公司承办、北京华夏龙文旅联盟协办的“北京龙文化促进协会第九届二月二龙抬头传承会”在北京市丰台区顺和国际大厦A口6层会议厅隆重召开。 传承会活动内容主…...
《软件方法》强化自测题-业务建模(4)
按照业务建模、需求、分析、设计工作流考察,答案不直接给出,可访问自测链接或扫二维码自测,做到全对才能知道答案。 知识点见《软件方法》(http://www.umlchina.com/book/softmeth.html)、 “软件需求设计方法学全程…...

Prometheus之pushgateway
Pushgateway简介 Pushgateway是Prometheus监控系统中的一个重要组件,它采用被动push的方式获取数据,由应用主动将数据推送到pushgateway,然后Prometheus再从Pushgateway抓取数据。使用Pushgateway的主要原因是: Prometheus和targ…...

3分钟带您快速了解HIL测试及其架构
什么是HIL测试硬件在环(HIL)仿真是一种用于测试导航系统的技术,其中测试前并不知道车辆轨迹。在这种情况下,车辆轨迹被实时馈送到GNSS模拟器。HIL可用于复杂实时系统的开发和测试,如卫星控制系统、军事战术导弹、飞机飞…...

华为认证含金量如何?
一本证书是否有用,还要看它是否被市场所认可。 我们说华为认证HCIP有用,很大一部分还取决于它极高的适用性和权威性。华为是国内最大的生产销售通信设备的民营通信科技公司。 自2013年起,国家对网络安全极度重视,相继把国外的网…...
刷题记录:牛客NC54586小翔和泰拉瑞亚
传送门:牛客 题目描述: 小翔爱玩泰拉瑞亚 。 一天,他碰到了一幅地图。这幅地图可以分为n列,第i列的高度为Hi,他认为这个地图不好看,决定对它进行改造。 小翔又学会了m个魔法,实施第i个魔法可以使地图的第Li列到第Ri列…...

面试个3年自动化测试,测试水平一言难尽。。。。
公司前段缺人,也面了不少测试,结果竟然没有一个合适的。 一开始瞄准的就是中级的水准,也没指望来大牛,提供的薪资在10-20k,面试的人很多,但平均水平很让人失望。 看简历很多都是3年工作经验,但…...

C++面向对象(下)
文章目录前言1.再谈构造函数1.初始化列表2.explicit关键字2. static成员1.概念3.友元1.概念2.友元函数3.友元类4. 内部类5.匿名对象6.编译器优化7.总结前言 本文是主要是将之前关于C面向对象中的一些没有归纳到的零星知识点进行补充,同时对C中的面向对象简单收个尾…...

面试一位软件测试6年工作者:一年经验掰成六年来用....
在众多面试中,对于那个工作了6年的面试者,我印象很深刻,因为最开始拿到简历的时候,我一摸:"这简历,好厚啊!"再一看,工作6年。 于是我去找了我的领导,我说:“这人我应该没…...
Java8 新特性--Optional
Optional是什么 java.util.Optional Jdk8提供Optional,一个可以包含null值的容器对象,可以用来代替xx ! null的判断。 Optional常用方法 of public static <T> Optional<T> of(T value) {return new Optional<>(value); }为value…...

Pytorch GPU版本简明下载安装教程
1.根据自己的显卡型号下载显卡驱动并安装。这一步会更新你的显卡驱动,也可忽略第1步,如果第2步出现问题,返回执行第1步。 点击这里下载英伟达显卡驱动 2.安装完成后,wincmd打开命令行,输入nvidia-smi,查看…...

【C++】map和set的封装
文章目录一、前情回顾二、简化源码三、仿函数四、迭代器五、set的实现六、map的实现七、红黑树代码一、前情回顾 set 参数只有 key,但是map除了key还有value。我们还是需要KV模型的红黑树的: #pragma once #include <iostream> #include <ass…...
互融云金融控股集团管理平台系统搭建
金融控股公司是指对两个或两个以上不同类型金融机构拥有实质控制权,自身仅开展股权投资管理、不直接从事商业性经营活动的有限责任公司或者股份有限公司。 金融控股公司是金融业实现综合经营的一种组织形式,也是一种追求资本投资最优化、资本利润最大化…...

Git复习
1. 引言 现在要用到Git,复习一下关于Git的指令,知识摘自《Pro Git》 2. 起步 git和其他版本控制软件最大的差别在于git是直接记录某个版本的快照,而不是逐渐地比较差异。 安装: sudo apt install git-all设置用户信息: git c…...
WebGPU学习(2)---使用VertexBuffer(顶点缓冲区)
在本文中,我们使用 VertexBuffer 绘制一个矩形。示例地址 1.准备顶点数据 首先,我们准备好顶点数据。定义顶点数据有多种方法,这次我们将在 TypeScript 代码中将其定义为 Float32Array 类型的数据。 const quadVertexSize 4 * 8; // 一个顶…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
P10909 [蓝桥杯 2024 国 B] 立定跳远
# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上,小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时࿰…...