CNN | 05池化层

2024-03-07 17:58
文章标签 05 cnn 池化层

本文主要是介绍CNN | 05池化层,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5 池化层

5.1 常用池化方法

池化 pooling,又称为下采样,downstream sampling or sub-sampling。

池化方法分为两种,一种是最大值池化 Max Pooling,一种是平均值池化 Mean/Average Pooling。如图17-32所示。

图17-32 池化

  • 最大值池化,是取当前池化视野中所有元素的最大值,输出到下一层特征图中。
  • 平均值池化,是取当前池化视野中所有元素的平均值,输出到下一层特征图中。

其目的是:

  • 扩大视野:就如同先从近处看一张图片,然后离远一些再看同一张图片,有些细节就会被忽略
  • 降维:在保留图片局部特征的前提下,使得图片更小,更易于计算
  • 平移不变性,轻微扰动不会影响输出:比如上图中最大值池化的4,即使向右偏一个像素,其输出值仍为4
  • 维持同尺寸图片,便于后端处理:假设输入的图片不是一样大小的,就需要用池化来转换成同尺寸图片

一般我们都使用最大值池化。

5.2 池化的其它方式

在上面的例子中,我们使用了size=2x2,stride=2的模式,这是常用的模式,即步长与池化尺寸相同。

我们很少使用步长值与池化尺寸不同的配置,所以只是提一下,如图17-33。

图17-33 步长为1的池化

上图是stride=1, size=2x2的情况,可以看到,右侧的结果中,有一大堆的3和4,基本分不开了,所以其池化效果并不好。

假设输入图片的形状是 W 1 × H 1 × D 1 W_1 \times H_1 \times D_1 W1×H1×D1,其中W是图片宽度,H是图片高度,D是图片深度(多个图层),F是池化的视野(正方形),S是池化的步长,则输出图片的形状是:

$$
\begin{aligned}
W_2 &= (W_1 - F)/S + 1 \
H_2 &= (H_1 - F)/S + 1 \
D_2 &= D_1
\end{aligned}

$$

池化层不会改变图片的深度,即D值前后相同。

5.3 池化层的训练

我们假设图17-34中, [ [ 1 , 2 ] , [ 3 , 4 ] ] [[1,2],[3,4]] [[1,2],[3,4]]是上一层网络回传的残差,那么:

  • 对于最大值池化,残差值会回传到当初最大值的位置上,而其它三个位置的残差都是0。
  • 对于平均值池化,残差值会平均到原始的4个位置上。

图17-34 平均池化与最大池化

图17-35 池化层反向传播的示例

Max Pooling

严格的数学推导过程以图17-35为例进行。

正向公式:

w = m a x ( a , b , e , f ) w = max(a,b,e,f) w=max(a,b,e,f)

反向公式(假设Input Layer中的最大值是b):

∂ w ∂ a = 0 , ∂ w ∂ b = 1 {\partial w \over \partial a} = 0, \quad {\partial w \over \partial b} = 1 aw=0,bw=1

∂ w ∂ e = 0 , ∂ w ∂ f = 0 {\partial w \over \partial e} = 0, \quad {\partial w \over \partial f} = 0 ew=0,fw=0

因为a,e,f对w都没有贡献,所以偏导数为0,只有b有贡献,偏导数为1。

δ a = ∂ J ∂ a = ∂ J ∂ w ∂ w ∂ a = 0 \delta_a = {\partial J \over \partial a} = {\partial J \over \partial w} {\partial w \over \partial a} = 0 δa=aJ=wJaw=0

δ b = ∂ J ∂ b = ∂ J ∂ w ∂ w ∂ b = δ w ⋅ 1 = δ w \delta_b = {\partial J \over \partial b} = {\partial J \over \partial w} {\partial w \over \partial b} = \delta_w \cdot 1 = \delta_w δb=bJ=wJbw=δw1=δw

δ e = ∂ J ∂ e = ∂ J ∂ w ∂ w ∂ e = 0 \delta_e = {\partial J \over \partial e} = {\partial J \over \partial w} {\partial w \over \partial e} = 0 δe=eJ=wJew=0

δ f = ∂ J ∂ f = ∂ J ∂ w ∂ w ∂ f = 0 \delta_f = {\partial J \over \partial f} = {\partial J \over \partial w} {\partial w \over \partial f} = 0 δf=fJ=wJfw=0

Mean Pooling

正向公式:

w = 1 4 ( a + b + e + f ) w = \frac{1}{4}(a+b+e+f) w=41(a+b+e+f)

反向公式(假设Layer-1中的最大值是b):

∂ w ∂ a = 1 4 , ∂ w ∂ b = 1 4 {\partial w \over \partial a} = \frac{1}{4}, \quad {\partial w \over \partial b} = \frac{1}{4} aw=41,bw=41

∂ w ∂ e = 1 4 , ∂ w ∂ f = 1 4 {\partial w \over \partial e} = \frac{1}{4}, \quad {\partial w \over \partial f} = \frac{1}{4} ew=41,fw=41

因为a,b,e,f对w都有贡献,所以偏导数都为1:

δ a = ∂ J ∂ a = ∂ J ∂ w ∂ w ∂ a = 1 4 δ w \delta_a = {\partial J \over \partial a} = {\partial J \over \partial w} {\partial w \over \partial a} = \frac{1}{4}\delta_w δa=aJ=wJaw=41δw

δ b = ∂ J ∂ b = ∂ J ∂ w ∂ w ∂ b = 1 4 δ w \delta_b = {\partial J \over \partial b} = {\partial J \over \partial w} {\partial w \over \partial b} = \frac{1}{4}\delta_w δb=bJ=wJbw=41δw

δ e = ∂ J ∂ e = ∂ J ∂ w ∂ w ∂ e = 1 4 δ w \delta_e = {\partial J \over \partial e} = {\partial J \over \partial w} {\partial w \over \partial e} = \frac{1}{4}\delta_w δe=eJ=wJew=41δw

δ f = ∂ J ∂ f = ∂ J ∂ w ∂ w ∂ f = 1 4 δ w \delta_f = {\partial J \over \partial f} = {\partial J \over \partial w} {\partial w \over \partial f} = \frac{1}{4}\delta_w δf=fJ=wJfw=41δw

无论是max pooling还是mean pooling,都没有要学习的参数,所以,在卷积网络的训练中,池化层需要做的只是把误差项向后传递,不需要计算任何梯度。

5.4 实现方法1

按照标准公式来实现池化的正向和反向代码。

class PoolingLayer(CLayer):def forward_numba(self, x, train=True):......def backward_numba(self, delta_in, layer_idx):......

有了前面的经验,这次我们直接把前向和反向函数用numba方式来实现,并在前面加上@nb.jit修饰符:

@nb.jit(nopython=True)
def jit_maxpool_forward(...):...return z@nb.jit(nopython=True)
def jit_maxpool_backward(...):...return delta_out

5.5 实现方法2

池化也有类似与卷积优化的方法来计算,在图17-36中,我们假设大写字母为池子中的最大元素,并且用max_pool方式。

图17-36 池化层的img2col实现

原始数据先做img2col变换,然后做一次np.max(axis=1)的max计算,会大大增加速度,然后把结果reshape成正确的矩阵即可。做一次大矩阵的max计算,比做4次小矩阵计算要快很多。

class PoolingLayer(CLayer):def forward_img2col(self, x, train=True):......def backward_col2img(self, delta_in, layer_idx):......

5.6 性能测试

下面我们要比较一下以上两种实现方式的性能,来最终决定使用哪一种。

对同样的一批64个样本,分别用两种方法做5000次的前向和反向计算,得到的结果:

Elapsed of numba: 17.537396907806396
Elapsed of img2col: 22.51519775390625
forward: True
backward: True

numba方法用了17秒,img2col方法用了22秒。并且两种方法的返回矩阵值是一样的,说明代码实现正确。

代码位置

ch17, Level5

这篇关于CNN | 05池化层的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/784346

相关文章

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

深度学习实战:如何利用CNN实现人脸识别考勤系统

1. 何为CNN及其在人脸识别中的应用 卷积神经网络(CNN)是深度学习中的核心技术之一,擅长处理图像数据。CNN通过卷积层提取图像的局部特征,在人脸识别领域尤其适用。CNN的多个层次可以逐步提取面部的特征,最终实现精确的身份识别。对于考勤系统而言,CNN可以自动从摄像头捕捉的视频流中检测并识别出员工的面部。 我们在该项目中采用了 RetinaFace 模型,它基于CNN的结构实现高效、精准的

C++入门(05-2)从命令行执行C++编译器_GCC

文章目录 GCC编译器1. 下载MinGW-w64,安装(不推荐)2. 使用MSYS2安装MinGW-w64(推荐)2.1 安装MSYS22.2 初始化和更新2.3 安装MinGW-w64编译器2.3 在MSYS2 Shell中导航到代码目录2.4 使用 g++ 编译2.5 运行可执行文件 GCC编译器 GCC(GNU Compiler Collection)是一个开源编译器集

如何将卷积神经网络(CNN)应用于医学图像分析:从分类到分割和检测的实用指南

引言 在现代医疗领域,医学图像已经成为疾病诊断和治疗规划的重要工具。医学图像的类型繁多,包括但不限于X射线、CT(计算机断层扫描)、MRI(磁共振成像)和超声图像。这些图像提供了对身体内部结构的详细视图,有助于医生在进行准确诊断和制定个性化治疗方案时获取关键的信息。 1. 医学图像分析的挑战 医学图像分析面临诸多挑战,其中包括: 图像数据的复杂性:医学图像通常具有高维度和复杂的结构

C++入门(05)从命令行执行C++编译器_MSVC

文章目录 1.C++ 编译器2. 常用 C++ 编译器MSVC(Microsoft Visual C++)GCC(GNU Compiler Collection)Clang 3. MSVC 编译器3.1 开发者命令提示符3.2 编译 C++ 代码 1.C++ 编译器 将C++源代码(扩展名为 .cpp )转换成计算机可以运行的可执行程序 编译器会检查代码的语法和语义,生成相应

龙芯+FreeRTOS+LVGL实战笔记(新)——05部署主按钮

本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了改进和优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前往本人在B站的视频合集(图2所示)观看所有演示视频,合集首个视频链接为: 借助RT-Thread和LVGL

【SpringMVC学习05】SpringMVC中的异常处理器

SpringMVC在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。 异常处理思路 我们知道,系统中异常包括两类:预期异常和运行时异常(RuntimeException),前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。系统的dao、service、controller出现异常都通过throws E

学习硬件测试05:NTC(ADC)+正弦波(DAC)+DMA(ADC+DAC)(P73、P76、P78)

文章以下内容全部为硬件相关知识,鲜有软件知识,并且记的是自己需要的部分,大家可能看不明白。 一、NTC(ADC) 1.1实验现象 本实验用 NTC 采集温度,数码管实时显示温度数据(整数),左下角 USB 小串口每隔 1S 打印温度信息。 1.2硬件电路 NTC 电阻是一个模拟温度传感器,随着温度的升高,电阻值逐渐减小。电路简单介绍如下: 电源滤波电容在 25℃ 室温下 NTC 电

CNN-LSTM模型中应用贝叶斯推断进行时间序列预测

这篇论文的标题是《在混合CNN-LSTM模型中应用贝叶斯推断进行时间序列预测》,作者是Thi-Lich Nghiem, Viet-Duc Le, Thi-Lan Le, Pierre Maréchal, Daniel Delahaye, Andrija Vidosavljevic。论文发表在2022年10月于越南富国岛举行的国际多媒体分析与模式识别会议(MAPR)上。 摘要部分提到,卷积

python+selenium2学习笔记unittest-05测试用例实例

看一下非常简单的目录结构 test_baidu from selenium import webdriverimport unittestimport timeclass MyTest(unittest.TestCase):def setUp(self):self.driver = webdriver.Firefox()self.driver.maximize_window()self