【深度学习】6-3 卷积神经网络 - 卷积层和池化层的实现

news2024/11/15 13:28:51

卷积层和池化层的实现
如前所述,CNN 中各层间传递的数据是 4 维数据。所谓 4 维数据,比如数据的形状是 (10, 1, 28, 28),则它对应 10 个高为 28、长为 28、通道为 1 的数据。用 Python 来实现的话,如下所示

>>> x = np.random.rand(10, 1, 28, 28) # 随机生成数据
>>> x.shape
(10, 1, 28, 28)

这里,如果要访问第 1 个数据,只要写 x[0]就可以了

如果要访问第 1 个数据的第 1 个通道的空间数据,可以写成下面这样。

>>> x[0, 0] # 或者x[0][0]

像这样,CNN 中处理的是 4 维数据,因此卷积运算的实现看上去会很复杂,但是通过使用下面要介绍的 im2col这个技巧,问题就会变得很简单。

基于 im2col 的展开
如果老老实实地实现卷积运算,估计要重复好几层的 for语句。这样的实现有点麻烦。这里不使用 for语句,而是使用 im2col(image to column)这个便利的函数进行简单的实现。

im2col是一个函数,将输入数据展开以适合滤波器(权重)。
如下图所示,对 3 维的输入数据应用 im2col后,数据转换为 2 维矩阵(正确地讲,是把包含批数量的 4 维数据转换成了 2 维数据)。
在这里插入图片描述
具体地说,如下图所示,对于输入数据,将应用滤波器的区域(3 维方块)横向展开为 1 列。im2col会在所有应用滤波器的地方进行这个展开处理。

在这里插入图片描述
在上图中,为了便于观察,将步幅设置得很大,以使滤波器的应用区域不重叠。而在实际的卷积运算中,滤波器的应用区域几乎都是重叠的。在滤波器的应用区域重叠的情况下,使用 im2col展开后,展开后的元素个数会多于原方块的元素个数。因此,使用 im2col的实现存在比普通的实现消耗更多内存的缺点。但是,汇总成一个大的矩阵进行计算,对计算机的计算颇有益处。比如,在矩阵计算的库(线性代数库)等中,矩阵计算的实现已被高度最优化,可以高速地进行大矩阵的乘法运算。因此,通过归结到矩阵计算上,可以有效地利用线性代数库。

如下图所示,基于 im2col方式的输出结果是 2 维矩阵。因为 CNN 中数据会保存为 4 维数组,所以要将 2 维输出数据转换为合适的形状。以上就是卷积层的实现流程。
在这里插入图片描述
卷积运算的滤波器处理的细节:将滤波器纵向展开为 1 列,并计算和 im2col 展开的数据的矩阵乘积,最后转换(reshape)为输出数据的大小

卷积层的实现
im2col的实现如下

def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    """

    Parameters
    ----------
    input_data :(数据量, 通道,,)4维数组构成的输入数据
    filter_h : 滤波器的高
    filter_w : 滤波器的长
    stride : 步幅
    pad : 填充

    Returns
    -------
    col : 2维数组
    """
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = 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_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, 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

input_data——由(数据量,通道,高,长)的 4 维数组构成的输入数据
filter_h——滤波器的高
filter_w——滤波器的长
stride——步幅
pad——填充

下面使用im2col来实现卷积层,这里将卷积层实现为名为Convolution的类

class Convolution:
	def __init__(self, W, b, stride=1,pad=0):
		self.W = W
		self.b = b
		self.stride = stride
		self.pad = pad

	def forward(self, x):
		FN, C, FH, FW = self.W.shape
		N, C, H, W = x.shape
		out_h = init(1+ (H + 2*self.pad - FH) / self.stride)
		out_w = init(1+ (W + 2*self.pad - FW) / self.stride)

		col = im2col(x, FH, FW, self.stride, self.pad)
		col_W = self.W.reshape(FN, -1).T  # 滤波器的展开 
		out = np.dot(col, col_W) + self.b

		out = out.reshape(N,out_h,out_w, -1).transpose(0, 3, 1, 2)
		return out

度上的元素个数,以使多维数组的元素个数前后一致。比如,(10, 3, 5, 5) 形状的数组的元素个数共有 750 个,指定 reshape(10,-1)后,就会转换成 (10, 75) 形状的数组。

展开滤波器的部分将各个滤波器的方块纵向展开为 1 列。这里通过 reshape(FN,-1)将参数指定为 -1,这是 reshape的一个便利的功能。通过在 reshape时指定为 -1,reshape函数会自动计算 -1维度上的元素个数,以使多维数组的元素个数前后一致。比如,(10, 3, 5, 5) 形状的数组的元素个数共有 750 个,指定 reshape(10,-1)后,就会转换成 (10, 75) 形状的数组

池化层的实现
池化层也要使用 im2col展开输入数据
不过,池化的情况下,在通道方向上是独立的,这一点和卷积层不同。具体地讲,池化的应用区域按通道单独展开
如下图:
在这里插入图片描述
像这样展开之后,只需对展开的矩阵求各行的最大值,并转换为合适的形状即可
在这里插入图片描述
池化层的实现按下面 3 个阶段进行

  1. 展开输入数据。
  2. 求各行的最大值。
  3. 转换为合适的输出大小。

下面看Python的实际实现:

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 = pad

	def forward(self, x):
		N, C, H, W = x.shape
		out_h = init(1+ (H - self.pool_h) / self.stride)
		out_w = init(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*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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/674767.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS 7.9 安装 Docker

CentOS 7.9 安装 Docker 文章目录 CentOS 7.9 安装 Docker一、相关博客二、安装 Docker1、安装 device-mapper-persistent-data 和 lvm2 两个依赖2、添加阿里云 Docker 镜像源3、安装 Docker 社区版4、启动5、运行测试 三、配置阿里云镜像加速器 一、相关博客 【Docker】002-D…

基于ASP.NET MVC的网络书店系统/书店商城

摘 要 随着书店规模的不断扩大,人流数量的急剧增加,有关书店的各种信息量也在不断成倍增长。面对庞大的信息量,就需要有网络书店来提高书店工作的效率。通过这样的系统,我们可以做到信息的规范管理和快速查询,从而减少…

1Panel 安装部署

1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 1. 环境要求 安装前请确保您的系统符合安装条件: 操作系统:支持主流 Linux 发行版本(基于 Debian / RedHat,包括国产操作系统); 服务器架构&#…

LangChain: LLM应用开发框架

GitHub - hwchase17/langchain: ⚡ Building applications with LLMs through composability ⚡⚡ Building applications with LLMs through composability ⚡ - GitHub - hwchase17/langchain: ⚡ Building applications with LLMs through composability ⚡https://github.c…

6.22 驱动开发作业

字符设备驱动内部实现原理 1.字面理解解析: 字符设备驱动的内部实现有两种情况: 情况1.应用层调用open函数的内部实现: open函数的第一个参数是要打开的文件的路径,根据这个路径 虚拟文件系统层VFS 可以找到这个文件在文件系统…

Cookie,Session,Token,JWT授权方式对比

文章目录 HTTPCookieSessionSession认证流程Session 共享方案 TokenToken认证流程 JWTJWT认证流程 HTTP HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。服务端无法确认当前访问者的身份信息&…

升级一下《单词猜谜》

网上的单词猜谜都是英文的,不会英语的头痛 于是,我把《单词猜谜》改成中文,并且加上了点新功能: import random as rdmc rdm.randint(1, 3)name1 input("你的名字叫什么?:") if c 1:turns1 …

详解BigDecimal

目录 1.概述 2.基本API 2.1.创建 BigDecimal 对象: 2.3.基本运算方法: 2.4.精度控制方法: 2.5.比较 2.6.转换 3.注意事项 4.底层实现原理 1.概述 精度丢失,由于现代计算机中采用了浮点数来表示小数,这种表示…

小马哥训练营-Java EE单体架构

什么是Servlet Servlet 是一种基于 Java 技术的 Web 组件,用于生成动态内容,由容器管理。类似于其他 Java 技术组件,Servlet 是平台无关的 Java 类组成,并且由 Java Web 服务器加载执行。通常情况,由 Servlet 容器提供…

(十一)CSharp-LINQ-查询表达式(2)

一、查询表达式 1、查询表达式的结构 查询表达式由 from 子句和查询主体组成。 子句必须按照一定的顺序出现。from 子句和 select…group 子句这两部分是必需的。其他子句是可选的。在 LINQ 查询表达式中,select 子句在表达式最后。可以有任意多的 from…let…wh…

Nginx服务器的六个修改小实验

一、Nginx虚拟主机配置 1.基于域名 (1)为虚拟主机提供域名解析 配置DNS 修改/etc/hosts文件 (2)为虚拟主机准备网页文档 #创建网页目录 mkdir -p /var/www/html/abc mkdir -p /var/www/html/def ​ #编写简易首页html文件 ec…

Finalshell安全吗?Xshell怎么样?

文章目录 一、我的常用ssh连接工具二、Xshell2.1 下载:认准官网2.2 Xshell 配置2.3 Xftp和WinSCP 一、我的常用ssh连接工具 之前讲过: 【服务器】远程连接选SSH(PUTTY、Finalshell、WinSCP) 还是 远程桌面(RDP、VNC、…

代码随想录训练营第四十二天|01背包、416.分割等和子集

01背包 代码随想录理论讲解 背包问题分类 01背包 问题描述 有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 动归五部曲 确定dp数组及下…

基于java web高校社交系统 /springboot高校社交系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的系统应运而生,各行各业相继进入信息管理时代&#…

CSS处理页面元素浮动的几个办法

CSS处理页面元素浮动的几个办法 不使用浮动的情况下&#xff0c;子盒子1和2分别在盒子1中占据一行的空间。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" cont…

Java 8新特性:方法引用的介绍与使用

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 什么是方法引用&#xff1f; 2. 方法引用的…

【30天熟悉Go语言】9 Go函数全方位解析

作者&#xff1a;秃秃爱健身&#xff0c;多平台博客专家&#xff0c;某大厂后端开发&#xff0c;个人IP起于源码分析文章 &#x1f60b;。 源码系列专栏&#xff1a;Spring MVC源码系列、Spring Boot源码系列、SpringCloud源码系列&#xff08;含&#xff1a;Ribbon、Feign&…

【好书精读】网络是怎样连接的 之 数据收发完成之后 从服务器断开并删除套接字

&#xff08; 该图由AI制作 &#xff09; 目录 数据收发完成后协议栈要执行的操作 数据发送完毕后断开连接 删除套接字 数据收发操作小结 第一步是创建套接字 然后 客户端会向服务器发起连接操作 数据收发阶段 执行断开操作 数据收发完成后协议栈要执行的操作 数据发…

html_css模拟端午赛龙舟运动

文章目录 ⭐前言&#x1f496; 样式布局&#x1f496; 添加龙舟&#x1f496; 添加css_animation运动 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本期给大家分享css实现赛龙舟运动。 &#x1f496; 样式布局 风格&#xff1a;卡通 首先采用一张包括水元素的照片…

液体泄露识别检测算法 监控识别管道液体泄漏

液体泄露识别检测算法通过 yolov8python网络模型技术&#xff0c;液体泄露识别检测算法对管道的液体泄露情况进行全天候不间断实时监测&#xff0c;检测到画面中管道设备液体泄露现象时&#xff0c;将自动发出警报提示相关人员及时采取措施。YOLOv8 算法的核心特性和改动可以归…