当前位置: 首页 > news >正文

深度学习------------池化层

目录

  • 池化层
    • 二维最大池化
    • 填充、步幅和多个通道
    • 平均池化层
  • 总结
  • 池化层的代码部分
    • 实现池化层的正向传播
    • 验证二维最大池化层的输出
      • 该部分总代码
    • 验证平均池化层
      • 该部分总代码
    • 填充和步幅
    • 深度学习框架中的步幅与池化窗口的大小相同
      • 该部分总代码
    • 填充和步幅可以手动设定
      • 该部分总代码
    • 自定义池化窗口、填充、步幅
      • 该部分总代码
    • 多个通道
      • 该部分总代码
    • 池化后输出通道数量不变(输入=输出)
      • 该部分总代码
  • 小结

池化层

    ①二维卷积层可以帮助我们检测图像物体边缘

    ②无论是原始图片,还是经过卷积核处理的中间特征,都是基于像素的基础进行的数学运算。

    ③实际图像里,我们感兴趣的物体不会总出现在固定像素位置:即使我们用三脚架固定相机去连续拍摄同一个物体也极有可能出现像素位置上的偏移。

    ④绝大多数计算机视觉任务对图像处理终极目标识别图片内的物体,所以不需要细致到对每个像素进行检测,只需要找到图片中物体的大概轮廓就好了。

    ⑤池化层可以缓解卷积层对位置的过度敏感性



如下所示,例如1X2的卷积核[1,-1],会使得下图中Y输出的第二列为1,其他为0,如果像素偏移,会导致边缘检测的1在其他位置输出,所以说卷积对像素的位置是非常敏感的。

这里本质上讲的是池化层对于像素偏移的容忍性。

在这里插入图片描述




二维最大池化

2×2的池化窗口

在这里插入图片描述
跟卷积一样,用滑动窗口来计算输出,但没有进行求和而是其中的最大值
在这里插入图片描述

在这里插入图片描述


返回滑动窗口的最大值

输入:进行边缘检测
在这里插入图片描述
卷积输出

在这里插入图片描述
2×2最大池化(可容1像素移位)
在这里插入图片描述




填充、步幅和多个通道

    ①池化层与卷积层类似,都具有填充和步幅。(填充上下左右都是1)
    ②没有可学习的参数。
    ③在每个输入通道应用池化层以获得相应的输出通道(不像卷积一样可以融合多个通道)
    ④输出通道数=输入通道数




平均池化层

最大池化层:每个窗口中最强的模式信号。

平均池化层:将最大池化层中的“最大”操作替换“平均

在这里插入图片描述




总结

    ①池化层返回窗口中最大或平均值

    ②缓解卷积层对位置的敏感性

    ③同样有窗口大小、填充和步幅作为超参数




池化层的代码部分

实现池化层的正向传播

import torch
from torch import nn
from d2l import torch as d2l
# X:输入的特征图,pool_size:池化窗口的大小,以及mode(池化模式,默认为'max'
def pool2d(X, pool_size, mode='max'):# 池化窗口的高度和宽度p_h, p_w = pool_size# 根据输入特征图X的形状和池化窗口的大小计算得出Y的形状Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))# 遍历输出特征图Y的每一个位置(i, j)for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode == 'max':# 判断池化模式是否为'max'。如果是,就在输入特征图X上对应的池化窗口内执行最大池化操作,并将最大值赋值给Y[i, j]Y[i, j] = X[i: i + p_h, j: j + p_w].max()elif mode == 'avg':# 判断池化模式是否为'avg'。如果是,就在输入特征图X上对应的池化窗口内执行平均池化操作,并将平均值赋值给Y[i, j]。Y[i, j] = X[i: i + p_h, j: j + p_w].mean()return Y

解释一下:(X.shape[0] - p_h + 1, X.shape[1] - p_w + 1)
这是一个输入特征图,即X,它是4×5的形状
在这里插入图片描述
这里
    X.shape[0]=4
    X.shape[1]=5
    p_h=p_w=2

∴这里的Y的形状是3×4的形状,(然后代码中是对Y进行一个全零的初始化。)
在这里插入图片描述


验证二维最大池化层的输出

X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool2d(X, (2, 2))

输出:
在这里插入图片描述


该部分总代码

import torch# X:输入的特征图,pool_size:池化窗口的大小,以及mode(池化模式,默认为'max'
def pool2d(X, pool_size, mode='max'):# 池化窗口的高度和宽度p_h, p_w = pool_size# 根据输入特征图X的形状和池化窗口的大小计算得出Y的形状Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))# 遍历输出特征图Y的每一个位置(i, j)for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode == 'max':# 判断池化模式是否为'max'。如果是,就在输入特征图X上对应的池化窗口内执行最大池化操作,并将最大值赋值给Y[i, j]Y[i, j] = X[i: i + p_h, j: j + p_w].max()elif mode == 'avg':# 判断池化模式是否为'avg'。如果是,就在输入特征图X上对应的池化窗口内执行平均池化操作,并将平均值赋值给Y[i, j]。Y[i, j] = X[i: i + p_h, j: j + p_w].mean()return YX = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
print(pool2d(X, (2, 2)))



验证平均池化层

pool2d(X, (2, 2), 'avg')

输出:

在这里插入图片描述

该部分总代码

import torch# X:输入的特征图,pool_size:池化窗口的大小,以及mode(池化模式,默认为'max'
def pool2d(X, pool_size, mode='max'):# 池化窗口的高度和宽度p_h, p_w = pool_size# 根据输入特征图X的形状和池化窗口的大小计算得出Y的形状Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))# 遍历输出特征图Y的每一个位置(i, j)for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode == 'max':# 判断池化模式是否为'max'。如果是,就在输入特征图X上对应的池化窗口内执行最大池化操作,并将最大值赋值给Y[i, j]Y[i, j] = X[i: i + p_h, j: j + p_w].max()elif mode == 'avg':# 判断池化模式是否为'avg'。如果是,就在输入特征图X上对应的池化窗口内执行平均池化操作,并将平均值赋值给Y[i, j]。Y[i, j] = X[i: i + p_h, j: j + p_w].mean()return YX = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
print(pool2d(X, (2, 2), 'avg'))



填充和步幅

与卷积层一样,池化层也可以改变输出形状。和以前一样,我们可以通过填充步幅以获得所需的输出形状。 下面,我们用深度学习框架中内置的二维最大汇聚层,来演示汇聚层中填充和步幅的使用。 我们首先构造了一个输入张量X,它有四个维度,其中样本数通道数都是1

# 样本数和通道数都是1,高度和宽度都是4
X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
print(X)

输出:
在这里插入图片描述




深度学习框架中的步幅与池化窗口的大小相同

默认情况下,深度学习框架中的步幅与池化窗口的大小相同。 因此,如果我们使用形状为(3, 3)的池化窗口,那么默认情况下,我们得到的步幅形状为(3, 3)

pool2d = nn.MaxPool2d(3)
pool2d(X)

结果:

在这里插入图片描述

在这里插入图片描述

该部分总代码

import torch
from torch import nnX = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
pool2d = nn.MaxPool2d(3)
print(pool2d(X))



填充和步幅可以手动设定

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

结果:
在这里插入图片描述

该部分总代码

import torch
from torch import nnX = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
pool2d = nn.MaxPool2d(3, padding=1, stride=2)
print(pool2d(X))



自定义池化窗口、填充、步幅

设定一个任意大小的矩形池化窗口,并分别设定填充步幅的高度和宽度

# 池化窗口的大小,高度为2,宽度为3
pool2d = nn.MaxPool2d((2, 3), padding=(1, 1), stride=(2, 3))
print(pool2d(X))

结果:
在这里插入图片描述

该部分总代码

import torch
from torch import nnX = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
# 池化窗口的大小,高度为2,宽度为3
pool2d = nn.MaxPool2d((2, 3), padding=(1, 1), stride=(2, 3))
print(pool2d(X))



多个通道

    在处理多通道输入数据时,池化层在每个输入通道上单独运算而不是像卷积层一样在通道上对输入进行汇总。 这意味着池化层的输出通道数输入通道数相同。下面,我们将在通道维度上连结张量X和X + 1,以构建具有2个通道的输入。

# 创建了一个与 X 形状相同的新张量X+1,将 X 和 X + 1 这两个张量沿着它们的第二个维度(索引为1的维度,记住索引是从0开始的)拼接起来。形成一个新的张量。
X = torch.cat((X, X + 1), 1)
print(X)

结果:
在这里插入图片描述

假设 X 是一个形状为 (N, C, H, W) 的四维张量
    N 是批量大小(batch size)
    C 是通道数(channel)
    H 是高度(height)
    W 是宽度(width)
执行 torch.cat((X, X + 1), 1) 后,结果张量的形状将是 (N, 2*C, H, W)。这是因为在第二个维度(即通道维度)上,我们将 X 和 X + 1 拼接了起来,所以通道数从 C 变成了 2×C。

stack是增加维度(即:stack是升维拼接)
cat是在当前维度上连接(cat是等维拼接)

该部分总代码

import torchX = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X = torch.cat((X, X + 1), 1)
print(X)



池化后输出通道数量不变(输入=输出)

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

结果:
在这里插入图片描述

该部分总代码

import torch
from torch import nnX = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X = torch.cat((X, X + 1), 1)
pool2d = nn.MaxPool2d(3, padding=1, stride=2)
print(pool2d(X))



小结

    ①对于给定输入元素,最大池化层会输出该窗口内的最大值,平均池化层会输出该窗口内的平均值。
    ②池化层的主要优点之一是减轻卷积层对位置的过度敏感。
    ③我们可以指定池化层的填充和步幅。
    ④使用最大池化层以及大于1的步幅,可减少空间维度(如高度和宽度)。
    ⑤池化层的输出通道数与输入通道数相同。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • vue3 ts vite开发bug记录(类型转换)
  • 如何获取能直接在浏览器打开的播放地址?
  • C语言 --- 枚举、位运算
  • 电机学习-基础知识
  • AR技术:汽车行业创新发展的新动力
  • Grafana 可视化监控和告警
  • 28. 找出字符串中第一个匹配项的下标【 力扣(LeetCode) 】
  • 【知识点介绍】时钟置换算法(CLOCK算法)
  • 【python学习】深入解析 `jq` 库:JSON 处理的利器
  • 数据库(一):MySQL概述
  • Spring Boot + Vue 跨域配置(CORS)问题解决历程
  • 构建智能生态,视频监控/安防监控EasyCVR视频汇聚流媒体技术在智能分析领域的应用
  • 《TOGAF®标准第10版》:企业架构新时代的必备指南与实践蓝图
  • JS【详解】 延迟加载
  • 阿里云服务器 ECS部署jenkins
  • ECMAScript6(0):ES6简明参考手册
  • gops —— Go 程序诊断分析工具
  • JS+CSS实现数字滚动
  • Magento 1.x 中文订单打印乱码
  • MySQL数据库运维之数据恢复
  • NSTimer学习笔记
  • Python利用正则抓取网页内容保存到本地
  • web标准化(下)
  • 创建一个Struts2项目maven 方式
  • 缓存与缓冲
  • ------- 计算机网络基础
  • 前端代码风格自动化系列(二)之Commitlint
  • 我是如何设计 Upload 上传组件的
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • scrapy中间件源码分析及常用中间件大全
  • 湖北分布式智能数据采集方法有哪些?
  • 积累各种好的链接
  • 交换综合实验一
  • # centos7下FFmpeg环境部署记录
  • #{} 和 ${}区别
  • #DBA杂记1
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (0)Nginx 功能特性
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (pycharm)安装python库函数Matplotlib步骤
  • (pytorch进阶之路)扩散概率模型
  • (纯JS)图片裁剪
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot教学评价 毕业设计 641310
  • (四)模仿学习-完成后台管理页面查询
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)项目管理杂谈-我所期望的新人
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net FrameWork简介,数组,枚举
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net MySql
  • .NET 药厂业务系统 CPU爆高分析