欢迎光临散文网 会员登陆 & 注册

47 转置卷积【动手学深度学习v2】

2023-08-10 18:02 作者:月芜SA  | 我要投稿

转置卷积

卷积操作一般不会改变输入的高宽。若改变一般是往缩小改变。

在语义分割问题中,数据是像素级别的输入与输出,如果使用一般卷积使得高宽减小到很小的数值,则会造成数据损失。

转置卷积通常用于增大数据的高宽

具体来说,输入数据中的每个值都会与整个转置卷积核相乘,形成一个与卷积核大小相同的新数据,放置在特定对应位置,最后相加。


为什么称此运算方法为“转置”?(此处设计卷积法的矩阵实现,在下一讲中会作详细说明)


代码实现

import torch
from torch import nn
from d2l import torch as d2l

对输入矩阵X和卷积核矩阵K实现基本的转置卷积运算trans_conv


def trans_conv(X, K):
    h, w = K.shape
    Y = torch.zeros((X.shape[0] + h - 1, X.shape[1] + w - 1))
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            Y[i: i + h, j: j + w] += X[i, j] * K
    return Y


与通过卷积核“减少”输入元素的常规卷积(在 6.2节中)相比,转置卷积通过卷积核“广播”输入元素,从而产生大于输入的输出。 我们可以通过 图13.10.1来构建输入张量X和卷积核张量K从而验证上述实现输出。 此实现是基本的二维转置卷积运算。


X = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
trans_conv(X, K)


tensor([[ 0.,  0.,  1.],
        [ 0.,  4.,  6.],
        [ 4., 12.,  9.]])

或者,当输入X和卷积核K都是四维张量时,我们可以使用高级API获得相同的结果。


X, K = X.reshape(1, 1, 2, 2), K.reshape(1, 1, 2, 2)
tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, bias=False)
tconv.weight.data = K
tconv(X)


tensor([[[[ 0.,  0.,  1.],
          [ 0.,  4.,  6.],
          [ 4., 12.,  9.]]]], grad_fn=<ConvolutionBackward0>)


填充、步幅和多通道实现

与常规卷积不同,在转置卷积中,填充被应用于的输出(常规卷积将填充应用于输入)。 例如,当将高和宽两侧的填充数指定为1时,转置卷积的输出中将删除第一和最后的行与列。


tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, padding=1, bias=False)
tconv.weight.data = K
tconv(X)


tensor([[[[4.]]]], grad_fn=<ConvolutionBackward0>)

在转置卷积中,步幅被指定为中间结果(输出),而不是输入。 使用 图13.10.1中相同输入和卷积核张量,将步幅从1更改为2会增加中间张量的高和权重,因此输出张量在 图13.10.2中。


可以发现转置卷积中padding和stride的作用和一般卷积完全是反过来的,一般卷积中padding会扩大输出结构,转置卷积相反。一般卷积中stride会缩小输出结构,转置卷积则相反。

以下代码可以验证 图13.10.2中步幅为2的转置卷积的输出。


tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, stride=2, bias=False)
tconv.weight.data = K
tconv(X)


tensor([[[[0., 0., 0., 1.],
          [0., 0., 2., 3.],
          [0., 2., 0., 3.],
          [4., 6., 6., 9.]]]], grad_fn=<ConvolutionBackward0>)

对于多个输入和输出通道,转置卷积与常规卷积以相同方式运作。 假设输入有Ci个通道,且转置卷积为每个输入通道分配了一个Kℎ×Kw

的卷积核张量。 当指定多个输出通道时,每个输出通道将有一个Ci×Kℎ×Kw的卷积核。

同样,如果我们将X代入卷积层f来输出Y=f(X)

,并创建一个与f具有相同的超参数、但输出通道数量是X中通道数的转置卷积层g,那么g(Y)

的形状将与X相同。 下面的示例可以解释这一点。


X = torch.rand(size=(1, 10, 16, 16))
conv = nn.Conv2d(10, 20, kernel_size=5, padding=2, stride=3)
tconv = nn.ConvTranspose2d(20, 10, kernel_size=5, padding=2, stride=3)
tconv(conv(X)).shape == X.shape


True


知识补充

·转置卷积可以视作对像素信息的放大尝试。转置卷积是以一个不损失信息的方式变换feature图,把它拉大

·转置卷积在网络中的作用不是将图片还原(指还原成原图片的RGB信息),而是对每个像素进行标号归类。

·虽然在卷积过程中会对数据结构的高宽作一定的压缩,但是通道数随之也会增加,并没有损失太多的信息量。这一过程可以看做图片数据的空间分辨维度在下降,但是特征分辨维度在上升。







47 转置卷积【动手学深度学习v2】的评论 (共 条)

分享到微博请遵守国家法律