调整Network的架构设计(Architecture Design),让它变得只需要比较少的参数,这是在实际操作中最有效的做法。
Low Rank Approximation
如果是Fully Connected Network,前一层和后一层分别有N、M个neuron则需要(N imes M)个参数,我们可以在这两层中间加一个有K个neuron的层(不要激活函数)就需要(K(N+M))个neuron,这样就可以减少参数量,但是根据线性代数的知识可知这3层的性能不一定比之前的2层好。
Depthwise & Pointwise Convolution
在普通卷积中,每个filter(卷积核)要处理输入的所有channel。假设输入有(I)个channel,有(O)个尺寸为(k imes k)的filter,则需要((k imes k imes I) imes O)个参数、输出(O)个channel。
深度可分离卷积(Depthwise Separable Convolution)又称为Depthwise&Pointwise Convolution,分为以下2步,共需要(k imes k imes I+I imes O)个参数、输出(O)个channel。
-
Depthwise Convolution
在这一步中,filter的数量等于输入channel的数量,即每个filter只处理一个channel,这步的作用就是修改输入的尺寸。
假设输入有(I)个channel,因此就有(I)个filter;假设每个filter的尺寸为(k imes k),则需要((k imes k imes1) imes I)个参数、输出(I)个channel。
-
Pointwise Convolution
在这一步中,以上一步(Depthwise Convolution)的输出作为输入,每个filter的尺寸必须为(1 imes 1),和普通卷积核一样要处理输入的所有channel,这步的作用就是修改输入的通道数。
假设有(O)个filter,则需要((1 imes1 imes I) imes O)个参数、输出(O)个channel。
Group Convolution
Group Convolution就是把输入的多个channel分成多个group,对每个group分别进行一次或多次普通卷积。Group Convolution算是普通卷积和Depthwise Convolution的折衷,当group数量和输入的通道数相同时它就相当于Depthwise Convolution,当group数量为1时它就相当于普通卷积。
不同卷积的PyTorch实现
# 普通卷积, weight数量 = in_chs * out_chs * kernel_size^2
nn.Conv2d(in_chs, out_chs, kernel_size, stride, padding)
# Group Convolution, Group数量可以自行控制,表示要分成几个group,其中in_chs和out_chs必须可以被groups整除
nn.Conv2d(in_chs, out_chs, kernel_size, stride, padding, groups=groups)
# Depthwise Convolution, 输入通道数=输出通道数=group数量, weight数量 = in_chs * kernel_size^2
nn.Conv2d(in_chs, out_chs=in_chs, kernel_size, stride, padding, groups=in_chs)
# Pointwise Convolution, 也就是1×1卷积, weight数量 = in_chs * out_chs
nn.Conv2d(in_chs, out_chs, 1)
Application
Depthwise Separable Convolution被广泛地用在各种小型网络中:SqueezeNet、MobileNet、ShuffleNet、Xception,其中最知名的为MobileNet。
Github(github.com):@chouxianyu
Github Pages(github.io):@臭咸鱼
知乎(zhihu.com):@臭咸鱼
博客园(cnblogs.com):@臭咸鱼
B站(bilibili.com):@绝版臭咸鱼
微信公众号:@臭咸鱼
转载请注明出处,欢迎讨论和交流!