卷积加速算法img2col、Winograd、FFT

news2024/9/19 10:34:52

FFT

空间域中矩阵的卷积算子,实际等于频率域中两个矩阵元素相乘。但卷积的方向是相反的。

通常情况下,feature的尺寸要比卷积的尺寸大很多,如果对两者进行快速傅里叶变换的话,得出来的两个矩阵大小不一样,不能进行对应位置相乘。

为了可以让他们对应位置相乘,必须要对卷积核进行扩充,将其扩充到feature尺寸大小相同。也正是扩充过程,限制了方法的使用,只有当feature尺寸和卷积核尺寸大小差不多的时候,才会采用这种方法。

通常有三种卷积方式:full、same、valid

full卷积方式:会先对图像的四周进行补0,补零的行数(列数)为卷积核宽度(高度)-1,最终卷积出来的结果一定会比原图像大的


same卷积方式:这种卷积方式的结果大小一定会与原图像一样,通常补零的个数为向下取整

卷积核大小为n/2


valid卷积方式:不会对原图进行补零操作,所以会导致原图像大小变小

现在来分析,如果使用FFT来进行快速卷积,怎么补零

假设,我们输入的图像和卷积核分别如下

如果用full方式进行卷积,补零结果如下

这是因为,在用full方式进行卷积的时候,原图8x7大小,会变成10x9的大小,所以我们要把原图填充成上述样子。同理,我们需要把卷积核进行填充至10x9的大小

我们需要先对其进行水平翻转和垂直翻转,再进行卷积运算

所以对feature和核填充0后,还要再进行水平翻转和垂直翻转

def fftConvt(img,ker):
    //第一步:对图像进行填充
    img_padding = np.zeros(shape = [len(img)+len(ker)-1],[len(img)+len(ker)-1])
    img_padding[(len(ker)-1:len(ker)-1+len(img)),len(ker[0])-1:len(ker[0])-1+len(img)]=img
    ker = np.flip(ker,axis=0)
    ker = np.flip(ker,axis=1)

//第二步,对卷积核进行填充
    ker_padding = np.zeros(shape = img_padding.shape)
    ker_padding[:len(ker),:len(ker[0])]=ker
    img_padding_fft2=np.fft.fft2(img_padding)
    ker_padding_fft2=np.fft.fft2(ker_padding)
    img_fft2=img_padding_fft2*ker_padding_fft2
    return np.real(np.fft.fft2(img_fft2))

img2col

将卷积运算转换为矩阵乘法运算。

输入数据是一个三通道的features

我们有两个卷积核,每个卷积核有三个子核

如何把卷积转换为矩阵乘法呢?

传统卷积中,我们采用滑动窗口进行加权求和。将每个滑块所形成的字矩阵拉直,我们拿出第一个features进行拉直

拿出第一个卷积核中的子矩阵

现在移动滑动窗口,逐一进行拉直

然后形成了四个向量,将其堆叠起来,形成一个新的矩阵

再将卷积核拉直

现在,就可以用之前形成的矩阵和拉直的卷积核进行矩阵乘法

 

做乘法之后,每个窗口会得到一个列向量,这个列向量就是每个窗口加权平均值,即卷积值,3*3矩阵做2*2卷积,输出是2*2,将列向量reshape,即可得到最终结果。

对于多通道,我们将三个通道生成的矩阵堆叠在一起

每个卷积核的子矩阵给拉直,然后再堆叠到一起

最后实现两者的乘积,即可得到卷积结果

def img2col(img,ker):
    ker_width=len(ker[0])
    ker_height=len(ker)
    transform=np.empty(shape=((len(img[0]) - ker_width)*(len(img) - ker_height), ker_width*ker_height))
    cur=0
    for y in range(0,len(img)-ker_height):
        for x in range(0, len(img[0]) - ker_width):
            data=img[y:y+ker_height,x:x+ker_width].reshape(1,9)
            transform[cur,:]=data
            cur=cur+1
    return np.dot(transform,ker.reshape(-1,1)).reshape(len(img)-ker_height,-1)


Winograd 需要仔细阅读

Winograd算法出自CVPR 2016的一篇 paper:Fast Algorithms for Convolutional Neural Networks。,这个算法可以用来加速卷积运算,目前有很多框架如NCNN、NNPACK等,对于卷积层都采用了Winograd快速卷积算法。

卷积神经网络中的Winograd快速卷积算法

  • Winograd算法通过减少乘法次数来实现提速,但是加法的数量会相应增加,同时需要额外的transform计算以及存储transform矩阵,随着卷积核和tile的尺寸增大,就需要考虑加法、transform和存储的代价,而且tile越大,transform矩阵越大,计算精度的损失会进一步增加,所以一般Winograd只适用于较小的卷积核和tile(对大尺寸的卷积核,可使用FFT加速),在目前流行的网络中,小尺寸卷积核是主流,典型实现如F(6×6,3×3)𝐹(6×6,3×3)、F(4×4,3×3)𝐹(4×4,3×3)、F(2×2,3×3)𝐹(2×2,3×3)等,可参见NCNN、FeatherCNN、ARM-ComputeLibrary等源码实现。
  • 就卷积而言,Winograd算法和FFT类似,都是先通过线性变换将input和filter映射到新的空间,在那个空间里简单运算后,再映射回原空间。
  • 与im2col+GEMM+col2im相比,winograd在划分时使用了更大的tile,就划分方式而言,F(1×1,r×r)𝐹(1×1,𝑟×𝑟)与im2col相同。
def Winograd(img,ker):
    U = G.dot(ker).dot(G.T)
    res=np.empty(shape=[98,98])
    for y in range(0,len(img)-8,6):
        for x in range(0, len(img[0])-8,6):
            tile=img[y:y+8,x:x+8]
            V=BT.dot(tile.T).dot(BT.T)
            res[y:y+6,x:x+6]=AT.dot(U*V).dot(AT.T).T
    return res

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

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

相关文章

Java读写t5557卡源码

T5557卡是美国Atmel公司生产的多功能非接触式射频卡芯片,属于125KHz的低频卡,在国内有广大的应用市场。该芯片共有330bit(比特)的EPROM(分布为10个区块, 每个区块33bit)。0页的块0是被保留用于设置T5557操作模式的参数配置块。第0页第7块可以作用户数据块…

ATA-8202射频功率放大器有什么作用

射频功率放大器是一种专门用于放大射频信号功率的电子器件。它在无线通信、雷达系统、卫星通信、医疗设备和广播电视等领域中发挥着重要作用。下面安泰电子将介绍ATA-8202射频功率放大器的作用及其在不同应用领域中的具体应用。 一、ATA-8202射频功率放大器的作用 射频功率放大…

短链接day8

短链接监控 开发访问单个短链接监控统计功能 不知道是哪里复制错了,反正就是一顿报错,改了这个又改那个,还是报错。。暂时不管了。 记录短链接访问日志 logdo新增networt、device、local属性。 分页查询短链接访问日志 分页查询短链接今…

使用Bind提供的域名解析服务

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、DNS域名解析服务 二、安装Bind服务程序 1、正向解析 2、反向解析 三、部署从服务器 四、安全的加密传输 五、部署缓存服务器 六、分…

AI算法19-偏最小二乘法回归算法Partial Least Squares Regression | PLS

偏最小二乘法回归算法简介 算法概述 偏最小二乘法模型可分为偏最小二乘回归模型和偏最小二乘路径模型。其中偏最小二乘回归模型是一种新型的多元统计方法,它集中了主成分分析、典型相关分析和线性回归的特点,特别在解决回归中的共线性问题具有无可比拟…

在JavaScript中,什么是解构赋值(destructuring assignment)?

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介在JavaScript中,什么是解构赋值(destructuring assignment)?1. 引言2. 解构赋值的概念3. 数组解构赋值3.1 基本语法3.2 跳过元素3.3 默认值3.4 交换变量值 4. 对象解构赋值4.1 基本语…

“解锁物流新纪元:深入探索‘沂路畅通‘分布式协作平台“

"解锁物流新纪元:深入探索沂路畅通分布式协作平台" 在21世纪的数字浪潮中,物流行业作为连接生产与消费的关键纽带,其重要性不言而喻。然而,随着市场规模的持续扩大和消费者需求的日益多样化,传统物流模式已…

150个pb网站模板(都是成品网站,上传php空间即可使用),建站必备

一网友提供的150个pb网站模板,其实就是成品网站,上传php空间即可使用,属于建站公司或者建站开发人员必备的资源。 一共150个基于pb的成品网站,基本上都可以找到适应你手头客户需要的一款,简单修改一下即可交活收钱了。…

LinuxShell编程1———shell基础命令

文章目录 前言 一、shell基础知识 1、shell概念 2、Shell的功能 接收:用户命令 调用:相应的应用程序 解释并交给:内核去处理 返还:内核处理结果 3、Shell种类(了解) 3.1、MS-DOS 3.2、Windows的…

图片在线怎样做二维码?制作二维码展示图片的制作方法

图片想要更快捷的分享给其他人展示,除了通过网站平台之外,比如朋友圈、qq空间、微博等方式外,现在很多人也会通过生成二维码的方法,让其他人可以通过扫描二维码查看图片。图片转换二维码的好处有很多,比如可以节省空间…

【C++航海王:追寻罗杰的编程之路】智能指针

目录 1 -> 为什么需要智能指针? 2 -> 内存泄漏 2.1 ->什么是内存泄漏,以及内存泄漏的危害 2.2 -> 内存泄漏分类 2.3 -> 如何避免内存泄漏 3 -> 智能指针的使用及原理 3.1 -> RAII 3.2 -> 智能指针的原理 3.3 -> std…

IDEA创建普通Java项目

环境准备 Java环境 运行javac查看java环境是否安装完成 开发工具Intellij IDEA 下载地址:https://www.jetbrains.com/idea/download/?sectionwindows 创建项目 点击新建项目 填入项目名字,项目路径,选择maven,点击下面的创建 运行项目 …

贪心,CF 1891C - Smilo and Monsters

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1891C - Smilo and Monsters 二、解题报告 1、思路分析 操作二显然很划算的,但是操作2有代价,为了更划算,我们要让操作2的操作次数最少 即,操作二尽可能用在…

Apollo docker-compose

来源 https://www.apolloconfig.com/#/zh/deployment/quick-start-docker 路径 /usr/apollo Sql 自己复制 Vim docker-compose.yml #如果安装过了 记得删除mysql 历史文件 rm -r /var/lib/mysql version: 2.1services:apollo-quick-start:image: nobodyiam/apollo-quick…

MongoDB教程(六):mongoDB复制副本集

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、MongoD…

React 速通笔记

前言 最近刚学完 React,想着把笔记分享给大家,本笔记特别适合从事后端想要学习前端的人。我看视频是黑马最新的 React 视频(黑马程序员前端React18入门到实战视频教程,从reacthooks核心基础到企业级项目开发实战(B站评…

Windows 2012安装之实现远程连接

新建虚拟机 点击稍后安装操作系统 点击Microsoft Windows(W) 选择Windows Server 2012 设置虚拟机名称、安装位置 选择你的电脑核数 点击编辑虚拟机设置 点击CD/DVD(SATA) 使用ISO映像文件(M) 配置完之后点击确定 然后开启虚拟机 下一步: 点击现在安装&#xff1a…

51单片机(STC8H8K64U/STC8051U34K64)_RA8889驱动大屏_硬件SPI4_参考代码(v1.3)

单片机实际不限,这里采用的STC最新、主推的型号,比如STC8H8K64U、STC8051U34K64进行实验测试,您可以换用不同型号。目前测试这两个系列,显示速度均相当不错,软件设计也是极为简单。各篇文章下方均提供源码供参考下载。…

Java 反射用法和8道练习题

目录 一、什么是反射二、反射的核心接口和类三、测试代码 Bean 类和目录结构Person 类代码目录结构 四、获取 Class 对象五、获取构造方法 Constructor 并使用六、获取成员变量 Field 并使用七、获取成员方法 Method 并使用八、练习1. 使用反射获取String类的所有公有方法&…

在python里构建你的投资组合portfolio--最好用的pandas零基础

有人可能觉得软件数据分析门槛很高,自学也坚持不下来, 其实分解成一个小的功能和任务,对零基础自学者非常有帮助。 今天用python中最好用的数据分析包pandas为例: 用最简单的代码完成全流程 构建投资组合 → 获取数据 → 进行分…