深度可分離卷積

深度可分離卷積 - 在Caffe框架中?

Google AI團隊開發了MobileNet CNN架構,與VGG Net等知名架構相比,它具有更高的準確性和更少的MAC。

MobileNet背後的關鍵思想是在inpur層使用Depthwise Convolution,然後使用1x1 Pointwise Convolution。該方法提供與普通卷積層相同的輸出維度,但具有較少的參數和MAC。它也被稱為Depthwise Separable Convolution。

以下圖像將解釋這3種類型的卷積:

深度可分離卷積

正常卷積( image_source )在Normal Convolution中

正常卷積( image_source Normal Convolution中,如果輸入是3x3x3(RGB圖像,高度和寬度等於3),卷積濾波器也是3x3

參數總數(濾波器係數)為3x3x n_ch = 27(假設沒有偏差)

如果只有一個這樣的卷積濾波器,它將通過將27個濾波器係數乘以27個像素值並且總計全部來生成僅1個像素輸出。

深度可分離卷積

深度卷積( image_source )在Depthwise Convolution中

深度卷積( image_source Depthwise Convolution中,參數的數量(濾波器係數)將等於3x3x3 = 27

該卷積濾波器將計算每個輸入通道的輸出。

在給定的例子中,我們將從深度卷積得到3個像素輸出,因為輸入通道的數量是3。

深度可分離卷積

逐 點卷積(image_source)在Pointwise Convolution中

點卷積(image_source)在Pointwise Convolution中,參數數量為1x n_ch = 3

將Depthwise Convolution的輸出饋送到Pointwise Convolution,以獲得類似於Normal Convolution的單像素輸出。

如何在Caffe中獲得深度可分離卷積?

在caffe框架中,我們可以使用普通卷積層作為深度卷積層,通過指定組的數量等於輸入通道的數量。

test_dw_pw_conv.prototxt: -

input: "data"
input_shape {
dim: 1
dim: 3
dim: 3
dim: 3
}
layer {
name: "conv1/dw"
type: "Convolution"
bottom: "data"
top: "conv1/dw"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {

num_output: 3
bias_term: false
pad: 0
kernel_size: 3
group: 3
weight_filler {
type: "msra"
}
}
}
layer {
name: "conv1/pw"
type: "Convolution"
bottom: "conv1/dw"
top: "conv1/pw"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {
num_output: 10
bias_term: false
pad: 0
kernel_size: 1
weight_filler {
type: "msra"
}
}
}

示例Python代碼:

import sys, caffe
from functools import reduce
import numpy as np
net = caffe.Net('test_dw_pw_conv.prototxt',caffe.TEST)
dw_conv_parameters = reduce(lambda x, y:y*x, net.params['conv1/dw'][0].data.shape)
pw_conv_parameters = reduce(lambda x, y:y*x, net.params['conv1/pw'][0].data.shape)
dw_conv_outputs = reduce(lambda x, y:y*x, net.blobs['conv1/dw'].data.shape)
pw_conv_outputs = reduce(lambda x, y:y*x, net.blobs['conv1/pw'].data.shape)
print('conv1/dw num param: ', dw_conv_parameters)
print('conv1/dw output shape: ',net.blobs['conv1/dw'].data.shape)
print ('conv1/dw num_multiplications: ', dw_conv_parameters * dw_conv_outputs)
print('conv1/pw num param',pw_conv_parameters)
print('conv1/pw output shape',net.blobs['conv1/pw'].data.shape)
print ('conv1/pw num_multiplications: ', pw_conv_parameters * pw_conv_outputs)
print('total parameters: ',dw_conv_parameters + pw_conv_parameters)

print('total multiplications: ',(pw_conv_parameters * pw_conv_outputs) + (dw_conv_parameters * dw_conv_outputs))

輸出:

('conv1/dw num param: ', 27)
('conv1/dw output shape: ', (1, 3, 1, 1))
('conv1/dw num_multiplications: ', 81)
('conv1/pw num param', 30)
('conv1/pw output shape', (1, 10, 1, 1))
('conv1/pw num_multiplications: ', 300)
('total parameters: ', 57)
('total multiplications: ', 381)

test_conv.prototxt

input: "data"
input_shape {
dim: 1
dim: 3
dim: 3
dim: 3
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {
num_output: 10
bias_term: false
pad: 0
kernel_size: 3
weight_filler {
type: "msra"
}
}
}

示例Python代碼:

import sys, caffe
from functools import reduce
import numpy as np
net = caffe.Net('/tmp/test_conv.prototxt',caffe.TEST)
conv_parameters = reduce(lambda x, y:y*x, net.params['conv1'][0].data.shape)
conv_outputs = reduce(lambda x, y:y*x, net.blobs['conv1'].data.shape)
print('conv1 num param: ', conv_parameters)
print('conv1 output shape: ',net.blobs['conv1'].data.shape)
print ('conv1 num_multiplications: ', conv_parameters * conv_outputs)
print('total parameters: ',conv_parameters)
print('total multiplications: ',(conv_parameters * conv_outputs))

輸出:

('conv1 num param: ', 270)
('conv1 output shape: ', (1, 10, 1, 1))
('conv1 num_multiplications: ', 2700)
('total parameters: ', 270)
('total multiplications: ', 2700)

結論:

+--------------------------------+--------+---------------------+
| | Normal | Depthwise Separable |
+--------------------------------+--------+---------------------+
| Number of parameters (weights) | 270 | 57 |
+--------------------------------+--------+---------------------+
| Number of multiplications | 2700 | 381 |
+--------------------------------+--------+---------------------+

從上表中,我們可以得出結論,在深度可分離卷積的情況下所需的乘法數和乘法次數小於正常卷積


分享到:


相關文章: