img2col C++版本代码实现

深度学习之卷积操作中的im2col-代码篇 前一篇博客 中介绍了img2col的原理好理论实现方式,本篇结合代码来剖析该方法。 img2col函数的代码如下所示,下面来分析代码。 #include "im2col.h" #include <stdio.h> float im2col_get_pixel(float *im, int height, int width, int channels, ... 阅读详情

近期学习了下img2col的原理,自己写了版用C++实现的img2col。img2col对于熟悉深度学习的卷积计算的人来说应该并不陌生,它是一种将普通卷积计算转换为一次矩阵乘法计算的算法,相较于直接计算卷积来说能提升计算效率。

关于img2col的原理,网上有非常多的讲解,在此不再多作描述,不了解的人可以自行百度或参考以下链接:

极智AI | 一文看懂Img2Col卷积加速算法

我所实现的代码,正是基于上文中卷积加速算法的最后一种,也就是利用分块矩阵乘法的计算特性,将加偏置的步骤合并到一次矩阵乘法中,省去了一步矩阵加法。也就是下图中的算法(来自于以上链接):

关键代码如下,如需要测试代码及pytorch_python版的正确性验证代码,请到以下链接下载:

自己实现的img2col-C++代码+测试代码+pytorch-python验证代码

#include <Eigen/Core>

using namespace std;
using namespace Eigen;

typedef struct convRet
{
	int num;
	int width;
	int height;
	int* data;
}convRet;

/***
input:
imgw 原图像素宽
imgh 原图像素高
img 原图像素值
pad padding值
stride 步长
convN 卷积核数目
convW 卷积核宽
convH 卷积核高
conv 卷积核数值
bias 偏置值
output 计算后的输出
**/
void myImg2col(int imgw, int imgh, int* img, int pad, int stride, int convN, int convW, int convH, 
	int* conv, int* bias, convRet* output) {
	int unfoldW = convW * convH + 1;//img展开后的宽,此处加了偏移量扩展
	int unfoldH = ((pad * 2 + imgh - convH) / stride + 1)*((pad * 2 + imgw - convW) / stride + 1);//img展开后的高=卷积乘法次数
	int brow = 0 - pad;
	int bcol = 0 - pad;
	//定义存放img展开后的矩阵的eigen矩阵
	MatrixXi unfold(unfoldH, unfoldW);
	for (int h = 0; h < unfoldH; h++) {
		if (bcol + convW > imgw + pad) {//水平方向上超出了pad后的图片,要换行
			bcol = 0 - pad;
			brow += stride;
		}
		if (brow + convH > imgh + pad) {//竖直方向上已经超出pad后的图片了,一般外层循环就限制了不会到这步,加一个保险
			break;
		}
		for (int w = 0; w < unfoldW - 1; w++) {
			int rowBias = w / convW;
			int colBias = w % convW;
			if (brow + rowBias < 0 || bcol + colBias < 0 || brow + rowBias >= imgh || bcol + colBias >= imgw) {
				//满足此条件则说明在pad的区域里
				unfold(h, w) = 0;
			}
			else {
				unfold(h, w) = img[(brow + rowBias)*imgw + bcol + colBias];
			}
		}
		unfold(h, unfoldW - 1) = 1;
		bcol += stride;
	}


	//定义存放展开后的卷积核的eigen矩阵
	int unfoldConvLen = convH * convW + 1;
	MatrixXi unfoldConv(convN, unfoldConvLen);
	for (int n = 0; n < convN; n++) {
		for (int m = 0; m < unfoldConvLen - 1; m++) {
			unfoldConv(n, m) = conv[n*convW*convH + (m / convW)*convW + m % convW];
		}
		unfoldConv(n, unfoldConvLen - 1) = bias[n];
	}


	//两矩阵相乘
	MatrixXi retMat = unfold * unfoldConv.transpose();


	//取结果
	output->num = convN;
	output->width = (pad * 2 + imgw - convW) / stride + 1;
	output->height = (pad * 2 + imgh - convH) / stride + 1;
	output->data = (int*)malloc(sizeof(int)*convN*output->width*output->height);
	for (int n = 0; n < output->num; n++) {
		for (int h = 0; h < output->height; h++) {
			for (int w = 0; w < output->width; w++) {
				output->data[n*output->width*output->height + h * output->width + w] = retMat(h*output->width + w, n);
			}
		}
	
	}
}

从零开始手工实现卷积神经网络CNN以及img2col和col2img的实现方法 本文主要实现卷积神经网络(Convolutional Neural Network, CNN)中卷积操作的forward和backward函数。CNN主要包括卷积(Convolution),池化(pooling),全连接(Fully Connected)操作。相信点进来的同学对这些操作的细节已经很熟悉了,不熟悉的同学可以参考这一篇博文(本人看过讲CNN最简单易懂、最好的博文,没有之一):An In... 阅读详情

相关推荐

大模型-img2col与Linear to Conv的比较区别

卷积的。

点滴的岁月 1073

高性能卷积计算:img2col 原理详解

在我的上一篇文章「看完这篇我就不信还有人不懂卷积神经网络!」中,有位掘友在评论区留言道:要是能讲讲 img2col 就好了。今天我就安排上了,于是就有了本文。温馨提示:本文需要一些卷积神经网络方面的基础知识,不了解的同学需要先看看上面这篇文章☝。img2col 是一种实现卷积操作的加速计算策略。它能将卷积操作转化为 GEMM,从而最大化地缩短卷积计算的时间。

taoqick的专栏 7645

卷积算子优化-2.几种卷积算法

这篇文章来学习一下现在卷积常见的几种实现方法。

qwesh157的博客 1837

一文看懂Img2Col卷积加速算法

本文转自。

piglite的专栏 2414

C++实现二维快速傅里叶变换(FFT2):从原理到代码详解

快速傅里叶变换(FFT)是数字信号处理与图像处理领域的核心算法,它将离散傅里叶变换的计算复杂度从O(N²)降至O(N log N),极大地提升了频谱分析的效率。其基本原理是通过分治策略和蝶形运算,将大点数DFT分解为小点数DFT的组合。在工程实践中,二维FFT(FFT2)广泛应用于图像滤波、卷积加速和特征提取等场景,例如通过频域乘法实现高效的低通或高通滤波。本文以经典的Cooley-Tukey算法为基础,详细讲解如何用纯C++实现一个不依赖第三方库的二维FFT,涵盖行列分离法、复数运算优化以及频谱可视化等关

weixin_34235457的博客 481

用C++写一个小游戏——扫雷(1)

如何使用C++写一个简单的小游戏——扫雷

weixin_53532647的博客 6815

CANN/PTO ISA IMG2COL填充设置指令

![SET_IMG2COL_PADDING tile operation](https://raw.gitcode.com/cann/pto-isa/raw/5dbf1b2f6b8ea934f03e62367c2f540ece21134e/docs/figures/isa/SET_IMG2COL_PADDING.svg?utm_source=gitcode_repo_files) ## 简介

gitblog_00087的博客 813

C/C++游戏项目详细教学:《扫雷》

扫雷最原始的版本可以追溯到1973年一款名为“方块”的游戏。 不久,“方块”被改写成了游戏“Rlogic”。在“Rlogic”里,玩家的任务是作为美国海军陆战队队员,为指挥中心探出一条没有地雷的安全路线,如果路全被地雷堵死就算输。两年后,汤姆·安德森在“Rlogic”的基础上又编写出了游戏“地雷”,由此奠定了现代扫雷游戏的雏形。 1981年,微软公司的罗伯特·杜尔和卡特·约翰逊两位工程师在Windows3.1系统上加载了该游戏,扫雷游戏才正式在全世界推广开来。 这款游戏的玩法是在一个9*9(初级)

C语言C++学习俱乐部:765860056 1万+

PTO-ISA 指令解析:SET_IMG2COL_RPT——IMG2COL 重复次数元数据设置与后端实现

SET_IMG2COL_RPT 是 CANN pto-isa 虚拟指令集中服务于卷积(Conv)类数据搬运流水的一类配置型指令,其职责是从 IMG2COL 配置 Tile 中读取重复次数相关字段,写入后续 `TIMG2COL` 数据搬运操作所依赖的控制状态。本文以 [docs/isa/SET_IMG2COL_RPT_zh.md](https://link.gitcode.com/i/768f5d3

gitblog_00011的博客 338

【25】OpenCV C++实战篇——Mat img.total() 和img.cols * img.rows 意思一样吗?二者完全相等吗?

为了便于理解,先来梳理一下 Mat img的属性data:数据存储的起始地址 (uchar*类型);dims:矩阵维度。如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维;channels():通道数量,矩阵中表示一个元素所需要的值的个数。例:3 * 4矩阵中共有12个元素,如果每个元素需要3个值表示,那么此矩阵的通道数为3。常见的是一张彩色图片有B蓝、G绿、R红3个通道;depth():深度,即表示单通道中元素值的位数(bits)。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 743

【24】OpenCV C++实战篇—Mat img.total()*img.elemSize() 和img.cols * img.rows * img.channels()意思一样吗?二者完全相等吗?

为了便于理解,先来梳理一下 Mat img的属性data:数据存储的起始地址 (uchar*类型);dims:矩阵维度。如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维;channels():通道数量,矩阵中表示一个元素所需要的值的个数。例:3 * 4矩阵中共有12个元素,如果每个元素需要3个值表示,那么此矩阵的通道数为3。常见的是一张彩色图片有B蓝、G绿、R红3个通道;depth():深度,即表示单通道中元素值的位数(bits)。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 697

CANN/PTO-ISA:IMG2COL填充设置指令

![SET_IMG2COL_PADDING tile operation](https://raw.gitcode.com/cann/pto-isa/raw/5dbf1b2f6b8ea934f03e62367c2f540ece21134e/docs/figures/isa/SET_IMG2COL_PADDING.svg?utm_source=gitcode_repo_files) ## In

gitblog_00500的博客 425

COMSOL模拟CO2驱替CH4:多物理场耦合建模与工程应用详解

在非常规天然气开发与碳封存工程中,多孔介质内的渗流、吸附与岩石变形相互耦合,使得CO2驱替CH4的产能预测和CO2封存评估无法仅靠经验公式完成。以达西定律描述裂隙流动、以扩展Langmuir方程刻画竞争吸附、用应力-吸附-渗透率关系关联煤岩变形,是多物理场耦合数值模拟的核心路径。COMSOL Multiphysics凭借内置渗流、固体力学与组分传递接口,能够将这些机制整合为可参数化扫描的仿真模型,为注气压力、井距、渗透率演化等方案设计提供量化依据。围绕CO2驱替CH4模拟的建模流程、参数取法与结果判读,可形

weixin_29574585的博客 162

CANN PTO-ISA SET_IMG2COL_RPT指令文档

![SET_IMG2COL_RPT tile operation](https://raw.gitcode.com/cann/pto-isa/raw/5dbf1b2f6b8ea934f03e62367c2f540ece21134e/docs/figures/isa/SET_IMG2COL_RPT.svg?utm_source=gitcode_repo_files) ## 简介 从 IM

gitblog_00211的博客 420

从理论到实践:用CST微波工作室完成单站雷达RCS仿真的完整指南

本文提供了一份利用CST微波工作室进行单站雷达RCS仿真的完整实践指南。文章深入剖析了从求解器选择(重点推荐积分方程法)、模型与材料设置、平面波激励定义到后处理分析的完整逻辑链条,旨在帮助工程师不仅完成仿真,更能理解其背后的物理原理与工程考量,从而高效、精准地评估目标的电磁散射特性。

weixin_29256771的博客 180

Mit6.S081-实验1-Xv6 and Unix utilities

Mit6.S081-实验1-Xv6 and Unix utilities前言一、Boot xv61,实验目的2,操作流程1)切换到xv6-labs-2020代码库的lab1分支2)启动xv63)测试xv64)过程分析5)其他操作二、在xv6中添加一个自己编写的程序1,源码准备2,编译配置3,测试添加程序4,过程分析三、xv6中shell简析 前言 一、Boot xv6 1,实验目的 利用qemu启动xv6 2,操作流程 1)切换到xv6-labs-2020代码库的lab1分支 git checkout ut

code a better life~ 36万+

CANN PTO-ISA TIMG2COL 指令详解:从 NC1HWC0 特征图到 im2col 矩阵 Tile 的卷积数据重排

TIMG2COL 是 Ascend CANN 并行 Tile 操作指令集(PTO-ISA)中面向类卷积负载的图像到列(im2col)变换指令,用于将 NC1HWC0/NDC1HWC0 布局的输入特征图 Tile 重排为可供 TMATMUL 等矩阵运算直接消费的 im2col 风格矩阵 Tile。本文以 [docs/isa/TIMG2COL_zh.md](https://link.gitcode.c

gitblog_00943的博客 247

STM32+Air724UG基于阿里云物联网平台的OTA远程升级实战指南

本文提供了一套基于STM32微控制器与Air724UG 4G Cat.1通信模组,通过阿里云物联网平台实现OTA远程升级的完整实战指南。文章详细阐述了BootLoader与用户程序的分工、云端配置、固件下载与烧写流程,并分享了关键代码实现与常见问题排查方法,帮助开发者快速为物联网设备部署稳定可靠的无线升级功能。

weixin_28285943的博客 514

CANN/PTO-ISA TIMG2COL图像列变换指令

![TIMG2COL tile operation](https://raw.gitcode.com/cann/pto-isa/raw/5dbf1b2f6b8ea934f03e62367c2f540ece21134e/docs/figures/isa/TIMG2COL.svg?utm_source=gitcode_repo_files) ## 简介 用于类卷积工作负载的图像到列变换。 ##

gitblog_00620的博客 453

Facebook登录协议逆向实战:从加密参数到完整流程解析(附Python代码)

本文深入解析了Facebook登录协议的逆向工程实战,详细拆解了从关键加密参数(如`lgndim`、`encpass`)定位到完整登录流程的实现。文章提供了Python代码示例,重点阐述了加密逻辑的深度解析、加密函数的本地化实现,并解决了Crypto.js异步调用等常见问题,为研究Web安全和协议逆向的开发者提供了实用参考。

metal的博客 1312

PSOC Creator 入门教程超详细

最近工作原因需要使用到赛普拉斯的一款芯片,奈何以前没有用过,所以趁这次也学习了一些简单的用法,总结一下,希望能帮到有需要朋友,因为网上关于这方面的文章少的可怜,详细点的更是少之又少!废话少说,正文开始.

qm_mq的博客 5747

使用Pytorch的 C++ (CUDA)扩展实现卷积算子

在实现卷积算子时,将卷积算子等价转换为两个阶段:收集(collecting)和 线性变换(linear transform)。在收集阶段,“image to column” 和 “column to image” 过程分别在前向传播中将输入的。文件 setup.py,在项目目录中使用命令 python setup.py install 将其编译安装到python中。这里根据设备不同提供两种实现方式,一种是在CPU设备上串行实现,另一种是在GPU设备上并行实现。在线性变换阶段,卷积核权重对前向传播中得到的。

Mark的博客 1060

Codex 实战 Skills:自动采集一天之内的 Git 提交,一键排版成精美工作日报并发送邮件

特性手动撰写脚本辅助(仅聚合)AI 增强自动化(本文方案)时间成本高(30-60分钟/天)中(5-10分钟/天)低(<1分钟/天)内容质量依赖个人总结能力原始数据堆砌,缺乏提炼专业、结构化、有业务视角信息完整性易遗漏完整,但难以阅读完整,且经过分类筛选维护成本无低中(需维护 Skill 配置)可扩展性低中高(可轻松添加周报、月报)适用场景所有开发者初级开发者追求效率的高级开发者本文详细介绍了一种基于 Codex Agent Skills 的自动日报生成方案。

yueyeguzhuo的专栏 102

CANN/PTO-ISA SETFMATRIX指令文档

![SETFMATRIX tile operation](https://raw.gitcode.com/cann/pto-isa/raw/5dbf1b2f6b8ea934f03e62367c2f540ece21134e/docs/figures/isa/SETFMATRIX.svg?utm_source=gitcode_repo_files) ## Introduction Set the

gitblog_00153的博客 861

PMP--工件

合同是指对双方都有约束力的协议,强制卖方提供规定的产品、服务或结果,以及强制买方支付相应的费用。它还可能包括处于中间状态的特性,例如已设计但尚未构建的特性、质量保证中的特性或测试中的特性。RACI 矩阵是一种常见的方法,用于显示执行、担责、咨询或知情,且与项目活动、决策和可交付物有关的干系人。计划是提议的实现某种目标的方式。在项目开始前或开始时创建的文件,涉及与项目有关的战略、商业或高层级的信息。或 © 它们是用特定方法创建的结果,例如,虽然成本估算结果是一个重要工件,它们是用不同估算方法得出的结果。

stqer的博客 1666

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

opencv 的 (x、y) 坐标与 (row、col) 坐标的区别和使用方法

目录1、创建全黑图像2、单通道图像素值的读取3、三通道图像素值的读取4、保存视频时的尺寸 使用opencv时,经常用错(x、y)坐标和 (row、col) 坐标,所以写个博客总结一下。 1、创建全黑图像 Mat img = Mat::zeros(Size(cols,rows), CV_8UC1); //全黑单通道图 Mat img = Mat::zeros(Size(cols,rows), CV_8UC3); //全黑三通道图 Mat img1 = Mat::zeros(img.size(),

qq_43799400的博客 8753

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 怎样查询包含在A表中但不在B表中的数据?
下一篇: 老师上网课板书装备0成本解决方案
热血大婶
博客等级 码龄16年 58粉丝 32原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热血大婶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值