为什么GEMM是深度学习的核心

前言: 

在之前写的一篇计算机视觉入门路线文章中,我推荐大家在不用任何框架、只使用numpy这种包的情况下,从零实现一个卷积神经网络。其中一个很重要的因素就是在这个过程中大家会了解到卷积过程在底层中是如何优化实现的,其主流的方法就是GEMM。这篇博客比较细致地介绍了什么是GEMM,以及它的优缺点。

我大部分时间都在考虑如何让神经网络的深度学习更快、更高效。在实践中,这意味着要关注一个名为GEMM的函数。它是1979年首次创建的BLAS(基本线性代数子程序)库的一部分,直到我开始尝试优化神经网络之前,我从未听说过它。为了解释为什么它如此重要,这是我朋友杨庆嘉论文的图表

所有以fc(完全连接)或卷积)开头的层都使用GEMM实现,几乎所有时间(95%的GPU版本,89%的CPU)都花在这些层上。

那么什么是GEMM呢?它代表全局矩阵到矩阵的乘法,它本质上完全按照它在tins上所说的那样,将两个输入矩阵乘法在一起,得到一个输出矩阵。它和我在三维图形世界中使用的矩阵操作类型之间的区别在于,它所工作的矩阵通常非常大。

例如,典型网络中的单个层可能需要将256行、1152列矩阵乘以1152行、192列矩阵,以产生256行、192列的结果。天真地说,这需要5700万层(256x1152x192)浮点操作,在现代架构中可以有几十个这样的层,所以我经常看到网络需要几十亿FLOP来计算一帧。下面是我绘制的一个关系图,以帮助我可视化它的工作原理:

关注公众号CV技术指南,及时获取更多计算机视觉的内容。

 

完全连接的图层

全连接层是已经存在了几十年的经典神经网络,并且可以最简单地从如何使用GEMM开始。FC层的每个输出值查看输入层中的每个值,将它们全部乘以该输入索引的相应权重,并将结果相加以得到其输出。根据上图的说明,具体情况如下:

 

有“k”输入值,也有“n”神经元,每个输入值都有自己的学习权值集。有“n”输出值,每个神经元都有一个输出值,通过做其权值和输入值的点积来计算。

 

 

卷积图层

使用GEMM进行卷积层并不是一个明显的选择。卷积层将其输入视为二维图像,每个像素都有多个通道,很像具有宽度、高度和深度的经典图像。与我习惯处理的图像不同,通道的数量可以是数百个,而不仅仅是RGB或RGBA!

卷积操作通过获取一些“核”的权重来产生其输出。并在图像中应用它们。下面是输入映像和单个内核的外观:

 

每个卷积核都是一个三维数组,其深度与输入图像相同,但其宽度和高度要小得多,通常就像7×7一样。为了产生结果,卷积核将应用到输入图像的点网格。在应用它的每个点,所有相应的输入值和权重相乘,然后在该点相加产生单个输出值。以下是视觉效果:

 

您可以将这个操作看作是一个边缘检测器。卷积核包含一个权重模式,并且当它所查看的输入图像的部分具有类似的模式时,它会输出一个高值。当输入与模式不匹配时,结果是该位置的数较低。以下是一些典型的模式,它们是由网络的第一层学习的。

因为第一层的输入是RGB图像,所有这些核也可以可视化为RGB,它们显示网络正在寻找的原始模式。这些96个内核中的每一个在输入上以网格模式应用,结果是一系列96个二维数组,它们被视为具有96个通道深度的输出图像。如果您习惯了像Sobel操作符这样的图像处理操作,您可以想象它们都有点像针对图像中不同重要模式优化的边缘检测器,因此每个通道都是输入中这些模式发生位置的映射。

您可能已经注意到,我对内核应用的网格类型很模糊。它的关键控制因素是一个称为“步幅”的参数,它定义了内核应用程序之间的间距。例如,随着步幅为1,256×256输入图像将在每个像素处应用一个内核,并且输出将是与输入图像相同的宽度和高度。只要迈出4步,相同的输入图像就只能每四个像素应用一次内核,因此输出将只有64×64。典型的步幅值小于内核的大小,这意味着在可视化内核应用程序的图表中,其中很多值实际上会在边缘重叠。

 

GEMM如何处理卷积解决方案

这似乎是一个相当专门的操作。它涉及大量的乘法和求和,比如完全连接层,但不清楚如何或为什么要将其变成GEMM的矩阵乘法。最后我将讨论动机,但这个操作是如何用矩阵乘法表示的

第一步是将来自一个实际上是一个三维数组的图像的输入变成一个二维数组,我们可以像一个矩阵一样处理。应用每个内核的地方是图像中的一个小三维多维方体,因此我们提取每个输入值的多维方体,并将它们作为一列复制到一个矩阵中。这被称为im2col,对于图像到列,我相信从一个原始的Matlab函数,下面是我如何可视化它的:

如果步幅小于内核大小,你可能会对我们进行此转换时发生的内存大小的扩展感到震惊。这意味着包含在重叠核站点中的像素将在矩阵中被复制,这看起来效率低下,但实际上利大于弊。

现在您有了矩阵形式的输入图像,您可以对每个内核的权重执行同样的操作,将三维多维数据集序列化为行,作为乘法的第二个矩阵。以下是最终的GEMM的外观:

这里的“k”是每个补丁和内核中的值数,因此它是内核宽度*内核高度”深度。结果矩阵是“patches数”列高,按“kernels数”行宽计算。这个矩阵实际上被随后的操作视为一个三维数组,以内核维数作为深度,然后根据它们在输入图像中的原始位置将斑块分割回行和列。

 

为什么GEMM适用于卷积

希望您现在可以看到如何将卷积层表示为矩阵乘法,但仍然不清楚您为什么要这么做。简而言之,答案是,科学程序员的格式世界已经花了几十年时间优化代码来执行大矩阵到矩阵乘法,而非常规则的内存访问模式的好处超过了浪费的存储成本。这篇来自Nvidia的论文(文末附下载方式)很好地介绍了一些不同的方法,但他们也描述了为什么他们最终以一个修改版本的GEMM作为他们最喜欢的方法。同时对相同的内核批处理大量输入图像还有很多优点,本文关于《Caffe con troll》的论文(文末附下载方式)使用了非常好的效果。GEMM方法的主要竞争对手是使用傅里叶变换在频率空间中进行操作,但在卷积中使用步进使其难以如此有效。

好消息是,拥有一个单一的、被充分理解的算法(即GEMM)占据了我们的大部分时间,这为优化速度和功率的使用提供了一条非常清晰的路径,无论是通过更好的软件实现,还是通过定制硬件来很好地运行操作。因为深度网络已被证明对跨语音、NLP和计算机视觉的大量应用程序有用,所以我期待看到未来几年的巨大改进,就像对3D游戏的广泛需求通过迫使顶点和像素处理操作的革命,推动了GPU的革命。

 

论文:cuDNN: Efficient Primitives for Deep Learning

地址:https://arxiv.org/pdf/1410.0759.pdf

论文:Caffe con Troll: Shallow Ideas to Speed Up Deep Learning

地址:https://arxiv.org/pdf/1504.04343v1.pdf

获取方式:公众号中回复“0002”可获取

 

原文链接:

https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/

 

本文来源于公众号 CV技术指南 的论文分享系列。

欢迎关注公众号 CV技术指南 ,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读。

在公众号中回复关键字 “技术总结” 可获取以下文章的汇总pdf。

 

其它文章

使用深度神经网络为什么8位足够?

经典论文系列 | 目标检测--CornerNet & 又名 anchor boxes的缺陷

如何看待人工智能的泡沫

使用Dice loss实现清晰的边界检测

PVT--无卷积密集预测的多功能backbone

CVPR2021 | 开放世界的目标检测

Siamese network总结

视觉目标检测和识别之过去,现在及可能

在做算法工程师的道路上,你掌握了什么概念或技术使你感觉自我提升突飞猛进?

计算机视觉专业术语总结(一)构建计算机视觉的知识体系

欠拟合与过拟合技术总结

归一化方法总结

论文创新的常见思路总结

CV方向的高效阅读英文文献方法总结

计算机视觉中的小样本学习综述   

知识蒸馏的简要概述   

优化OpenCV视频的读取速度

NMS总结   

损失函数技术总结

注意力机制技术总结   

特征金字塔技术总结   

池化技术总结

数据增强方法总结   

CNN结构演变总结(一)经典模型

CNN结构演变总结(二)轻量化模型 

CNN结构演变总结(三)设计原则

如何看待计算机视觉未来的走向   

CNN可视化技术总结(一)特征图可视化

CNN可视化技术总结(二)卷积核可视化

CNN可视化技术总结(三)类可视化

CNN可视化技术总结(四)可视化工具与项目

posted @ 2021-07-17 14:55  CV技术指南(公众号)  阅读(704)  评论(0编辑  收藏  举报