网站首页 > 技术文章 正文
全连接层是神经网络大内存占用的主要原因,但是速度很快,而卷积虽然参数数量紧凑,但却消耗了大部分计算能力。事实上,卷积计算器非常昂贵,所以它们是我们需要这么多计算能力来训练和运行最先进的神经网络的主要原因。
有一些方法可以加速卷积,而不会严重降低模型的准确性。
卷积的核分解(Factorization/Decomposition of convolution’s kernels)
瓶颈层(Bottleneck Layers)
更宽的卷积(Wider Convolutions)
深度可分卷积(Depthwise Separable Convolutions)
简单分解
我们从NumPy中的以下示例开始
>>> from numpy.random import random
>>> random((3, 3)).shape == (random((3, 1)) * random((1, 3))).shape
>>> True
你可能会问,为什么我会向你展示这个愚蠢的片段?那么答案就是,它表明你可以写一个N×N矩阵,将卷积核看作是2个较小的矩阵/内核的乘积,其形状为Nx1和1xN。回想一下,卷积操作需要in_channels * n * n * out_channels 参数或权重。此外,请记住,每个权重/参数都需要激活。所以,减少参数的数量将减少所需的操作次数和计算成本。
考虑到卷积运算实际上是用张量乘法完成的,而张量乘法是多项式依赖于张量的大小,正确应用的因式分解应该产生有形的加速。
Keras看起来像这样:
# k - kernel size, for example 3, 5, 7...
# n_filters - number of filters/channels
# Note that you shouldn't apply any activation
# or normalization between these 2 layers
fact_conv1 = Conv(n_filters, (1, k))(inp)
fact_conv1 = Conv(n_filters, (k, 1))(fact_conv1)
不过,请注意,不建议将最接近输入卷积层的因素考虑在内。此外,分解3x3的卷积甚至会破坏网络的性能。最好将它们保存在更大的内核中。
在我们深入探讨这个话题之前,有一种更稳定的方式来分解大内核:代之以将更小的内核堆叠起来。例如,不是使用5x5卷积,而是使用两个3x3卷积,或者如果要替换7x7内核,则使用3个。
瓶颈层
瓶颈层背后的主要思想是通过减少输入通道的数量(也就是输入张量的深度)来减小内核大于1x1的卷积层中输入张量的大小。
这是它的Keras代码:
从keras.layers导入Conv2D
from keras.layers import Conv2D
# given that conv1 has shape (None, N, N, 128)
conv2 = Conv2D(96, (1, 1), ...)(conv1) # squeeze
conv3 = Conv2D(96, (3, 3), ...)(conv2) # map
conv4 = Conv2D(128, (1, 1), ...)(conv3) # expand
几乎所有的CNN,从革命性的InceptionV1到现代的DenseNet,都以不同的方式使用瓶颈层。这种技术有助于保持参数的数量,从而降低计算成本。
更宽的卷积
加速卷积的另一个简单方法是所谓的宽卷积层。你看,你的模型有越多的卷积层,它会变得越慢。然而,你需要大量卷积的表现力。你做什么?您使用的是less-but-fatter层,其中fat意味着每层更多的内核。它为什么有效?因为GPU或其他大规模并行机器对于处理单个大块数据而不是很多小数据很容易。
# convert from
conv = Conv2D(96, (3, 3), ...)(conv)
conv = Conv2D(96, (3, 3), ...)(conv)
# to
conv = Conv2D(128, (3, 3), ...)(conv)
# roughly, take the sqrt of the number of layers you want
# to merge and multipy the number to
# the number of filters/channels in the initial convolutions
# to get the number of filters/channels in the new layer
深度可分卷积
在深入研究这种方法之前,请注意,它非常依赖于在给定框架中实现的可分离卷积。就我而言,TensorFlow可能会对此方法进行一些特定的优化,而对于其他后端,如Caffe,CNTK或PyTorch,则尚不清楚。
这个想法是,不是在图像的所有通道上共同进行卷积运算,而是在每个通道上以深度运行单独的2D卷积channel_multiplier。in_channels * channel_multiplier中间通道得到串接在一起,并映射到out_channels使用1x1卷积。 这样一来,训练的参数就会显着减少。
# in Keras
from keras.layers import SeparableConv2D
...
net = SeparableConv2D(32, (3, 3))(net)
...
# it's almost 1:1 similar to the simple Keras Conv2D layer
请注意,可分离的卷积有时不会受到训练。在这种情况下,请将深度乘数从1修改为4或8.还要注意,这些对于小型数据集(如CIFAR 10,而且在MNIST上)并不那么有效。另外要记住的是,不要在网络的早期阶段使用可分离的卷积。
CP分解和高级方法
上面显示的分解方案在实践中运行良好,但相当简单。有许多作品,其中包括V. Lebedev等的作品。它们向我们展示了不同的张量分解方案,这大大减少了参数的数量,从而减少了所需的计算次数。
下面是如何在Keras中进行CP分解的代码片段:
# **kwargs - anything valid for Keras layers,
# like regularization, or activation function
# Though, add at your own risk
# Take a look into how ExpandDimension and SqueezeDimension
# are implemented in the associated Colab Notebook
# at the end of the article
first = Conv2D(rank, kernel_size=(1, 1), **kwargs)(inp)
expanded = ExpandDimension(axis=1)(first)
mid1 = Conv3D(rank, kernel_size=(d, 1, 1), **kwargs)(exapanded)
mid2 = Conv3D(rank, kernel_size=(1, d, 1), **kwargs)(mid1)
squeezed = SqueezeDimension(axis=1)(mid2)
last = Conv2D(out, kernel_size=(1, 1), **kwargs)(squeezed)
应该注意TensorTrain分解和Tucker等方案。对于PyTorch和NumPy,有一个名为Tensorly的伟大库,可为您执行所有低级别实现。
猜你喜欢
- 2024-09-27 深兰科技|目标检测二十年间那些事儿——加速与优化
- 2024-09-27 深度学习中GPU和显存分析 深度学习内存与显存多大合适
- 2024-09-27 发掘 ARM GPU 的全部深度学习性能,TVM 优化带来高达2倍性能提升
- 2024-09-27 关于“卷积层”你真正了解多少?? 卷积层的原理
- 2024-09-27 计算机视觉面试复习笔记:深度学习基础-神经网络
- 2024-09-27 CVPR 2019:中科院、牛津等提出SiamMask网络,视频跟踪最高精度
- 2024-09-27 目标跟踪最强算法开源:商汤SiamRPN系列解读
- 2024-09-27 寻找最佳的神经网络架构,韩松组两篇论文解读
- 2024-09-27 美团提出基于隐式条件位置编码,性能优于ViT和DeiT
- 2024-09-27 【综述】神经网络中不同类型的卷积层
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)