简明易懂——卷积神经网络的输入输出特征图大小计算


?? 参考文档:《百度飞浆:零基础入门深度学习》


假设输入图片尺寸是

H

×

W

H \times W

H×W,卷积核(池化窗口)大小为

k

h

×

k

w

k_h \times k_w

kh?×kw?

  • 卷积层: 假设填充为

    (

    p

    h

    ,

    p

    w

    )

    (p_h, p_w)

    (ph?,pw?),步幅为

    (

    s

    h

    ,

    s

    w

    )

    (s_h, s_w)

    (sh?,sw?),则卷积层输出特征图的大小为:

    H

    o

    u

    t

    =

    H

    +

    2

    p

    h

    ?

    k

    h

    s

    h

    +

    1

    H_{out} = \frac{H + 2p_h - k_h}{s_h} + 1

    Hout?=sh?H+2ph??kh??+1

    W

    o

    u

    t

    =

    W

    +

    2

    p

    w

    ?

    k

    w

    s

    w

    +

    1

    W_{out} = \frac{W + 2p_w - k_w}{s_w} + 1

    Wout?=sw?W+2pw??kw??+1


图1:步幅为2的卷积过程


  • 池化层: 假设在第一行之前填充

    p

    h

    1

    p_{h1}

    ph1? 行,在最后一行后面填充

    p

    h

    2

    p_{h2}

    ph2? 行。在第一列之前填充

    p

    w

    1

    p_{w1}

    pw1? 列,在最后一列之后填充

    p

    w

    2

    p_{w2}

    pw2? 列,则池化层输出特征图大小为:

    H

    o

    u

    t

    =

    H

    +

    p

    h

    1

    +

    p

    h

    2

    ?

    k

    h

    s

    h

    +

    1

    H_{out} = \frac{H + p_{h1} + p_{h2} - k_h}{s_h} + 1

    Hout?=sh?H+ph1?+ph2??kh??+1

    W

    o

    u

    t

    =

    W

    +

    p

    w

    1

    +

    p

    w

    2

    ?

    k

    w

    s

    w

    +

    1

    W_{out} = \frac{W + p_{w1} + p_{w2} - k_w}{s_w} + 1

    Wout?=sw?W+pw1?+pw2??kw??+1

    在卷积神经网络中,通常使用

    2

    ×

    2

    2\times2

    2×2 大小的池化窗口,步幅也使用 2,填充为 0,则输出特征图的尺寸为:

    H

    o

    u

    t

    =

    H

    2

    H_{out} = \frac{H}{2}

    Hout?=2H?

    W

    o

    u

    t

    =

    W

    2

    W_{out} = \frac{W}{2}

    Wout?=2W?



图2:平均池化


多输入通道、多输出通道和批量操作

前面介绍的卷积计算过程比较简单,实际应用时,处理的问题要复杂的多。例如:对于彩色图片有RGB三个通道,需要处理多输入通道的场景。输出特征图往往也会具有多个通道,而且在神经网络的计算中常常是把一个批次的样本放在一起计算,所以卷积算子需要具有批量处理多输入和多输出通道数据的功能,下面将分别介绍这几种场景的操作方式。

  • 多输入通道场景

    上面的例子中,卷积层的数据是一个 2 维数组,但实际上一张图片往往含有 RGB 三个通道,要计算卷积的输出结果,卷积核的形式也会发生变化。假设输入图片的通道数为

    C

    i

    n

    C_{in}

    Cin?,输入数据的形状是

    C

    i

    n

    ×

    H

    i

    n

    ×

    W

    i

    n

    C_{in} \times H_{in} \times W_{in}

    Cin?×Hin?×Win?,计算过程如 图3 所示。
    3
    假设图片尺寸是

    H

    ×

    W

    H \times W

    H×W,卷积核大小(kernel_size)为 ,填充(padding)为 ,步幅(strides)为 ,则该卷积层输出特征图大小为:

  1. 对每个通道分别设计一个 2 维数组作为卷积核,卷积核数组的形状是

    C

    i

    n

    ×

    k

    h

    ×

    k

    w

    C_{in} \times k_{h} \times k_{w}

    Cin?×kh?×kw?。

  2. 对任一通道

    c

    i

    n

    [

    0

    ,

    C

    i

    n

    )

    c_{in} \in [0, C_{in})

    cin?∈[0,Cin?),分别用大小为

    k

    h

    ×

    k

    w

    k_{h} \times k_{w}

    kh?×kw? 的卷积核在大小为

    H

    i

    n

    ×

    W

    i

    n

    H_{in}\times{W_{in}}

    Hin?×Win? 的二维矩阵上做卷积。

  3. 将这

    C

    i

    n

    C_{in}

    Cin? 个通道的计算结果相加,得到的是一个形状为

    H

    o

    u

    t

    ×

    W

    o

    u

    t

    H_{out}\times{W_{out}}

    Hout?×Wout? 的二维矩阵。

  • 多输出通道场景

    一般来说,卷积操作的输出特征图也会具有多个通道

    C

    o

    u

    t

    C_{out}

    Cout?,这时我们要设计

    C

    o

    u

    t

    C_{out}

    Cout? 个维度为

    C

    i

    n

    ×

    k

    h

    ×

    k

    w

    C_{in}\times{k_h}\times{k_w}

    Cin?×kh?×kw? 的卷积核,卷积核数组的维度是

    C

    o

    u

    t

    ×

    C

    i

    n

    ×

    k

    h

    ×

    k

    w

    C_{out}\times C_{in}\times{k_h}\times{k_w}

    Cout?×Cin?×kh?×kw?,如 图4 所示。
    4

  1. 对任一输出通道

    c

    o

    u

    t

    [

    0

    ,

    C

    o

    u

    t

    )

    c_{out} \in [0, C_{out})

    cout?∈[0,Cout?),分别使用上面描述的形状为

    C

    i

    n

    ×

    k

    h

    ×

    k

    w

    C_{in}\times{k_h}\times{k_w}

    Cin?×kh?×kw? 的卷积核对输入图片做卷积。

  2. 将这

    C

    o

    u

    t

    C_{out}

    Cout? 个形状为

    H

    o

    u

    t

    ×

    W

    o

    u

    t

    H_{out}\times{W_{out}}

    Hout?×Wout? 的二维数组堆叠在一起,形成维度为

    C

    o

    u

    t

    ×

    H

    o

    u

    t

    ×

    W

    o

    u

    t

    C_{out}\times{H_{out}}\times{W_{out}}

    Cout?×Hout?×Wout? 的三维数组。

说明: 通常将卷积核的输出通道数叫做卷积核的个数。

  • 批量操作

    在卷积神经网络的计算中,通常将多个样本放在一起形成一个 mini-batch 进行批量操作,即输入数据的维度是

    N

    ×

    C

    i

    n

    ×

    H

    i

    n

    ×

    W

    i

    n

    N\times{C_{in}}\times{H_{in}}\times{W_{in}}

    N×Cin?×Hin?×Win?。由于会对每张图片使用同样的卷积核进行卷积操作,卷积核的维度与上面多输出通道的情况一样,仍然是

    C

    o

    u

    t

    ×

    C

    i

    n

    ×

    k

    h

    ×

    k

    w

    C_{out}\times C_{in}\times{k_h}\times{k_w}

    Cout?×Cin?×kh?×kw?,输出特征图的维度是

    N

    ×

    C

    o

    u

    t

    ×

    H

    o

    u

    t

    ×

    W

    o

    u

    t

    N\times{C_{out}}\times{H_{out}}\times{W_{out}}

    N×Cout?×Hout?×Wout?,如 图5 所示。
    5

飞桨 PaddlePaddle 和 PyTorch 卷积 API 介绍

飞桨卷积算子对应的 API 是 paddle.fluid.dygraph.Conv2D,PyTorch 卷积算子对应 API 是 torch.nn.Conv2d,常用的参数如下:

PaddlePaddle API PyTorch API 注释
num_channels in_channels (int) - 输入图像的通道数
num_fliters out_chanels (int) - 卷积核的个数,和输出特征图通道数相同,相当于上文中的

C

o

u

t

C_{out}

Cout?

filter_size kernel_size (int | tuple) - 卷积核大小,可以是整数,比如 3,表示卷积核的高和宽均为 3 ;或者是两个整数的 list,例如 [3, 2] ,表示卷积核的高为 3,宽为 2
stride stride (int | tuple) - 步幅,可以是整数,默认值为 1,表示垂直和水平滑动步幅均为 1;或者是两个整数的 list,例如 [3, 2],表示垂直滑动步幅为 3,水平滑动步幅为 2
padding padding (int | tuple) - 填充大小,可以是整数,比如 1,表示竖直和水平边界填充大小均为 1;或者是两个整数的 list,例如 [2, 1],表示竖直边界填充大小为 2,水平边界填充大小为 1

输入数据维度

[

N

,

C

i

n

,

H

i

n

,

W

i

n

]

[N, C_{in}, H_{in}, W_{in}]

[N,Cin?,Hin?,Win?] ,输出数据维度

[

N

,

n

u

m

_

f

i

l

t

e

r

s

,

H

o

u

t

,

W

o

u

t

]

[N, num\_filters, H_{out}, W_{out}]

[N,num_filters,Hout?,Wout?],权重参数

w

w

w 的维度

[

n

u

m

_

f

i

l

t

e

r

s

,

C

i

n

,

f

i

l

t

e

r

_

s

i

z

e

_

h

,

f

i

l

t

e

r

_

s

i

z

e

_

w

]

[num\_filters, C_{in}, filter\_size\_h, filter\_size\_w]

[num_filters,Cin?,filter_size_h,filter_size_w],偏置参数

b

b

b 的维度是

[

n

u

m

_

f

i

l

t

e

r

s

]

[num\_filters]

[num_filters]。