卷积神经网络的参数量及尺度变化计算

文章目录

  • 前言
  • 1.卷积
  • 2.参数量的计算
    • 2.1案例一
    • 2.2案例二
  • 3.奇怪的优化思想
    • 3.1使用小核卷积替换大核卷积
    • 3.2卷积核1×1的应用
  • 4.输出图像尺寸的计算
    • 4.1Same convolution
    • 4.2具体计算规则
    • 4.3转置卷积
  • 小结

前言

本篇博客主要介绍卷积基本概念,卷积神经网络的参数量计算、参数量优化的一些方法(VGG思想,1×1卷积核的应用)、输出图像尺寸的计算,同时也介绍了转置卷积(反卷积)中该如何计算输出图像的尺寸大小。

1.卷积

在深度学习的世界里,卷积操作如同一位默默耕耘的幕后英雄,支撑起图像识别、自然语言处理等众多领域的技术突破。无论是识别交通标志的自动驾驶系统,还是能理解人类语言的智能助手,背后都离不开卷积操作的强大力量。那么,卷积操作究竟是什么?
从数学角度来看,卷积是一种数学运算,用于描述两个函数如何通过某种方式相互作用,产生一个新的函数。在离散的数字信号处理场景下,卷积可以简单理解为两个序列通过特定的乘法和累加运算,得到一个新的序列,具体计算方式可以总结为8个字:翻褶、移位、相乘、相加,具体可见我之前博客的介绍卷积演示系统
而在计算机视觉领域,卷积与之类似,不同的是,处理的数据维度略有不同。
以3×3卷积核为例,其计算公式可以表示为;
g ( x , y ) = ∑ i = − 1 1 ∑ j = − 1 1 f ( x − i ) ( x − j ) ∗ w ( i , j ) g(x,y)=\sum_{i=-1}^{1}\sum_{j=-1}^{1}f(x-i)(x-j)*w(i,j) g(x,y)=i=11j=11f(xi)(xj)w(i,j)
其中w(i,j)表示卷积核,f(x,y)输入图像,g(x,y)为输出图像。
由于在训练过程中,学习的参数是w(i,j),因此加不加入翻褶区别并不大,因此在视觉领域一般不对卷积和进行翻褶操作。计算公式为:
g ( x , y ) = ∑ i = − 1 1 ∑ j = − 1 1 f ( x + i ) ( x + j ) ∗ w ( i , j ) g(x,y)=\sum_{i=-1}^{1}\sum_{j=-1}^{1}f(x+i)(x+j)*w(i,j) g(x,y)=i=11j=11f(x+i)(x+j)w(i,j)
这一操作准确来说应该称之为相关操作,但视觉领域一般并不区分这两种操作,统一称之为卷积操作
在这里插入图片描述

2.参数量的计算

在计算机视觉领域,卷积核不仅具有宽和高,还具有深度,常写成宽度×高度×深度的形式。
卷积核的参数不仅包括核中存储的权值,还包括一个偏置值。

2.1案例一

下面通过一个简单的例子介绍如何计算卷积和的参数量,这里定义如下网络:

import torch.nn as nn
class Net1(nn.Module):def __init__(self):super(Net1, self).__init__()self.conv1 = nn.Conv2d(1, 32, 5, padding=1)def forward(self, x):x = self.conv1(x)return x

该网络包括一个卷积层,输入通道数为1,输出通道数为32,卷积核大小为5×5,计算该层的参数量。
解释:因为输入通道数为1,因此卷积核大小可以表示为5×5×1,输出通道数为32,表明该层使用32个卷积核,同时每个卷积核有一个偏置值,因此参数量为:5×5×1×32+32=832。
通过代码验证可得:


from ptflops import get_model_complexity_infomodel = Net1()
ops, params = get_model_complexity_info(model, (1, 512, 512), as_strings=True,print_per_layer_stat=False, verbose=True)
params,5*5*1*32+32

运行结果:
在这里插入图片描述
这时可以看到,卷积操作的参数量核输入图像的尺寸大小无关,上述输入图像尺寸为1×512×512,如果使用全连接网络的话,那么此时输入层的结点个数为512×512=262144,如果隐含层结点个数为8,那么此时全连接网络的参数量为262144×8+8,之所以加8,是因为隐含层每个神经元都有一个偏置。
这是可以看到,卷积神经网络相对于全连接网络的优势,权值共享,参数量小
为什么称权值共享呢?因为每个特征图的计算依赖于同一个卷积核。

2.2案例二

为了避免你还未理清如何计算参数量这里再举一个例子,网络结构如下:

class Net2(nn.Module):def __init__(self):super(Net2, self).__init__()self.conv1 = nn.Conv2d(8, 32, 3, padding=1)def forward(self, x):x = self.conv1(x)return x

该网络包括一个卷积层,输入通道数为8,输出通道数为32,卷积核大小为3×3,计算该层的参数量。
解释:因为输入通道数为8,因此卷积核大小可以表示为3×3×8,输出通道数为32,表明该层使用32个卷积核,同时每个卷积核有一个偏置值,因此参数量为:3×3×8×32+32=2336。
代码验证:

model = Net2()
ops2, params2 = get_model_complexity_info(model, (8, 256, 256), as_strings=True,print_per_layer_stat=False, verbose=True)
params2,3*3*8*32+32

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

3.奇怪的优化思想

在卷积这一块,有很多优化思想,来所谓的减少参数量,这里主要介绍两种主流思想。

3.1使用小核卷积替换大核卷积

该思想来源于VGG网络的设计思想,论文地址:VGG网络模型,众所周知,之所以使用大核卷积,是为了获得更大的感受野,捕获更大的局部依赖关系。
前提知识:使用两个3×3的卷积核的感受野和一个5×5的卷积核的感受野大小一致。
这里我们定义两个网络,一个使用小核卷积,另一个使用大核卷积,假设每个卷积操作前后图像的深度保持不变。
大核卷积网络结构:

import torch.nn as nn
class Net1(nn.Module):def __init__(self):super(Net1, self).__init__()self.conv1 = nn.Conv2d(32, 32, 5, padding=2)def forward(self, x):x = self.conv1(x)return x

参数量:
在这里插入图片描述
小核卷积网络结构:

class Net3(nn.Module):def __init__(self):super(Net3, self).__init__()self.conv1 = nn.Conv2d(32, 32, 3, padding=1)self.conv2 = nn.Conv2d(32, 32, 3, padding=1)self.relu = nn.ReLU()def forward(self, x):x = self.conv1(x)x = self.relu(x)x = self.conv2(x)x = self.relu(x)return x

参数量:
在这里插入图片描述
从结果来看,小核卷积参数量更小,但能够和大核卷积达到相同的感受野。这就是为什么越来越多的网络结构使用小核卷积替换大核卷积。

3.2卷积核1×1的应用

这里直接举两个例子来介绍:
未使用1×1的卷积核:

class Net4(nn.Module):def __init__(self):super(Net4, self).__init__()self.conv1 = nn.Conv2d(256, 512, 3, padding=1)def forward(self, x):x = self.conv1(x)return x

参数量:
在这里插入图片描述
使用1×1卷积核:

class Net5(nn.Module):def __init__(self):super(Net5, self).__init__()self.conv1 = nn.Conv2d(256, 32, 1)self.conv2 = nn.Conv2d(32, 512, 3, padding=1)def forward(self, x):x = self.conv1(x)x = self.conv2(x)return x

参数量:
在这里插入图片描述
从结果来看,使用1×1的卷积核减少通道数,能够在一定程度上减少参数量,但在减少参数量的同时,输入的信息量也随之减少,如果输入的信息是一个稀疏矩阵的话,那么该方法确实适合减少参数量。

4.输出图像尺寸的计算

前面所说,都是考虑的是卷积的参数量,接着讨论输出图像尺寸如何计算。
卷积主要分为三种,Full convolution、Same convolution、valid convolution,这里主要介绍用处较多的一种,即Same convolution

4.1Same convolution

主要是设置padding参数的值
网络结构:

class Net6(nn.Module):def __init__(self):super(Net6, self).__init__()self.conv2 = nn.Conv2d(32, 512, 3, padding='same')def forward(self, x):x = self.conv2(x)return x

运行测试:

import torch
model = Net6()
I=torch.randn(32,128,128)
model(I).shape

运行结果:
在这里插入图片描述
解释:输入图像的尺寸为32×128×128,通过网络结构可以看出,该层使用512个卷积核,因此输出通道数为512,因为padding参数设置的是same,输出会保持图像的尺寸大小。
有时并不将其设置为same,而是设置一个具体的值,这里只是因为设置了same,其自动计算了一个具体的值代入进去了而已。

4.2具体计算规则

输出图像的尺寸,不仅和填充列数有关,还和卷积核大小以及卷积步长有关。具体计算公式如下:
W 2 = ( W 1 − F + 2 P ) S + 1 W_2=\frac{(W_1-F+2P)}{S}+1 W2=S(W1F+2P)+1
H 2 = ( H 1 − F + 2 P ) S + 1 H_2=\frac{(H_1-F+2P)}{S}+1 H2=S(H1F+2P)+1
其中, W 1 、 H 1 W_1、H_1 W1H1表示输入图像的尺寸大小, W 2 、 H 2 W_2、H_2 W2H2表示输出图像的尺寸大小,F为卷积核尺寸,S为卷积步长,P为零填充数量。
下面举一个详细的例子说明。
网络结构为:

class Net7(nn.Module):def __init__(self):super(Net7, self).__init__()self.conv2 = nn.Conv2d(32, 512, 5, padding=1,stride=2)def forward(self, x):x = self.conv2(x)return x

输出结果:
在这里插入图片描述
解释:根据公式计算即可,(128-5+2*1)/2+1=63,除法运算一律向下取整。输出通道数和卷积核个数512保持一致,因此输出形状为512×63×63。

4.3转置卷积

转置卷积(Transposed Convolution),又称反卷积(Deconvolution),具体计算方式也是卷积的逆运算。
由卷积计算公式为:
W 2 = ( W 1 − F + 2 P ) S + 1 W_2=\frac{(W_1-F+2P)}{S}+1 W2=S(W1F+2P)+1
H 2 = ( H 1 − F + 2 P ) S + 1 H_2=\frac{(H_1-F+2P)}{S}+1 H2=S(H1F+2P)+1
转置卷积,与其计算方式相反,相当于反函数的关系。
W 1 = S × ( W 2 − 1 ) − 2 P + F W_1=S×(W_2-1)-2P+F W1=S×(W21)2P+F
H 1 = S × ( H 2 − 1 ) − 2 P + F H_1=S×(H_2-1)-2P+F H1=S×(H21)2P+F
其中, W 1 、 H 1 W_1、H_1 W1H1表示输出图像的尺寸大小, W 2 、 H 2 W_2、H_2 W2H2表示输入图像的尺寸大小,F为卷积核尺寸,S为卷积步长,P为零填充数量。
下面举一个详细的例子说明。

class Net8(nn.Module):def __init__(self):super(Net8, self).__init__()# 转置卷积self.conv_transpose = nn.ConvTranspose2d(in_channels=32, out_channels=16, kernel_size=3, stride=2, padding=1)def forward(self, x):x = self.conv_transpose(x)return x

输出结果:
在这里插入图片描述
解释:根据公式计算即可,2*(128-1)-2*1+3,输出通道数和卷积核个数16保持一致,因此输出形状为16×255×255。

小结

通过本篇博客,相比你也能够计算卷积神经网络中图像尺寸如何变化的,快去找一个深层的网络试试看吧,看它的尺寸变化是否和你想的一样呢?可以试试本篇博客设计的网络模型——Unet语义分割模型

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

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

相关文章

OpenCV——图像平滑

图像平滑 一、图像的噪声1.1、噪声来源1.2、噪声类型1.3、噪声模拟 二、滤波器三、线性滤波3.1、均值滤波3.2、方框滤波3.3、高斯滤波 四、非线性滤波4.1、中值滤波4.2、双边滤波 图像在采集和传输过程中容易受到各种因素的影响而产生噪声,而噪声会对图像的正确解读…

鸿蒙系统备份恢复

鸿蒙系统尝试者,在纯血鸿蒙与鸿蒙4.2/4.3之前反复横跳,中间折腾… 目录 鸿蒙4.2/4.3升级鸿蒙5.0系统备份 鸿蒙5.0回退鸿蒙4.2/4.3系统备份备份恢复 华为手机助手注意 鸿蒙4.2/4.3升级鸿蒙5.0 系统备份 云空间备份手机本地备份华为手机助手备份 鸿蒙5.…

JS进阶 Day03

1.两种面向编程思想 2.构造函数实现封装以及存在的问题 下面就引出了原型对象 3.原型对象prototype 共享原理图&#xff1a; 4.数组扩展案例-求最大值和数组求和 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><…

visual studio小番茄插件某些快捷键失效

问题 AltO 切换头文件和源文件失效。 背景 最近升级了 visual studio&#xff0c;多了一些插件 原因 Alt O 快捷键被其他插件占用了 解决方案 工具 → 选项 → 环境 → 键盘 搜索这个 VAssistX.OpenCorrespondingFile&#xff08;切换头/源文件&#xff09; 发现命令的快…

基于单片机的PT100温度变送器设计

基于单片机的PT100温度变送器设计 文章目录 基于单片机的PT100温度变送器设计前言一、资源分享二、系统框架三、硬件准备1.主控制器2、PT100温度传感器3、显示屏4、WIFI模块5、USB转RS485模块6、SP3485EN7、K11-11D3 四、设计PCB1、安装下载立创EDA专业版2、画原理图3、摆放元器…

Git 清理指南:如何从版本库中移除误提交的文件(保留本地文件)

场景 在 Git 项目中&#xff0c;我们可能会不小心提交了本应忽略的文件&#xff08;如 node_modules/、.env、*.log 等&#xff09;&#xff0c;导致仓库体积膨胀或敏感信息泄露。本文介绍如何从 Git 历史中彻底删除这些文件&#xff0c;同时保留本地文件。 解决方案 1. 确认…

服务器数据恢复—重装系统导致XFS文件系统分区无法访问的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台服务器上通过磁盘柜RAID卡组建的riad5磁盘阵列&#xff0c;服务器上层安装Linux操作系统&#xff0c;搭建XFS文件系统。服务器上层分配一个LUN&#xff0c;并划分了两个分区。通过LVM扩容的方式将sdc1分区加入到了root_lv中&#…

在QtCreator中使用GitHubCopilot

文章目录 1.github copilot账号2. 安装node.js3.安装 GitHub Copilot Neovim plugin4.在Qt中启用4.1.在extension中启用4.2.在配置中启用4.3.使用/禁用 5.评价 在最新版的QtCreator中&#xff0c;已经通过Extension集成了GitHubCopilot进来。 我用的是16.0.2版本的&#xff08;…

岛屿周长问题的三种解法:直接计数法、数学计算法与深度优先搜索

问题描述 给定一个二维网格 grid&#xff0c;其中1表示陆地&#xff0c;0表示水域。网格中的格子水平和垂直方向相连&#xff08;对角线不相连&#xff09;。网格中恰好有一个岛屿&#xff08;即一个或多个相连的陆地格子&#xff09;&#xff0c;需要计算这个岛屿的周长。 解…

将包含父子关系的扁平列表 List<Demo> 转换成树形结构的 List<DemoVO>,每个节点包含自己的子节点列表

1.stream递归操作 private List<DemoVO> createtree(List<Demo> datas) {//得到父节点return datas.stream().filter(m -> TargetConstants.ROOT.equalsIgnoreCase(m.getParentId())).map(m -> {DemoVO vo new DemoVO();vo.setTaxonomyId(m.getPlatformTaxo…

【Jmeter】Jmeter 高并发性能压力测试

目录 一、下载 Jmeter 二、配置环境变量 三、设置中文语言 四、入门最简单的高并发性能压测流程 1. 添加线程组 2. 添加请求 3. 添加监听器 3.1 添加聚合报告 3.2 添加结果树 4. 启动测试 2 种启动方式&#xff1a; 查看结果树&#xff1a; 聚合报告&#xff1a; 五…

芯片测试之VIL/VIH(输入电平)Test全解析:从原理到实战

大家好&#xff0c;我是硅言。在数字芯片的“沟通体系”中&#xff0c;​​VIL&#xff08;输入低电平&#xff09;​​和​​VIH&#xff08;输入高电平&#xff09;​​如同芯片的“听觉阈值”&#xff0c;决定了它能否准确识别外部信号的逻辑状态。本文将从原理剖析、测试方…

【WPF】MVVM的消息机制

在WVM&#xff08;Model-View-ViewModel&#xff09;架构中&#xff0c;消息机制主要用于实现ViewModel与View之间的通信&#xff0c;同时保持它们的分离。这对于维护代码的清晰度和可测试性非常重要。在WPF&#xff08;Windows Presentation Foundation&#xff09;应用程序中…

以楼宇自控关键技术,夯实现代低碳建筑发展重要基础

当“碳达峰、碳中和”成为全球发展共识&#xff0c;建筑行业作为能源消耗与碳排放的重要领域&#xff0c;正加速向低碳化转型。在这场绿色变革中&#xff0c;楼宇自控技术凭借对建筑设备的智能管控与能源优化能力&#xff0c;成为现代低碳建筑建设的核心支撑。从数据采集到智能…

西电【信息与内容安全】课程期末复习笔记

西电【信息与内容安全】课程期末复习笔记 来自2022年春的古早遗留档案&#xff0c;有人需要这个&#xff0c;我就再发一下吧。 ‍ 平时成绩&#xff1a; 10%。线上&#xff1a; 10% &#xff08;线上学习内容&#xff0c; 共 100 分。&#xff09;实验&#xff1a; 10% &#…

【论文阅读笔记】ICLR 2025 | 解析Ref-Gaussian如何实现高质量可交互反射渲染

Reflective Gaussian Splatting Info 会议 【ICLR 2025】 作者 复旦大学&#xff0c;萨里大学&#xff1b;复旦张力教授团队 Github地址 https://github.com/fudan-zvg/ref-gaussian.git Project地址 https://fudan-zvg.github.io/ref-gaussian/ Abstract 新视图合成得益…

面向GPU、CPU及机器学习加速器的机器学习编译器

机器学习编译器概述 机器学习编译器是一种专门针对机器学习工作负载设计的工具&#xff0c;旨在将高层模型描述&#xff08;如TensorFlow或PyTorch模型&#xff09;高效编译为可在不同硬件&#xff08;如GPU、CPU或专用加速器&#xff09;上执行的底层代码。其核心目标是优化计…

论文分类打榜赛Baseline(2):InternLM昇腾硬件微调实践

本文来自社区投稿&#xff0c;作者丁一超 书生大模型实战营第5期已正式启动&#xff0c;本期实战营新增「论文分类打榜赛」&#xff0c;以帮助学员更好地掌握大模型技能。 本文将手把手带领大家如何基于昇腾微调 InternLM 模型&#xff0c;轻松上手论文自动分类任务。从环境配…

mac安装mvnd结合idea

mac安装mvnd结合idea hi&#xff0c;我是阿昌&#xff0c;今天记录一下mac系统下如何安装mvnd同时通过maven-helper插件配置mvnd命令&#xff0c;提升编译速度&#xff1b; 0、前言 如果你正在开发一个由大量模块组成的大型项目&#xff0c;Gradle可以让大型项目构建的更快&…

扩展模块--QWebEngine功能及架构解析

Qt WebEngine 模块在 Qt 6.9 中提供了基于 Chromium 的网页渲染引擎功能。 一、主要功能 核心功能 网页渲染引擎 基于 Chromium 项目的最新稳定版本 支持现代 HTML5、CSS3 和 JavaScript 标准 主要组件 QWebEngineView - 用于显示网页内容的 widget QWebEnginePage - 表示…