im2col运算 - 一种卷积优化算法
原文:https://blog.csdn.net/dwyane12138/article/details/78449898
1、矩阵卷积
卷积就是卷积核跟图像矩阵的运算。卷积核是一个小窗口,记录的是权重。卷积核在输入图像上按步长滑动,每次操作卷积核对应区域的输入图像,将卷积核中的权值和对应的输入图像的值相乘再相加,赋给卷积核中心所对应的输出特征图的一个值,如下图所示(这里卷积核要旋转180 °):
2、im2col的实现
2.1 im2col有什么作用
以上我们已经知道了卷积是如何操作的,im2col的作用就是优化卷积运算,如何优化呢,我们先学习一下这个函数的原理。
我们假设卷积核的尺寸为2*2,输入图像尺寸为3*3.im2col做的事情就是对于卷积核每一次要处理的小窗,将其展开到新矩阵的一行(列),新矩阵的列(行)数,就是对于一副输入图像,卷积运算的次数(卷积核滑动的次数),如下图所示:
以最右侧一列为例,卷积核为2*2,所以新矩阵的列数就为4;步长为一,卷积核共滑动4次,行数就为4.再放一张图应该看得更清楚。
输入为4*4,卷积核为3*3,则新矩阵为9*4 。看到这里我就产生了一个疑问:我们把一个卷积核对应的值展开,到底应该展开为行还是列呢?卷积核的滑动先行后列还是相反?区别在哪?
这其实主要取决于我们使用的框架访存的方式。计算机一次性读取相近的内存是最快的,尤其是当需要把数据送到GPU去计算的时候,这样可以节省访存的时间,以达到加速的目的。不同框架的访存机制不一样,所以会有行列相反这样的区别。在caffe框架下,im2col是将一个小窗的值展开为一行,而在matlab中则展开为列。所以说,行列的问题没有本质区别,目的都是为了在计算时读取连续的内存。
这也解释了我们为什么要通过这个变化来优化卷积。如果按照数学上的步骤做卷积读取内存是不连续的,这样就会增加时间成本。同时我们注意到做卷积对应元素相乘再相加的做法跟向量内积很相似,所以通过im2col将矩阵卷积转化为矩阵乘法来实现。
2.2 一个简单实现
基于以上对于im2col的理解,自己写了一个简单实现(c++ opencv3.2)。
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;int main()
{Mat img =imread("1.jpg");Mat kernel=Mat::ones(9,9,CV_8UC1);int stride=5;int kernum_w,kernum_h;if(img.rows%stride==0)kernum_w=img.rows/stride;elsekernum_w=img.rows/stride+1;if(img.cols%stride==0)kernum_h=img.cols/stride;elsekernum_h=img.cols/stride+1;int out_w=kernum_w*kernum_h;int out_h=kernel.cols*kernel.rows;int channel_size=img.cols*img.rows;//初始化输入、卷积核并计算新矩阵的尺寸Mat C=Mat::zeros(out_w,out_h,CV_8UC3);for (int channel=img.channels();channel--;channel>0){ int i=0;for (int im_row=0;im_row<img.rows;im_row+=stride){for (int im_col=0;im_col<img.cols;im_col+=stride){ for (int ker_row=0;ker_row<kernel.rows;ker_row++){for(int ker_col=0;ker_col<kernel.cols;ker_col++){int input_row=im_row-(kernel.rows-1)/2+ker_row;int input_col=im_col-(kernel.cols-1)/2+ker_col;//索引当前小窗内元素对应到输入的行列值if(input_row<0||input_col<0||input_row>=img.rows||input_col>=img.cols)C.at<Vec3b>(i,ker_col+kernel.cols*ker_row)[channel]=0; else C.at<Vec3b>(i,ker_col+kernel.cols*ker_row)[channel]=img.at<Vec3b>(input_row,input_col)[channel];//超出原图的范围,则新矩阵对应的位置赋零,否则将输入赋给对应的位置}}i++;}} }imshow("im2col",C);waitKey(0);return 0;
}
对于c++我也只是初学者,关于指针,我还要多加学习,这里对图像的遍历使用了Mat类的成员函数at(),也是一种比较低效率的方法。高效的方法(指针方法)参考这篇http://blog.csdn.net/daoqinglin/article/details/23628125
参考文献
http://lib.csdn.net/article/aiframework/62849(这里有caffe中的源码解读)
http://blog.csdn.net/mrhiuser/article/details/52672824
im2col运算 - 一种卷积优化算法相关推荐
- 梯度下降算法_Adam-一种随机优化算法
[前言]: 优化问题一直是机器学习乃至深度学习中的一个非常重要的领域.尤其是深度学习,即使在数据集和模型架构完全相同的情况下,采用不同的优化算法,也很可能导致截然不同的训练效果. adam是opena ...
- 两种鲸鱼优化算法 (whale optimization algorithm, WOA)及仿真实验——附代码
目录 摘要: 算法设计: WOA总体流程图如下: 增强型WOA(E-WOA) 仿真运行效果: 完整程序: 摘要: 鲸鱼优化算法 (whale optimization algorithm,WOA)是 ...
- 机器学习萌新必备的三种优化算法 | 选型指南
作者 | Nasir Hemed 编译 | Rachel 出品 | AI科技大本营(id:rgznai100) [导读]在本文中,作者对常用的三种机器学习优化算法(牛顿法.梯度下降法.最速下降法)进行 ...
- 各种智能优化算法比较与实现(matlab版)
各种智能优化算法比较与实现(matlab版) 一. 方法介绍 1免疫算法(Immune Algorithm,IA) 1.1算法基本思想 免疫算法是受生物免疫系统的启发而推出的一种新型的智能搜索算法.它 ...
- 深度学习中的优化算法之MBGD
之前在https://blog.csdn.net/fengbingchun/article/details/75351323 介绍过梯度下降,常见的梯度下降有三种形式:BGD.SGD.MBGD,它们的 ...
- 深度学习中的优化算法之BGD
之前在https://blog.csdn.net/fengbingchun/article/details/75351323 介绍过梯度下降,常见的梯度下降有三种形式:BGD.SGD.MBGD,它们的 ...
- 2021-01-26 粒子群优化算法(PSO)以及Matlab实现
粒子群优化算法(PSO)以及Matlab实现 1.粒子群算法 粒子群算法是一种智能优化算法.关于智能,个人理解,不过是在枚举法的基础上加上了一定的寻优机制.试想一下枚举法,假设问题的解空间很小,比如一 ...
- 萤火虫算法_智能优化算法萤火虫算法
今天介绍的算法是萤火虫算法(Firefly Algorithm,简称FA),也是一种仿生优化算法.从算法名字就知道了,该算法的思想来源于萤火虫,具体是萤火虫的闪烁行为.下面是展开对算法相关内容的介绍. ...
- 智能优化算法:白鲸优化算法-附代码
智能优化算法:白鲸优化算法 摘要:白鲸优化算法([Beluga whale optimization,BWO)是由是由 Changting Zhong 等于2022 年提出的一种群体智能优化算法.其灵 ...
- 智能优化算法:侏儒猫鼬优化算法-附代码
智能优化算法:侏儒猫鼬优化算法 摘要:侏儒猫鼬优化算法(Dwarf Mongoose Optimization,DMO)是由是由 Jeffrey O. Agushaka 等于2022 年提出的一种群体 ...
最新文章
- cstring 比较_不同商用齿轮齿接触分析软件的比较(三)
- PaperNotes(5)-Conditional Generative Adversarial Nets
- java中产生对象的两种方式
- 跨境电商为什么需要ERP系统?
- php毕设周记_毕设周记(一)
- 洛谷试炼场P1035 级数求和
- python验证身份证号码_用Python校验身份证号码
- Zerotier+Microsoft远程桌面 实现内网穿透搭建异地局域网内远程连接控制桌面
- 新型的Hbb项目目录结构
- java毕业设计_基于android的二手书城app的设计与实现
- uva10158(并查集)
- 发布本人整理的面试问题大全,为准备找工作的同行们尽一份力 希望大家多补充或回答
- 手把手教你使用Python抓取QQ音乐数据!
- centos 安装erlang
- matlab画对数坐标!
- DS1307时钟模块
- 我有一只猫,名字叫做狗.还有一只狗,名字叫做猫
- (力扣)LeetCode994. 腐烂的橘子(C语言)
- 用Go处理原始数据包
- win10突然出现蓝屏,终止代码:BAD_POOL_CALLER
热门文章
- CAD基础+常用快捷(四)
- 搭建syslog日志服务器
- ACM中AC、WA、PE、RE分别是什么意思
- RuntimeError: The size of tensor a (4) must match the size of tensor b (3)
- 自组织神经网络:自组织特征映射SOM网络
- 发表skiller的几个版本
- linux系统中rpm啥意思,Linux系统中的RPM简说
- 解决多旅行商(MTSP)的分组遗传算法(GGA-SS)
- android 6 root权限,安卓手机获取root权限真的很简单
- 如何让自己的电脑内外网同时用?