卷积神经网络的复杂度分析

作者 | Michael Yuan@知乎(已授权)
来源 | https://zhuanlan.zhihu.com/p/31575074

编辑丨极市平台

导读

 

在梳理CNN经典模型的过程中,作者理解到其实经典模型演进中的很多创新点都与改善模型计算复杂度紧密相关,因此今天就让我们对卷积神经网络的复杂度分析简单总结一下。 

在梳理CNN经典模型的过程中,我理解到其实经典模型演进中的很多创新点都与改善模型计算复杂度紧密相关,因此今天就让我们对卷积神经网络的复杂度分析简单总结一下下。

时间复杂度

即模型的运算次数,可用468b3d36603d632928ebdd3c64df9558.png衡量,也就是浮点运算次数(FLoating-point OPerations)。

1.1 单个卷积层的时间复杂度
  • outside_default.png每个卷积核输出特征图 outside_default.png 的边长

  • outside_default.png每个卷积核 outside_default.png的边长

  • outside_default.png每个卷积核的通道数,也即输入通道数,也即上一层的输出通道数。

  • c7bdd8001df50330c140feead288a9c2.png本卷积层具有的卷积核个数,也即输出通道数。

  • 可见,每个卷积层的时间复杂度由输出特征图面积 70eef85701538940685777252ccbfb19.png、卷积核面b1b1c62c0a7cedb7cca5b2441e5252b1.png、输入b26d762fb1f93ce7ce83710cba1302a3.png 和输出通道数8ea7f604d3781e1233fc0aaa592427af.png完全决定。

  • 其中,输出特征图尺寸本身又由输入矩阵尺寸182d628a1caf43a3ac06c60e5e0cb5e2.png 、卷积核尺寸outside_default.png 、f877f0a2554143fb4c6e4e9e673679a4.png这四个参数所决定,表示如下:

d2dbdcb9442ccf49c20805ae3baa867c.png

  • 注1:为了简化表达式中的变量个数,这里统一假设输入和卷积核的形状都是正方形。

  • 注2:严格来讲每层应该还包含 1 个 51cb7ed1bdd980377635c62299e919f0.png参数,这里为了简洁就省略了。

1.2 卷积神经网络整体的时间复杂度

dde091d6f96941b39d0a014f48dff505.png

  • 902bdcc28072c23ee853a78e2b8af1a5.png神经网络所具有的卷积层数,也即网络的深度。

  • 91dbd4eea25cbd95d50a65ec2816256a.png神经网络第c0d7caae9a9d6d371e866be8ddc5b4c0.png个卷积层

  •  9cc18c99e9159d7d0914f09ce7590ecf.png神经网络第1ed7135ea6b3bea8b842bcba6f593c2f.png个卷积层的输出通道数9bb7f1c891ab316f7546175865df8759.png,也即该层的卷积核个数。

  • 对于第d4bdf971cf5d426874a71f1a8a1697e8.png个卷积层而言,其输入通道数501cfad482899192bb19e98f0a17ca8f.png就是第4f70b723b0e248ae36c0138bbc5d21d7.png个卷积层的输出通道数。

  • 可见,CNN整体的时间复杂度并不神秘,只是所有卷积层的时间复杂度累加而已。

  • 简而言之,层内连乘,层间累加。

示例:用 Numpy 手动简单实现二维卷积

假设 Stride = 1, Padding = 0, img 和 kernel 都是 np.ndarray.

def conv2d(img, kernel):
    height, width, in_channels = img.shape
    kernel_height, kernel_width, in_channels, out_channels = kernel.shape
    out_height = height - kernel_height + 1
    out_width = width - kernel_width + 1
    feature_maps = np.zeros(shape=(out_height, out_width, out_channels))
    for oc in range(out_channels):              # Iterate out_channels (# of kernels)
        for h in range(out_height):             # Iterate out_height
            for w in range(out_width):          # Iterate out_width
                for ic in range(in_channels):   # Iterate in_channels
                    patch = img[h: h + kernel_height, w: w + kernel_width, ic]
                    feature_maps[h, w, oc] += np.sum(patch * kernel[:, :, ic, oc])

    return feature_maps



空间复杂度

空间复杂度(访存量),严格来讲包括两部分:总参数量 + 各层输出特征图。

  • 参数量:模型所有带参数的层的权重参数总量(即模型体积,下式第一个求和表达式)

  • 特征图:模型在实时运行过程中每层所计算出的输出特征图大小(下式第二个求和表达式)

outside_default.png

  • 总参数量只与卷积核的尺寸 6acb9a016de2a0ea600ac6dc0beb64f6.png、通道数4263d1d8da404c000c0273474c12f69f.png、层数df15bed611e034994544fee7ac3a73f5.png相关,而与输入数据的大小无关。

  • 输出特征图的空间占用比较容易,就是其空间尺寸6a845a3d5b05aabc6fcc80e226914492.png和通道数b056899368db99a85fab7d19e01cb002.png的连乘。

  • 注:实际上有些层(例如 ReLU)其实是可以通过原位运算完成的,此时就不用统计输出特征图这一项了。



复杂度对模型的影响


  • 时间复杂度决定了模型的训练/预测时间。如果复杂度过高,则会导致模型训练和预测耗费大量时间,既无法快速的验证想法和改善模型,也无法做到快速的预测。

  • 空间复杂度决定了模型的参数数量。由于维度诅咒的限制,模型的参数越多,训练模型所需的数据量就越大,而现实生活中的数据集通常不会太大,这会导致模型的训练更容易过拟合。

  • 当我们需要裁剪模型时,由于卷积核的空间尺寸通常已经很小(3x3),而网络的深度又与模型的表征能力紧密相关,不宜过多削减,因此模型裁剪通常最先下手的地方就是通道数。



Inception 系列模型是如何优化复杂度的

通过五个小例子说明模型的演进过程中是如何优化复杂度的。

4.1  a59c1399149b9da1e8936a5e189922bc.png 中的 1f844207a8e47db65811152578139bf4.png 卷积降维同时优化时间复杂度和空间复杂度
c0c24a05f852cdc1d6717ae98966e3ec.png
(图像被压缩的惨不忍睹...)
  • InceptionV1 借鉴了 Network in Network 的思想,在一个 Inception Module 中构造了四个并行的不同尺寸的卷积/池化模块(上图左),有效的提升了网络的宽度。但是这么做也造成了网络的时间和空间复杂度的激增。对策就是添加 1 x 1 卷积(上图右红色模块)将输入通道数先降到一个较低的值,再进行真正的卷积。

  • 以 InceptionV1 论文中的 (3b) 模块为例(可以点击上图看超级精美的大图),输入尺寸为6ad5eccf9bbedf2866a28e9ce449a8cb.png, 2c79aad6581667b0c121041a437b96d7.png卷积核 outside_default.png 个,0a3fbd8d16c57f67a3254638be0f99da.png卷积核 outside_default.png 个,d446789d1c6042a40e9ba6038b818b56.png卷积核 outside_default.png 个,卷积核一律采用 Same Padding 确保输出不改变尺寸。

  • 99b91d99655aff9a1f8d6b39bf885a70.png卷积分支上加入387ade84fb79dd730ceb7e3db7ea289a.png50ab440bf4cdb6f3014bdd913ce44bcf.png卷积前后的时间复杂度对比如下式:

    f65da95d5f0f528e69a55867fc0aa65d.png

  • 同理,在92d196e817fcaf0c4e7e4e1c560c2ba9.png卷积分支上加入c957d625626cc42847266481ffd878d9.pngc29165293724fa11c52313f4fa345d64.png卷积前后的时间复杂度对比如下式:

     19d33dc943b3086ce182c0227f42b229.png

  • 可见,使用916b8d541d83dc8322c6cff62d7a8b42.png卷积降维可以降低时间复杂度3倍以上。该层完整的运算量可以在论文中查到,为 300 M,即7a12e09d45e518b45b886648d8237276.png

  • 另一方面,我们同样可以简单分析一下这一层参数量在使用 1 x 1 卷积前后的变化。可以看到,由于 1 x 1 卷积的添加,3 x 3 和 5 x 5 卷积核的参数量得以降低 4 倍,因此本层的参数量从 1000 K 降低到 300 K 左右。

4a2a9f2ebde1086ba5d39cbe385ce2f6.png

4.2  bb99a6d1f8e115c93caa92c206abcadf.png 中使用  4dc59a605649ab9d4a5e64b85111dd75.png  代替 4e117fb4d3fdad79006955a72d88c87a.png
  • 全连接层可以视为一种特殊的卷积层,其卷积核尺寸 outside_default.png 与输入矩阵尺寸 一模一样。每个卷积核的输出特征图是一个标量点,即 。复杂度分析如下:

    9953944eee83596a8196a6d873424ec4.png

  • 可见,与真正的卷积层不同,全连接层的空间复杂度与输入数据的尺寸密切相关。因此如果输入图像尺寸越大,模型的体积也就会越大,这显然是不可接受的。例如早期的VGG系列模型,其 90% 的参数都耗费在全连接层上。

  • InceptionV1 中使用的全局平均池化 GAP 改善了这个问题。由于每个卷积核输出的特征图在经过全局平均池化后都会直接精炼成一个标量点,因此全连接层的复杂度不再与输入图像尺寸有关,运算量和参数数量都得以大规模削减。复杂度分析如下:

    f569f9812ac24f334173e133dd693719.png

4.3  5e9a71b7023ddacc42ffbef80675bf64.png 中使用两个 6ed3dd4cf2d6e4a5c790ca880927ca8c.png 卷积级联替代 90a1d91c8b4929b0f9c997e74fbd7818.png 卷积分支
a99859006e20a26a5f7f92fe9c44957c.png
感受野不变
  • 根据上面提到的二维卷积输入输出尺寸关系公式,可知:对于同一个输入尺寸,单个2cd11375b589797a8b1786b0303815f3.png卷积的输出与两个7b666f5fb3a96b0ead4f477debb3ed34.png卷积级联输出的尺寸完全一样,即感受野相同。

  • 同样根据上面提到的复杂度分析公式,可知:这种替换能够非常有效的降低时间和空间复杂度。我们可以把辛辛苦苦省出来的这些复杂度用来提升模型的深度和宽度,使得我们的模型能够在复杂度不变的前提下,具有更大的容量,爽爽的。

  • 同样以 InceptionV1 里的 (3b) 模块为例,替换前后的ed77c42f136aa4d7ecb6b95c84de22e5.png卷积分支复杂度如下:

    d595bb8c382c98e89cb4f0a2021e8f90.png

4.4  efe26c1096a17d4be9266cae8115b8a2.png 中使用 outside_default.png 与 06105969e926eea129d9f30ae73a097d.png 卷积级联替代  82a81878792927bb7830cf9bcd2e71e3.png 卷积
5d1766cd06c43ec67e9abeddb53677e3.png
  • InceptionV3 中提出了卷积的 Factorization,在确保感受野不变的前提下进一步简化。

  • 复杂度的改善同理可得,不再赘述。

4.5  37c9d345342686d019ea24fa7e317e6d.png 中使用 outside_default.png
9e11d112cb0484503418df604c08f0cf.png
  • 我们之前讨论的都是标准卷积运算,每个卷积核都对输入的所有通道进行卷积。

  • Xception 模型挑战了这个思维定势,它让每个卷积核只负责输入的某一个通道,这就是所谓的 Depth-wise Separable Convolution。

  • 从输入通道的视角看,标准卷积中每个输入通道都会被所有卷积核蹂躏一遍,而 Xception 中每个输入通道只会被对应的一个卷积核扫描,降低了模型的冗余度。

  • 标准卷积与可分离卷积的时间复杂度对比:可以看到本质上是把连乘转化成为相加。

    ff677aecbf0a97e75acdd5b2e6ffc0a6.png



总结

通过上面的推导和经典模型的案例分析,我们可以清楚的看到其实很多创新点都是围绕模型复杂度的优化展开的,其基本逻辑就是乘变加。模型的优化换来了更少的运算次数和更少的参数数量,一方面促使我们能够构建更轻更快的模型(例如MobileNet),一方面促使我们能够构建更深更宽的网络(例如Xception),提升模型的容量,打败各种大怪兽,欧耶~

6b01d982da7b09b09d997fcade1c6057.png 参考论文
  • https://arxiv.org/abs/1412.1710

  • https://arxiv.org/abs/1409.4842

  • https://arxiv.org/abs/1502.03167

  • https://arxiv.org/abs/1512.00567

  • https://arxiv.org/abs/1610.0235

本文仅做学术分享,如有侵权,请联系删文。

重磅!计算机视觉工坊-学习交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有ORB-SLAM系列源码学习、3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、深度估计、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

21aec1459bc7f5b0183ce8756566ea49.png

▲长按加微信群或投稿

7a4840c8d5dccc9a1533b77c0a09f6e5.png

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定、激光/视觉SLAM、自动驾驶等)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近4000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

bda76b9e1d6e5d185145aa7174e91388.png

 圈里有高质量教程资料、可答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值