(pytorch-深度学习系列)CNN中的池化层-学习笔记
CNN中的池化层
首先,池化(pooling)层的提出是为了缓解卷积层对位置的过度敏感性。
什么意思?
比如在图像边缘检测问题中,实际图像里,我们的目标物体不会总出现在固定位置,即使我们连续拍摄同一个物体也极有可能出现像素位置上的偏移。这会导致同一个边缘对应的输出可能出现在卷积输出的边缘的不同位置,从而对模式识别造成影响。
与卷积层类似,池化层每次也是对输入数据的一个固定窗口内的元素计算输出
但是池化层不同于卷积层,它不考虑输入与核的互相关性,池化层直接计算池化窗口内数据的最大值或平均值,这分别对应与最大池化与平均池化。
对于二维最大池化,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
[012345678]∗[2∗2最大池化层]=[4578]\begin{bmatrix} 0&1&2 \\ 3&4&5 \\ 6&7&8 \end{bmatrix} * \begin{bmatrix} 2*2 \\ 最大池化层 \end{bmatrix} = \begin{bmatrix} 4&5 \\ 7&8 \end{bmatrix} ⎣⎡036147258⎦⎤∗[2∗2最大池化层]=[4758]
由:
max(0,1,3,4)=4,max(1,2,4,5)=5,max(3,4,6,7)=7,max(4,5,7,8)=8.\max(0,1,3,4)=4,\\ \max(1,2,4,5)=5,\\ \max(3,4,6,7)=7,\\ \max(4,5,7,8)=8. max(0,1,3,4)=4,max(1,2,4,5)=5,max(3,4,6,7)=7,max(4,5,7,8)=8.
·
构造一个实现最大池化和平均池化的层:
import torch
from torch import nndef pool2d(X, pool_size, mode='max'):X = X.float()p_h, p_w = pool_sizeY = torch.zeros(X.shape[0] - p_h + 1, X.shape[1] - p_w + 1)for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode == 'max':Y[i, j] = X[i: i + p_h, j: j + p_w].max()elif mode == 'avg':Y[i, j] = X[i: i + p_h, j: j + p_w].mean() return Y
对于物体边缘检测的例子:
检测图像中物体的边缘,即找到像素变化的位置。首先我们构造一张6×86×8的图像(即高和宽分别为6像素和8像素的图像)。它中间4列为黑(0),其余为白(1)。
X = torch.ones(6, 8)
X[:, 2:6] = 0
X
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.]])
然后我们构造一个高和宽分别为1和2的卷积核K。当它与输入做互相关运算时,如果横向相邻元素相同,输出为0;否则输出为非0。
K = torch.tensor([[1, -1]])
下面将输入X和我们设计的卷积核K做互相关运算。可以看出,我们将从白到黑的边缘和从黑到白的边缘分别检测成了1和-1。其余部分的输出全是0。
def corr2d(X, K): h, w = K.shapeY = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i: i + h, j: j + w] * K).sum()return Y
Y = corr2d(X, K)
print(Y)
tensor([[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.]])
现在我们将卷积层的输出作为2×2平均池化层的输入。设该卷积层输入是X、池化层输出为Y。
无论是X[i, j]和X[i, j+1]值不同,还是X[i, j+1]和X[i, j+2]不同,池化层输出均有Y[i, j]不等于0。也就是说,使用2×2平均池化层时,只要卷积层识别的模式在高和宽上移动不超过一个元素,我们依然可以将它检测出来。
池化层的填充和步幅:
同卷积层一样,池化层也可以在输入的高和宽两侧的填充并调整窗口的移动步幅来改变输出形状。
先构造一个形状为(1, 1, 4, 4)的输入数据,前两个维度分别是批量和通道。
X = torch.arange(16, dtype=torch.float).view((1, 1, 4, 4))
print(X)
tensor([[[[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[12., 13., 14., 15.]]]])
默认情况下,MaxPool2d实例里步幅和池化窗口形状相同。下面使用形状为(3, 3)的池化窗口,默认获得形状为(3, 3)的步幅。
pool2d = nn.MaxPool2d(3)
pool2d(X)
输出为:
[0123456789101112131415]∗[3∗3最大池化层]=[10]\begin{bmatrix} 0&1&2&3 \\ 4&5&6&7 \\ 8&9&10&11 \\ 12&13&14&15 \end{bmatrix} * \begin{bmatrix} 3*3 \\ 最大池化层 \end{bmatrix} = \begin{bmatrix} 10 \end{bmatrix} ⎣⎢⎢⎡0481215913261014371115⎦⎥⎥⎤∗[3∗3最大池化层]=[10]
至于输出为什么是[10],根据之前的blog中讲过的卷积层的输入输出公式:
output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−3+0×2+3)/3⌋×⌊(4−3+0×2+3)/3⌋=1×1output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-3+0\times2+3)/3\rfloor \times \lfloor(4-3+0\times2+3)/3\rfloor = 1 \times 1 output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−3+0×2+3)/3⌋×⌊(4−3+0×2+3)/3⌋=1×1
得出输出维度为(1*1)
如果手动指定步幅和填充:
pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)
output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−3+1×2+2)/2⌋×⌊(4−3+1×2+2)/2⌋=2×2output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-3+1\times2+2)/2\rfloor \times \lfloor(4-3+1\times2+2)/2\rfloor = 2 \times 2 output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−3+1×2+2)/2⌋×⌊(4−3+1×2+2)/2⌋=2×2
tensor([[[[ 5., 7.],[13., 15.]]]])
指定非正矩形的窗口:
pool2d = nn.MaxPool2d((2, 4), padding=(1, 2), stride=(2, 3))
pool2d(X)
output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−2+1×2+2)/2⌋×⌊(4−4+2×2+3)/3⌋=3×2output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-2+1\times2+2)/2\rfloor \times \lfloor(4-4+2\times2+3)/3\rfloor = 3 \times 2 output=⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(4−2+1×2+2)/2⌋×⌊(4−4+2×2+3)/3⌋=3×2
输出为:
[000000000001230000456700008910110000121314150000000000]∗[2∗4最大池化层]=[139111315]\begin{bmatrix} 0&0&0&0&0&0&0&0\\ 0&0&0&1&2&3&0&0 \\ 0&0&4&5&6&7&0&0 \\ 0&0&8&9&10&11&0&0 \\ 0&0&12&13&14&15&0&0\\ 0&0&0&0&0&0&0&0 \end{bmatrix} * \begin{bmatrix} 2*4 \\ 最大池化层 \end{bmatrix} = \begin{bmatrix} 1&3\\ 9&11\\ 13&15\\ \end{bmatrix} ⎣⎢⎢⎢⎢⎢⎢⎡000000000000004812001591300261014003711150000000000000⎦⎥⎥⎥⎥⎥⎥⎤∗[2∗4最大池化层]=⎣⎡191331115⎦⎤
池化层中的多通道
在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各通道的输入按通道相加。这意味着池化层的输出通道数与输入通道数相等。
例如:
X = torch.cat((X, X + 1), dim=1)
print(X)
输出:
tensor([[[[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[12., 13., 14., 15.]],[[ 1., 2., 3., 4.],[ 5., 6., 7., 8.],[ 9., 10., 11., 12.],[13., 14., 15., 16.]]]])
pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)
输出通道数仍然是2
tensor([[[[ 5., 7.],[13., 15.]],[[ 6., 8.],[14., 16.]]]])
(pytorch-深度学习系列)CNN中的池化层-学习笔记相关推荐
- cnn池化层输入通道数_(pytorch-深度学习系列)CNN中的池化层-学习笔记
CNN中的池化层 首先,池化(pooling)层的提出是为了缓解卷积层对位置的过度敏感性. 什么意思? 比如在图像边缘检测问题中,实际图像里,我们的目标物体不会总出现在固定位置,即使我们连续拍摄同一个 ...
- 转:卷积神经网络_(1)卷积层和池化层学习
博主总结的很好,学习中.转载:http://www.cnblogs.com/zf-blog/p/6075286.htm 卷积神经网络_(1)卷积层和池化层学习 卷积神经网络(CNN)由输入层.卷积层. ...
- 【TensorFlow】TensorFlow从浅入深系列之十二 -- 教你深入理解卷积神经网络中的池化层
本文是<TensorFlow从浅入深>系列之第12篇 TensorFlow从浅入深系列之一 -- 教你如何设置学习率(指数衰减法) TensorFlow从浅入深系列之二 -- 教你通过思维 ...
- 卷积神经网络——池化层学习——最大池化
池化层(Pooling layers) 除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性,我们来看一下. 先举一个池化层的例子,然后我们再讨论池化层的必要 ...
- 卷积神经网络(CNN)之池化层的实现
池化层的实现和卷积层的实现差不多,都是使用im2col来展开输入数据,只不过在池化的应用区域是按照通道单独展开.看图更直观. 图中我们可以看出,对输入数据进行展开之后,再对展开的矩阵求各行的最大值,这 ...
- 机器学习入门(18)— 卷积网络中的池化层实现
1. 池化层实现 池化层的实现和卷积层相同,都使用 im2col 展开输入数据.不过,池化的情况下,在通道方向上是独立的,这一点和卷积层不同.具体地讲,如图 7-21 所示,池化的应用区域按通道单独展 ...
- Keras卷积+池化层学习
转自:https://keras-cn.readthedocs.io/en/latest/layers/convolutional_layer/ https://keras-cn.readthedoc ...
- 【综述】盘点卷积神经网络中的池化操作
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 池化操作(Pooling)是CNN中非常常见的一种操作,池化操作通 ...
- torch.nn模块之池化层详解
torch中的池化层 1. torch.nn模块中的池化层简介 2. 池化的调用方式 3. 图像池化演示 3.1 最大值池化 3.2 平均值池化 3.3 自适应平均值池化 参考资料 1. torch. ...
最新文章
- centos7 解决chrome提示您的连接不是私密连接的方法
- 详解pytorch中的常见的Tensor数据类型以及类型转换
- 梯度下降(BGD)、随机梯度下降(SGD)、Mini-batch Gradient Descent、带Mini-batch的SGD
- dispatch事件分发
- 医学计算机教学计划,医学院教学计划
- 【Python】30天进阶Python!这个Github项目你值得拥有!
- .NET 云原生架构师训练营(系统架构)--学习笔记
- 三面美团Java岗,尚学堂java马士兵全套
- 设置dns_网络速度缓慢怎么办?轻松一键修改DNS设置让网速提升五倍
- python批处理将图片进行放大实例代码
- seo模拟点击软件_百度快排软件原理分析
- 利用函数指针实现累加
- 复制百度文库文字最简单的方法
- PCIe总线协议概述
- 水下通信方式以及WSN(无线传感器网络
- Linux下oracle数据库备份导出
- 计算机按电源键无法反应,电脑无法开机怎么办 按电脑开机键也没反应的原因及处理解决办法...
- 更好的Google Glass:棱镜变长、Intel Atom处理器和外置电池组
- Orthogonal greedy algorithm降维
- 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试...
热门文章
- 现代软件工程讲义 8 稳定阶段 (测试的计划和执行)
- mysql 快速导出_mysql 快速导入导出
- 初学者怎么自学python编程_怎样自学python编程?从零开始学习python,400集免费教程!...
- Linux下安装VIM编辑器,以及简单的VIM指令操作
- php中arraymultisort,php 数组函数array_multisort()用法
- linux fg 命令,Linux fg 命令 command not found fg 命令详解 fg 命令未找到 fg 命令安装 - CommandNotFound ⚡️ 坑否...
- go语言io reader_Go语言中的io.Reader和io.Writer以及它们的实现
- 我的世界linux开服权限不足,我的世界路由器开服怎么获得超级管理员权限
- 2015计算机二级公共基础知识,2015年计算机二级公共基础知识考点测试题(8)
- 【LeetCode笔记】104. 二叉树的最大深度(Java、DFS、二叉树)