我在Ubuntu下成功编译了Caffe,并开始研究如何定义和训练我自己的网络。但是,我很难理解卷积层如何产生其输出。例如,LeNet MNIST教程(tutorial,lenet.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"
}
}
}
如何计算输出图像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
这个假设是否正确?
答案 0 :(得分:4)
在卷积层中,内核(也称为滤镜)与输入要素图卷积并生成输出要素图。一组特征映射称为blob。每个内核都是一个具有 C x H x W 大小的3D对象。这里 C 是平面或通道的no, H 是高度, W 是内核的宽度。通常,内核是正方形的,即内核的高度和宽度是相同的。内核的通道或平面数或深度应与输入要素图或图像的数量相同。图像和一组内核之间的卷积运算的输出称为特征映射。此外,特征映射和内核之间的后续卷积也会生成输出,也称为特征映射。
如上所述,内核是一个3D数组。当内核在输入图像上滑动或卷积时,它将内核中的值与图像的原始像素值相乘。因此,内核数组的每个值都与图像的相应像素相乘。最后,将所有产品添加到一起,以给出输出要素图的一个值。然后内核按给定的步幅滑动并再次启动该过程以生成输出要素图的下一个值。一个内核生成一个输出平面,称为特征映射。因此, N 内核会生成 N 要素贴图。每个内核都有一个偏置元素,它被添加到输出特征映射的每个值中。偏置元素的数量等于内核的数量。
对于3 x 3 x 3内核,卷积计算如下:
此处 p , q 和 r 取决于步幅。
这是来自Stanford 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×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)内核也分为2组128(48 x 5 x 5)内核。此后,每组输入特征映射与一组128(48×5×5)内核进行卷积。这导致2组(48×27×27)特征图。 2组中的每一组都具有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 x 2 - 5)/ 1 + 1,(27 + 2 x 2 - 5)/ 1 + 1)
P.S。:卷积背后的数学在所有工具中都很常见,无论是Caffe,Keras,Tensorflow还是Torch。只是在每个实现中代码的优化方式不同。