关于机器学习:深度学习基础入门篇92卷积之11-卷积残差网络2D3D卷积转置卷积数学推导应用实例

8次阅读

共计 13047 个字符,预计需要花费 33 分钟才能阅读完成。

深度学习根底入门篇[9.2]:卷积之 1 *1 卷积(残差网络)、2D/3D 卷积、转置卷积数学推导、利用实例

1.1*1 卷积

$1\times{1}$ 卷积,与规范卷积齐全一样,惟一的非凡点在于卷积核的尺寸是 $1\times{1}$,也就是不去思考输出数据部分信息之间的关系,而把关注点放在不同通道间。当输出矩阵的尺寸为 $3\times{3}$,通道数也为 3 时,应用 4 个 $1\times{1}$ 卷积核进行卷积计算,最终就会失去与输出矩阵尺寸雷同,通道数为 4 的输入矩阵,如 图 1 所示。

图 1 1*1 卷积构造示意图

  • $1\times{1}$ 卷积的作用
  1. 实现信息的跨通道交互与整合。思考到卷积运算的输入输出都是 3 个维度(宽、高、多通道),所以 $1\times{1}$ 卷积实际上就是对每个像素点,在不同的通道上进行线性组合,从而整合不同通道的信息。
  2. 对卷积核通道数进行降维和升维,缩小参数量。通过 $1\times{1}$ 卷积后的输入保留了输出数据的原有立体构造,通过调控通道数,从而实现升维或降维的作用。
  3. 利用 $1\times{1}$ 卷积后的非线性激活函数,在放弃特色图尺寸不变的前提下,大幅减少非线性

1.1 1*1 卷积在 GoogLeNet 中的利用

  • $1\times{1}$ 卷积在 GoogLeNet[1]中的利用

GoogLeNet 是 2014 年 ImageNet 较量的冠军,它的次要特点是网络不仅有深度,还在横向上具备“宽度”。因为图像信息在空间尺寸上的微小差别,如何抉择适合的卷积核来提取特色就显得比拟艰难了。空间散布范畴更广的图像信息适宜用较大的卷积核来提取其特色;而空间散布范畴较小的图像信息则适宜用较小的卷积核来提取其特色。为了解决这个问题,GoogLeNet 提出了一种被称为 Inception 模块的计划。如 图 2 所示:

图 2 Inception 模块构造示意图

Inception 模块的设计思维采纳多通路 (multi-path) 的设计模式,每个支路应用不同大小的卷积核,最终输入特色图的通道数是每个支路输入通道数的总和。如 图 2(a) 所示,Inception 模块应用 3 个不同大小的卷积核查输出图片进行卷积操作,并附加最大池化,将这 4 个操作的输入沿着通道维度进行拼接,形成的输入特色图将会蕴含通过不同大小的卷积核提取进去的特色,从而达到捕获不同尺度信息的成果。然而,这将会导致输入通道数变得很大,尤其是将多个 Inception 模块串联操作的时候,模型参数量会变得十分大。

为了减小参数量,Inception 模块改良了设计形式。如 图 2(b) 所示,在 $3\times{3}$ 和 $5\times{5}$ 的卷积层之前均减少 $1\times{1}$ 的卷积层来管制输入通道数;在最大池化层前面减少 $1\times{1}$ 卷积层减小输入通道数。上面这段程序是 Inception 块的具体实现形式,能够对照 图 2(b) 和代码一起浏览。

咱们这里能够简略计算一下 Inception 模块中应用 $1\times{1}$ 卷积前后参数量的变动,这里以 图 2(a) 为例,输出通道数 $C_{in}=192$,$1\times{1}$ 卷积的输入通道数 $C_{out1}=64$,$3\times{3}$ 卷积的输入通道数 $C_{out2}=128$,$5\times{5}$ 卷积的输入通道数 $C_{out3}=32$,则 图 2(a) 中的构造所需的参数量为:

$$1\times1\times192\times64+3\times3\times192\times128+5\times5\times192\times32=387072$$

图 2(b) 中在 $3\times{3}$ 卷积前减少了通道数 $C_{out4}=96$ 的 $1\times{1}$ 卷积,在 $5\times{5}$ 卷积前减少了通道数 $C_{out5}=16$ 的 $1\times{1}$ 卷积,同时在 maxpooling 后减少了通道数 $C_{out6}=32$ 的 $1\times{1}$ 卷积,参数质变为:

$$\small{1\times1\times192\times64+1\times1\times192\times96+1\times1\times192\times16+3\times3\times96\times128+5\times5\times16\times32 \\ +1\times1\times192\times32 =163328} $$

可见,$1\times{1}$ 卷积能够在不扭转模型表达能力的前提下,大大减少所应用的参数量。

Inception 模块的具体实现如下代码所示:

# GoogLeNet 模型代码
import numpy as np
import paddle
from paddle.nn import Conv2D, MaxPool2D, AdaptiveAvgPool2D, Linear
## 组网
import paddle.nn.functional as F

# 定义 Inception 块
class Inception(paddle.nn.Layer):
    def __init__(self, c0, c1, c2, c3, c4, **kwargs):
        '''
        Inception 模块的实现代码,c1, 图 (b) 中第一条支路 1x1 卷积的输入通道数,数据类型是整数
        c2, 图 (b) 中第二条支路卷积的输入通道数,数据类型是 tuple 或 list, 
               其中 c2[0]是 1x1 卷积的输入通道数,c2[1]是 3x3
        c3, 图 (b) 中第三条支路卷积的输入通道数,数据类型是 tuple 或 list, 
               其中 c3[0]是 1x1 卷积的输入通道数,c3[1]是 3x3
        c4, 图 (b) 中第一条支路 1x1 卷积的输入通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        # 顺次创立 Inception 块每条支路上应用到的操作
        self.p1_1 = Conv2D(in_channels=c0,out_channels=c1, kernel_size=1)
        self.p2_1 = Conv2D(in_channels=c0,out_channels=c2[0], kernel_size=1)
        self.p2_2 = Conv2D(in_channels=c2[0],out_channels=c2[1], kernel_size=3, padding=1)
        self.p3_1 = Conv2D(in_channels=c0,out_channels=c3[0], kernel_size=1)
        self.p3_2 = Conv2D(in_channels=c3[0],out_channels=c3[1], kernel_size=5, padding=2)
        self.p4_1 = MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.p4_2 = Conv2D(in_channels=c0,out_channels=c4, kernel_size=1)

    def forward(self, x):
        # 支路 1 只蕴含一个 1x1 卷积
        p1 = F.relu(self.p1_1(x))
        # 支路 2 蕴含 1x1 卷积 + 3x3 卷积
        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
        # 支路 3 蕴含 1x1 卷积 + 5x5 卷积
        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
        # 支路 4 蕴含 最大池化和 1x1 卷积
        p4 = F.relu(self.p4_2(self.p4_1(x)))
        # 将每个支路的输入特色图拼接在一起作为最终的输入后果
        return paddle.concat([p1, p2, p3, p4], axis=1)

1.2 1*1 卷积在 ResNet 中的利用 – 残差网络

随着深度学习的一直倒退,模型的层数越来越多,网络结构也越来越简单。然而减少网络的层数之后,训练误差往往不降反升。由此,Kaiming He 等人提出了残差网络 ResNet 来解决上述问题。ResNet 是 2015 年 ImageNet 较量的冠军,将辨认错误率升高到了 3.6%,这个后果甚至超出了正常人眼辨认的精度。在 ResNet 中,提出了一个十分经典的构造—残差块(Residual block)。

残差块是 ResNet 的根底,具体设计方案如 图 3 所示。不同规模的残差网络中应用的残差块也并不相同,对于小规模的网络,残差块如 图 3(a) 所示。然而对于稍大的模型,应用 图 3(a) 的构造会导致参数量十分大,因而从 ResNet50 当前,都是应用 图 3(b) 的构造。图 3(b) 中的这种设计方案也常称作瓶颈构造(BottleNeck)。1 1 的卷积核能够十分不便的调整中间层的通道数,在进入 3 3 的卷积层之前缩小通道数(256->64),通过该卷积层后再复原通道数(64->256),能够显著缩小网络的参数量。这个构造(256->64->256)像一个两头细,中间粗的瓶颈,所以被称为“BottleNeck”。

咱们这里能够简略计算一下残差块中应用 $1\times{1}$ 卷积前后参数量的变动,为了放弃对立,咱们令图 3 中的两个构造的输入输出通道数均为 256,则图 3(a)中的构造所需的参数量为:

$$3\times3\times256\times256\times2=1179648$$

而图 3(b)中采纳了 $1\times{1}$ 卷积后,参数量为:

$$1\times1\times256\times64+3\times3\times64\times64+1\times1\times64\times256=69632$$

同样,$1\times{1}$ 卷积能够在不扭转模型表达能力的前提下,大大减少所应用的参数量。

图 3 残差块构造示意图

残差块的具体实现如下代码所示:

# ResNet 模型代码
import numpy as np
import paddle
import paddle.nn as nn
import paddle.nn.functional as F

# ResNet 中应用了 BatchNorm 层,在卷积层的前面加上 BatchNorm 以晋升数值稳定性
# 定义卷积批归一化块
class ConvBNLayer(paddle.nn.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 filter_size,
                 stride=1,
                 groups=1,
                 act=None):
       
        """
        num_channels, 卷积层的输出通道数
        num_filters, 卷积层的输入通道数
        stride, 卷积层的步幅
        groups, 分组卷积的组数,默认 groups= 1 不应用分组卷积
        """
        super(ConvBNLayer, self).__init__()

        # 创立卷积层
        self._conv = nn.Conv2D(
            in_channels=num_channels,
            out_channels=num_filters,
            kernel_size=filter_size,
            stride=stride,
            padding=(filter_size - 1) // 2,
            groups=groups,
            bias_attr=False)

        # 创立 BatchNorm 层
        self._batch_norm = paddle.nn.BatchNorm2D(num_filters)
        
        self.act = act

    def forward(self, inputs):
        y = self._conv(inputs)
        y = self._batch_norm(y)
        if self.act == 'leaky':
            y = F.leaky_relu(x=y, negative_slope=0.1)
        elif self.act == 'relu':
            y = F.relu(x=y)
        return y

# 定义残差块
# 每个残差块会对输出图片做三次卷积,而后跟输出图片进行短接
# 如果残差块中第三次卷积输入特色图的形态与输出不统一,则对输出图片做 1x1 卷积,将其输入形态调整成统一
class BottleneckBlock(paddle.nn.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 stride,
                 shortcut=True):
        super(BottleneckBlock, self).__init__()
        # 创立第一个卷积层 1x1
        self.conv0 = ConvBNLayer(
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=1,
            act='relu')
        # 创立第二个卷积层 3x3
        self.conv1 = ConvBNLayer(
            num_channels=num_filters,
            num_filters=num_filters,
            filter_size=3,
            stride=stride,
            act='relu')
        # 创立第三个卷积 1x1,但输入通道数乘以 4
        self.conv2 = ConvBNLayer(
            num_channels=num_filters,
            num_filters=num_filters * 4,
            filter_size=1,
            act=None)

        # 如果 conv2 的输入跟此残差块的输出数据形态统一,则 shortcut=True
        # 否则 shortcut = False,增加 1 个 1x1 的卷积作用在输出数据上,使其形态变成跟 conv2 统一
        if not shortcut:
            self.short = ConvBNLayer(
                num_channels=num_channels,
                num_filters=num_filters * 4,
                filter_size=1,
                stride=stride)

        self.shortcut = shortcut

        self._num_channels_out = num_filters * 4

    def forward(self, inputs):
        y = self.conv0(inputs)
        conv1 = self.conv1(y)
        conv2 = self.conv2(conv1)

        # 如果 shortcut=True,间接将 inputs 跟 conv2 的输入相加
        # 否则须要对 inputs 进行一次卷积,将形态调整成跟 conv2 输入统一
        if self.shortcut:
            short = inputs
        else:
            short = self.short(inputs)

        y = paddle.add(x=short, y=conv2)
        y = F.relu(y)
        return y

参考文献

[1] Going deeper with convolutions

[2] Deep Residual Learning for Image Recognition

2. 3D 卷积(3D Convolution)

2.1 3D 卷积

规范卷积是一种 2D 卷积,计算形式如 图 1 所示。在 2D 卷积中,卷积核在图片上沿着宽和高两个维度滑动,在每次滑动过程时,对应地位的图像元素与卷积核中的参数进行乘加计算,失去输入特色图中的一个值。

图 1 2D 卷积示意图

2D 卷积仅仅思考 2D 图片的空间信息,所以只实用于单张 2D 图片的视觉了解工作。在解决 3D 图像或视频时,网络的输出多了一个维度,输出由 $(c,height,width)$ 变为了 $(c,depth,height,width)$,其中 $c$ 是通道数,$depth$ 为输出数据的宽度。因而,对该数据进行解决时,就须要卷积也作出相应的变换,由 2D 卷积变为 3D 卷积。

在 2D 卷积的根底上,3D 卷积 [1] 被提出。3D 卷积在结构上较 2D 卷积多了一个维度,2D 卷积的尺寸能够示意为 $k_h\times{k_w}$,而 3D 卷积的尺寸能够示意为 $k_h\times{k_w}\times{k_d}$。3D 卷积的具体的计算形式与 2D 卷积相似,即每次滑动时与 $c$ 个通道、尺寸大小为 $(depth,height,width)$ 的图像做乘加运算,从而失去输入特色图中的一个值,如 图 2 所示。

图 2 3D 卷积示意图

2.2 3D 卷积利用示例

3D 卷积的次要利用就是视频了解和医疗图像畛域。

视频了解工作 中,$k_d$ 就代表了工夫维度,也就是每个 3D 卷积核解决的间断帧数。在视频了解畛域的 3D 卷积计算中,首先会将 $k_d$ 个间断帧组成一个 3D 的图像序列,而后在图像序列中进行卷积计算。3D 卷积核会在 $k_d$ 个间断帧上进行滑动,每次滑动 $k_d$ 个间断帧中对应地位内的元素都要与卷积核中的参数进行乘加计算,最初失去输入特色图中的一个值。

3D CNN 中,应用了 3D 卷积对人体行为进行辨认,网络结构如 图 3 所示。网络只有 3 个卷积层、1 个全连贯层以及 2 个池化层。其中,前两个卷积层为 3D 卷积层,卷积核大小为 $7\times{7}\times{3}$ 和 $7\times{6}\times{3}$,也就是说每个卷积核解决 3 个间断帧中 $7\times{7}$ 和 $7\times{6}$ 大小的区域。

图 3 3D CNN 网络结构

因为该模型应用了 3D 卷积,使得其能够从空间和工夫的维度提取特色,从而捕获从多个间断帧中失去的静止信息。

医疗图像畛域 中,医学数据通常是 3D 的,比方咱们要宰割出的肿瘤就是 3D 的。如果用 2D 的图像处理模型去解决 3D 物体也是能够的,然而须要将生物医学影像图片的每一个切片成组的(蕴含训练数据和标注好的数据)的喂给模型进行训练,在这种状况下会存在一个效率问题,因而咱们应用的模型行将 U -Net 中 2D 卷积改为 3D 的模式,即 3D U-Net[2],如 图 4 所示。

图 4 3D U-Net 网络结构

该模型的网络结构跟 2D 构造的 U -Net 根本一样,惟一不同就是将 2D 卷积操作换成了 3D 卷积,因而,不须要独自输出每个切片进行训练,而是能够采取输出整张图片到模型中。

参考文献
[1] 3D Convolutional Neural Networks for Human Action Recognition

[2] 3D U-Net: Learning Dense Volumetric Segmentation from Sparse Annotation

3. 转置卷积(Transpose Convolution)

3.1 转置卷积提出背景

通常状况下,对图像进行卷积运算时,通过多层的卷积运算后,输入图像的尺寸会变得很小,即图像被约减。而对于某些特定的工作(比方:图像宰割、GAN),咱们须要将图像复原到原来的尺寸再进行进一步的计算。这个复原图像尺寸,实现图像由小分辨率到大分辨率映射的操作,叫做上采样(Upsample),如 图 1 所示。

图 1 上采样示例

上采样有多种形式,常见的包含:最近邻插值(Nearest neighbor interpolation)、双线性插值(Bi-Linear interpolation)等,然而这些上采样办法都是基于人们的先验教训来设计的,对于很多场景成果并不现实。因而,咱们心愿让神经网络本人学习如何更好地进行插值,这也就是接下来要介绍的转置卷积(Transpose Convolution)的办法。

3.2 转置卷积及其利用

转置卷积(Transpose Convolution),在某些文献中也被称为反卷积(Deconvolution)。转置卷积中,不会应用事后设定的插值办法,它具备可学习的参数,通过让网络自行学习,来获取最优的上采样形式。转置卷积在某些特定的畛域有着十分宽泛的利用,比方:

  • 在 DCGAN[1],生成器将会用随机值转变为一个全尺寸 (full-size) 的图片,这个时候就须要用到转置卷积。
  • 在语义宰割中,会应用卷积层在编码器中进行特征提取,而后在解码层中进行复原为原先的尺寸,这样才能够对原来图像的每个像素都进行分类。这个过程同样须要用到转置卷积。经典办法如:FCN[2]和 Unet[3]。
  • CNN 的可视化[4]:通过转置卷积将 CNN 中失去的特色图还原到像素空间,以察看特定的特色图对哪些模式的图像敏感。

3.3 转置卷积与规范卷积的区别

规范卷积的运算操作其实就是对卷积核中的元素与输出矩阵上对应地位的元素进行逐像素的乘积并求和。而后应用卷积核在输出矩阵上以步长为单位进行滑动,直到遍历完输出矩阵的所有地位。

这里举一个简略的例子演示一下具体的操作过程。假如输出是一个 $4\times{4}$ 的矩阵,应用 $3\times{3}$ 的规范卷积进行计算,同时不应用填充,步长设置为 1。最终输入的后果应该是一个 $2\times{2}$ 的矩阵,如 图 2 所示。

图 2 规范卷积运算示例

在上边的例子中,输出矩阵右上角 $3\times{3}$ 的值会影响输入矩阵中右上角的值,这其实也就对应了规范卷积中感触野的概念。所以,咱们能够说 $3\times{3}$ 的规范卷积核建设了输出矩阵中 9 个值与输入矩阵中 1 个值的对应关系。

综上所述,咱们也就能够认为规范卷积操作实际上就是建设了一个多对一的关系。

对于转置卷积而言,咱们实际上是想建设一个逆向操作,也就是建设一个一对多的关系。对于上边的例子,咱们想要建设的其实是输入卷积中的 1 个值与输出卷积中的 9 个值的关系,如 图 3 所示。

图 3 卷积逆向运算示例

当然,从信息论的角度,卷积操作是不可逆的,所以转置卷积并不是应用输入矩阵和卷积核计算原始的输出矩阵,而是计算失去放弃了绝对地位关系的矩阵

3.4 转置卷积数学推导

定义一个尺寸为 $4\times{4}$ 的输出矩阵 $input$:

$$ input=\left[\begin{array}{ccc} x_1 & x_2 & x_3 & x_4 \\ x_6 & x_7 & x_8 & x_9 \\ x_{10} & x_{11} & x_{12} & x_{13} \\ x_{14} & x_{15} & x_{16} & x_{17} \end{array}\right]$$

一个尺寸为 $3\times{3}$ 的规范卷积核 $kernel$:

$$ kernel=\left[\begin{array}{ccc} w_{0,0} & w_{0,1} & w_{0,2} \\ w_{1,0} & w_{1,1} & w_{1,2} \\ w_{2,0} & w_{2,1} & w_{2,2} \end{array}\right]$$

令步长 $stride=1$,填充 $padding=0$,依照输入特色图的计算形式 $o = \frac{i + 2p – k}{s} + 1$,咱们能够失去尺寸为 $2\times{2}$ 的输入矩阵 $output$:

$$ output=\left[\begin{array}{ccc} y_0 & y_1 \\ y_2 & y_3 \end{array}\right]$$

这里,咱们换一个表达方式,咱们将输出矩阵 $input$ 和输入矩阵 $output$ 开展成列向量 $X$ 和列向量 $Y$,那么向量 $X$ 和向量 $Y$ 的尺寸就别离是 $16\times{1}$ 和 $4\times{1}$,能够别离用如下公式示意:

$$ X=\left[\begin{array}{ccc} x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_6 \\ x_7 \\ x_8 \\ x_9 \\ x_{10} \\ x_{11} \\ x_{12} \\ x_{13} \\ x_{14} \\ x_{15} \\ x_{16} \\ x_{17} \end{array}\right]$$

$$ Y=\left[\begin{array}{ccc} y_0 \\ y_1 \\ y_2 \\ y_3 \end{array}\right]$$

咱们再用矩阵运算来形容规范卷积运算,这里应用矩阵 $C$ 来示意新的卷积核矩阵:

$$Y = CX$$

通过推导,咱们能够失去这个稠密矩阵 $C$,它的尺寸为 $4\times{16}$:

$$ \scriptsize{C=\left[\begin{array}{ccc} w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 & 0 & 0 & 0 & 0 \\ 0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 \\ 0 & 0 & 0 & 0 & 0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} \end{array}\right] }$$

这里,咱们用 图 4 为大家直观的展现一下上边的矩阵运算过程。

图 4 规范卷积矩阵运算示例

而转置卷积其实就是要对这个过程进行逆运算,即通过 $C$ 和 $Y$ 失去 $X$:

$$X = C^TY$$

此时,新的稠密矩阵就变成了尺寸为 $16\times{4}$ 的 $C^T$,这里咱们通过 图 5 为大家直观展现一下转置后的卷积矩阵运算示例。这里,用来进行转置卷积的权重矩阵不肯定来自于原卷积矩阵. 只是权重矩阵的形态和转置后的卷积矩阵雷同。

图 5 转置后卷积矩阵运算示例

咱们再将 $16\times{1}$ 的输入后果进行从新排序,这样就能够通过尺寸为 $2\times{2}$ 的输出矩阵失去尺寸为 $4\times{4}$ 的输入矩阵了。

3.5 转置卷积输入特色图尺寸

  • stride= 1 的转置卷积

咱们同样应用上文中的卷积核矩阵 $C$:

$$ \scriptsize{C=\left[\begin{array}{ccc}w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 & 0 & 0 & 0 & 0 \\0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 & 0 & 0 & 0 \\0 & 0 & 0 & 0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} & 0 \\0 & 0 & 0 & 0 & 0 & w_{0,0} & w_{0,1} & w_{0,2} & 0 & w_{1,0} & w_{1,1} & w_{1,2} & 0 & w_{2,0} & w_{2,1} & w_{2,2} \end{array}\right] }$$

对应的输入矩阵 $output$ 为:

$$ output=\left[\begin{array}{ccc}y_0 & y_1 \\y_2 & y_3\end{array}\right]$$

咱们将输入矩阵开展为列向量 $Y$:

$$ Y=\left[\begin{array}{ccc}y_0 \\ y_1 \\y_2 \\ y_3\end{array}\right]$$

带入到上文中提到的转置卷积计算公式,则转置卷积的计算结果为:

$$ \scriptsize{C^Ty’= \left[\begin{array}{ccc} w_{0,0}y_0 & w_{0,1}y_0+w_{0,0}y_1 & w_{0,2}y_0+w_{0,1}y_1 & w_{0,2}y_1 \\ w_{1,0}y_0+w_{0,0}y_2 & w_{1,1}y_0+w_{1,0}y_1+w_{0,1}y_2+w_{0,0}y_3 & w_{1,2}y_0+w_{1,1}y_1+w_{0,2}y_2+w_{0,1}y_3 & w_{1,2}y_1+w_{0,2}y_3 \\ w_{2,0}y_0+w_{1,0}y_2 & w_{2,1}y_0+w_{2,0}y_1+w_{1,1}y_2+w_{1,0}y_3 & w_{2,2}y_0+w_{2,1}y_1+w_{1,2}y_2+w_{1,1}y_3 & w_{2,2}y_1+w_{1,2}y_3 \\ w_{2,0}y_2 & w_{2,1}y_2+w_{2,0}y_3 & w_{2,2}y_2+w_{2,1}y_3 & w_{2,2}y_3 \end{array}\right] }$$

这其实就等价于填充 $padding=2$,输出为:

$$ input=\left[\begin{array}{ccc} 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & y_0 & y_1 & 0 & 0 \\ 0 & 0 & y_2 & y_3 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \end{array}\right]$$

同时,规范卷积核进行转置:

$$ kernel‘=\left[\begin{array}{ccc} w_{2,2} & w_{2,1} & w_{2,0} \\ w_{1,2} & w_{1,1} & w_{1,0} \\ w_{0,2} & w_{0,1} & w_{0,0} \end{array}\right]$$

之后的规范卷积的后果,运算过程如 图 6 所示。

图 6 s= 1 时,转置卷积运算示例

对于卷积核尺寸为 $k$,步长 $stride=1$,填充 $padding=0$ 的规范卷积,等价的转置卷积在尺寸为 $i’$ 的输出矩阵上进行运算,输入特色图的尺寸 $o’$ 为:

$$o’ = i’+(k-1)$$

同时,转置卷积的输出矩阵须要进行 $padding’=k-1$ 的填充。

  • stride>1 的转置卷积

在理论应用的过程中,咱们大多数时候应用的会是 stride>1 的转置卷积,从而取得较大的上采样倍率。这里,咱们令输出尺寸为 $5\times{5}$,规范卷积核的设置同上,步长 $stride=2$,填充 $padding=0$,规范卷积运算后,输入尺寸为 $2\times{2}$。

$$ Y=\left[\begin{array}{ccc}y_0 \\ y_1 \\y_2 \\ y_3\end{array}\right]$$

这里,步长 $stride=2$,转换后的稠密矩阵尺寸变为 $25\times{4}$,因为矩阵太大这里不开展进行列举。则转置卷积的后果为:

$$ \scriptsize{C^Ty’=\left[\begin{array}{ccc} w_{0,0}y_0 & w_{0,1}y_0 & w_{0,2}y_0+w_{0,0}y_1 & w_{0,1}y_1 & w_{0,2}y_1\\ w_{1,0}y_0 & w_{1,1}y_0 & w_{1,2}y_0+w_{1,0}y_1 & w_{1,1}y_1 & w_{1,2}y_1\\ w_{2,0}y_0+w_{0,0}y_2 & w_{2,1}y_0+w_{0,1}y_2 & w_{2,2}y_0+w_{2,0}y_1+w_{0,2}y_2+w_{0,0}y_3 & w_{2,1}y_1+w_{0,1}y_3 & w_{2,2}y_1+w_{0,2}y_3\\ w_{1,0}y_2 & w_{1,1}y_2 & w_{1,2}y_2+w_{1,0}y_3 & w_{1,1}y_3 & w_{1,2}y_3\\ w_{2,0}y_2 & w_{2,1}y_2 & w_{2,2}y_2+w_{2,0}y_3 & w_{2,1}y_3 & w_{2,2}y_3\\ \end{array}\right] }$$

此时,等价于输出矩阵增加了空洞,同时也增加了填充,规范卷积核进行转置之后的运算后果。运算过程如 图 7 所示。

图 7 s>1 时,转置卷积运算示例

对于卷积核尺寸为 $k$,步长 $stride>1$,填充 $padding=0$ 的规范卷积,等价的转置卷积在尺寸为 $i’$ 的输出矩阵上进行运算,输入特色图的尺寸 $o’$ 为:

$$o’ = s(i’-1)+k$$

同时,转置卷积的输出矩阵须要进行 $padding’=k-1$ 的填充,相邻元素间的空洞大小为 $s-1$。因而,能够通过管制步长 $stride$ 来管制上采样倍率。

参考文献

[1] Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks

[2] Fully Convolutional Networks for Semantic Segmentation

[3] U-Net: Convolutional Networks for Biomedical Image Segmentation

[4] Visualizing and Understanding Convolutional Networks

正文完
 0