2017-09-01 103 views
0

我在Ubuntu下成功编译Caffe并开始研究如何定义和训练我自己的网络。然而,我很难理解卷积层如何产生它的输出。例如,第二卷积层(CONV2)的LeNet MNIST教程(tutoriallenet.prototxt)具有20个输入图像和50倍输出的图像:了解Caffe卷积层

layer { 
    name: "conv2" 
    type: "Convolution" 
    bottom: "pool1" 
    top: "conv2" 
    param { 
    lr_mult: 1 
    } 
    param { 
    lr_mult: 2 
    } 
    convolution_param { 
    num_output: 50 
    kernel_size: 5 
    stride: 1 
    weight_filler { 
     type: "xavier" 
    } 
    bias_filler { 
     type: "constant" 
    } 
    } 
} 

如何输出图像O_0, ..., O_49计算的?我的直觉是,它是这样工作的(I_i输入图像,K_j仁,B_k biasses,*卷积运算符):

O_0 = I_0 * K_0 + ... + I_19 * K_19 + B_0 
O_1 = I_0 * K_20 + ... + I_19 * K_39 + B_1 
... 
O_49 = I_0 * K_980 + ... + I_19 * K_999 + B_49 

这是假设是正确的?

回答

2

在卷积层中,内核(也称为过滤器)与输入特征映射进行卷积并生成输出特征映射。一组特征映射被称为blob。每个内核都是一个3D对象,其大小为C x H x W。这里C是平面或通道号,H是高度和W是内核的宽度。通常,内核是方形的,即内核的高度和宽度是相同的。内核的通道或平面的数量或深度应与输入特征映射或图像的数量相同。图像和一组内核之间的卷积运算的输出被称为特征映射。此外,特征映射和内核之间的后续卷积产生也称为特征映射的输出。如上所述,内核是3D数组。当内核在输入图像上滑动或卷积时,它将内核中的值与图像的原始像素值相乘。因此,内核数组的每个值都与图像的相应像素相乘。最后,将所有产品加在一起给出输出特征映射的一个值。然后内核按给定的步幅滑动,并再次启动该过程以生成输出特征映射的下一个值。一个内核产生一个称为特征映射的输出平面。因此N内核生成N功能图。每个内核都有一个偏置元素,它被添加到输出特征映射的每个值中。偏置元素的数量等于内核的数量。

对于3×3×3内核的卷积计算如下:

enter image description here

这里pqř取决于步幅。

下面是从Stanford wiki的动画精美解释它:

enter image description here

的输入和输出特征图之间的关系给定为

输入:
C_IN =否在通道的输入特征图
H_in =输入特征图的高度
W_in =输入特征图的宽度

输出:
N_OUT =无籽粒的
C_out =否在内核通道
H_out =(H_IN + 2×填充高度 - 内核高度)/步幅高度+ 1
W_OUT =(W_IN + 2 x填充宽度 - 核宽度)/步幅宽度+ 1

所有C_out平面合并(累积)以形成一个平面。因此输出是一组N_out,H_out x W_out特征映射。

服用AlexNet例如:

层1个

输入数据(RGB图像):(3,227,227)
CONV1内核:(96,3,11,11 )
器CONV1的输出:(96,55,55)

N = 96,C = 3,H = 11,W = 11
填充高度= 0,填充宽度= 0
步幅高度= 4
跨距宽度= 4

在这里,每个(3×11×11)的内核卷积用(3×227 X 227)图像,使得与相应的信道内核卷积的每个信道的形象。您可以将其视为一个(11 x 11)蒙板,在(227 x 227)输入要素图上进行卷积以得到(55 x 55)输出要素图。这3个通道是针对每个内核获得的。之后,将不同通道的相应特征加在一起以给出一个(55×55)特征图。生成这样的96个特征图。因此,获得(96 x 55 x 55)输出斑点。

(55,55)=((227 + 2×0 - 11)/ 4 + 1,(227 + 2×0 - 11)/ 4 + 1)

RELU

正常化

二层

输入特征图:(96,27,27)
CONV2内核:(256,48,5,5)
CONV2输出:(256,27,27)

N = 256,C = 48,H = 5,W = 5
填充高度= 2,填充宽度= 2
步幅高度= 1
跨距宽度= 1

这里,输入特征映射具有96个通道,但内核48只有频道。所以,输入特征映射被分成两组(48×27×27)特征映射。 256(48×5×5)内核也被分成两组128(48×5×5)内核。之后,每组输入特征映射与一组128(48×5×5)内核卷积。这导致2组(48×27×27)特征图。两组中的每一组都有128个(48 x 27 x 27)特征地图。现在,每个集合的48个通道合并为128(27 x 27)个特征地图。因此获得2组128(27×27)个特征图。这两组现在连接在一起产生(256 x 27 x 27)输出blob。

(27,27)=((27 + 2×2 - 5)/ 1 + 1,(27 + 2×2 - 5)/ 1 + 1)

PS:后面卷积的数学无论是Caffe,Keras,Tensorflow还是Torch,所有工具都是常见的。只是代码在每个实现中都有不同的优化。