了解Caffe卷积层

kon*_*nze 1 convolution deep-learning caffe

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

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"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如何O_0, ..., O_49计算输出图像?我的直觉是,它的工作方式如下(I_i输入图像,K_j内核,B_k偏差,*卷积运算符):

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
Run Code Online (Sandbox Code Playgroud)

这个假设正确吗?

Har*_*han 5

在卷积层中,内核(也称为过滤器)与输入特征图进行卷积并生成输出特征图。一组要素贴图称为斑点。每个内核都是3D对象,尺寸为C xH xW。这里C是平面或通道的数目,H是高度,W是核的宽度。通常,内核是正方形的,即内核的高度和宽度是相同的。通道的数量或平面或内核的深度应与输入要素图或图像的数量相同。图像和一组内核之间的卷积运算的输出称为特征图。而且,特征图和内核之间的后续卷积会生成输出,也称为特征图。

如上所述,内核是3D数字数组。当内核在输入图像上滑动或卷积时,它将内核中的值与图像的原始像素值相乘。因此,内核数组的每个值都将与图像的相应像素相乘。最后,将所有乘积相加,得到输出要素图的一个值。然后内核滑动给定的步幅,并再次开始该过程以生成输出特征图的下一个值。一个内核生成一个输出平面,称为特征图。因此,N个内核生成N个特征图。每个内核都有一个偏置元素,该偏置元素被添加到输出特征图的每个值。偏置元素的数量等于内核的数量。

对于3 x 3 x 3内核,卷积计算如下:

在此处输入图片说明

在此,pqr取决于步幅。

这是斯坦福Wiki上的动画,对其进行了精美的解释:

在此处输入图片说明

输入和输出要素图之间的关系为

输入:
C_in =输入要素图的通道数H_in =输入要素图的
高度W_in =输入要素图的
宽度

输出:
N_out =内核数
C_out = 内核中的通道数
H_out =(H_in + 2 x填充高度-内核高度)/步幅高度+ 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 x 11 x 11)内核与(3 x 227 x 227)图像卷积,从而内核的每个通道都与图像的相应通道卷积。您可以将其可视化为(11 x 11)蒙版,在(227 x 227)输入特征图上卷积以给出(55 x 55)输出特征图。为每个内核获得了这3个通道。此后,将不同通道的相应特征相加在一起,得到一个(55 x 55)特征图。这样产生了96个特征图。因此,获得(96 x 55 x 55)输出斑点。

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

ReLU

汇集

正常化

第2层

输入特征图:(
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个通道。因此,输入要素图被分为2组(48 x 27 x 27)要素图。256(48 x 5 x 5)个内核也分为两组128(48 x 5 x 5)内核。此后,将每组输入特征图与一组128(48 x 5 x 5)个内核进行卷积。这将产生2组(48 x 27 x 27)特征图。2套中的每套都有128(48 x 27 x 27)个特征图。现在,将每组的48个通道合并以生成128个(27 x 27)特征图。因此,获得2组128(27 x 27)个特征图。现在将这两组连接起来以产生(256 x 27 x 27)输出斑点。

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

PS:卷积背后的数学原理在所有工具中都是通用的,无论是Caffe,Keras,Tensorflow还是Torch。只是在每个实现中对代码进行了不同的优化。