全连接层
全连接层底层是如何实现的
转换成矩阵和相乘的乘法, 然后利用 CUBLAS 或者 OpenBLAS 进行运算.
卷积层
简述 1x1 卷积层的作用
卷积操作的本质特性包括稀疏交互和参数共享, 具体解释这两种特性及其作用
卷积层底层是如何实现的
一种比较方便也是比较偷懒的卷积层实现方法都是将图片或者特征图谱利用 im2col 方法展开成矩阵, 将卷积操作变成普通的矩阵乘法, 然后利用 cuBLAS 或者 OpenBLAS 的库函数进行计算. 具体来说, 对于任意的输入图谱, 根据卷积核的大小在特征图谱上获得一个 patch, 将这个 patch 里面的元素拿出来变成矩阵的一列, 按照卷积操作, 取出所有的 path 组成一个新的矩阵. 然后将卷积核展开成一个矩阵, 矩阵的每一行都是卷积核中的元素, 总共的行数和输出图谱的通道数相关. 这样, 卷积的计算操作就变成了普通的矩阵乘法.
这里可以看出, 对于卷积核大于 1 的卷积层来说, 我们需要按照卷积核的大小对图谱重新进行排列. 但是, 当卷积核大小为 1 时, 我们就无需排列, 直接将其展开即可. 这也解释了 MobileNet 中提到的 $1\times 1$ 卷积在实现上执行速度很快的原因.
im2col+GEMM 的卷积实现方法有一个很明显的问题就是, 会存储大量的冗余元素, 使得内存消耗比较大.
当然, 随着新的算法出现, 卷积层对3*3的卷积核有专门的算法.
其他计算卷积的方法:
- FFT: 大卷积核时使用, 时域卷积等于频域相乘, 因此可以将问题转化成简单的乘法问题. cuFFT
- Winograd: 据说在 GPU 上效率更高, 貌似是针对 $2\times2$ 和 $3\times 3$ 的卷积核专门使用的?
- NNPACK: FFT 和 Winograd 方法的结合
- MEC(17年): 一种内存利用率高且速度较快的卷积计算方法, http://cn.arxiv.org/pdf/1706.06873v1. 主要改进了 im2col+GEMM 的策略, 目的主要是减少内存消耗的同时顺便提升速度. 由于同样可以利用现有的矩阵运算库, 因此算法的实现难度并不大.
CNN 基础之卷积及其矩阵加速 http://shuokay.com/2016/06/08/convolution
Winograd 方法快速计算卷积 http://shuokay.com/2018/02/21/winograd/
https://blog.csdn.net/antkillerfarm/article/details/78829889
https://blog.csdn.net/xiaoxiaowenqiang/article/details/82050354
BLAS 接受, 矩阵乘法优化 https://www.leiphone.com/news/201704/Puevv3ZWxn0heoEv.html
im2col 讲解: https://blog.csdn.net/Mrhiuser/article/details/52672824
简述矩阵乘法的优化方法
BLAS: Basic Linear Algebra Subprograms. 分为三级:
- BLAS 1级: 向量与向量之间的点乘或者乘加运算, 元素运算;
- BLAS 2级: 向量与矩阵的运算, 矩阵变形;
- BLAS 3级: 矩阵与矩阵的运算;