“上采样”与“反卷积”

在阅读YOLO模型和DenseNet网络模型的时候,对“上采样”和“反卷积”的概念不甚理解,查阅了一些资料,整理如下。并附上pytorch实现上采样的源码。

在阅读本文前,默认读者已经了解了深度学习中的卷积操作。

声明:本文用到的部分资料来自简书作者@乔大叶_803e和知乎作者@幽并游侠儿_1425

文章目录

  • 上采样(Upsample)
  • 反卷积(Transposed Convolution)
  • pytorch实现上采样

上采样(Upsample)

在介绍上采样前,还有一个概念叫做下采样。下采样简单来讲,就是在卷积时,通过设置步长的方式,达到将输出缩小的目的。例如,通过设置步长为2的方式,可以将输出缩减为输入的一半,这也是经常使用的下采样方式。

而上采样达到的效果,则和下采样相反。上采样可以扩大输入图像的尺寸,将一个小分辨率的图像扩展成一个高分辨率的图像。在YOLOv4模型中,上采样被加入卷积网络中,作为中间层使用,扩展特征图尺寸,便于张量拼接。

“上采样”与“反卷积”_第1张图片

上采样常用的方法有双线性插值法,反卷积(也称转置卷积)法和上池化法。这里主要介绍反卷积。

反卷积(Transposed Convolution)

在理解反卷积前,我们先回顾一下正向的卷积操作。

“上采样”与“反卷积”_第2张图片

而反卷积,顾名思义,是反向的卷积操作,如下图。

“上采样”与“反卷积”_第3张图片

假设我们有一个3×3的卷积核,

“上采样”与“反卷积”_第4张图片

将其按照行重新排列:

“上采样”与“反卷积”_第5张图片

得到了一个4×16的矩阵,记为C

“上采样”与“反卷积”_第6张图片

将原始的4×4的输入矩阵扁平化为一个16×1的列向量,记为A。
记输出矩阵为B,可以得到
C A = B CA=B CA=B

“上采样”与“反卷积”_第7张图片

我们现在要进行的是反卷积,即通过B得到A,按照线性代数,

A = C T B A=C^{T}B A=CTB

“上采样”与“反卷积”_第8张图片

然后将输出reshape就可以得到4×4的特征矩阵了。

“上采样”与“反卷积”_第9张图片

pytorch实现上采样

pytorch提供了上采样的实现,其源码如下

from .module import Module
from .. import functional as F
from torch import Tensor


class Upsample(Module):
    __constants__ = ['size', 'scale_factor', 'mode', 'align_corners', 'name']
    name: str
    size: Optional[_size_any_t]
    scale_factor: Optional[_ratio_any_t]
    mode: str
    align_corners: Optional[bool]

    def __init__(self, size: Optional[_size_any_t] = None, scale_factor: Optional[_ratio_any_t] = None,
                 mode: str = 'nearest', align_corners: Optional[bool] = None) -> None:
        super(Upsample, self).__init__()
        self.name = type(self).__name__
        self.size = size
        if isinstance(scale_factor, tuple):
            self.scale_factor = tuple(float(factor) for factor in scale_factor)
        else:
            self.scale_factor = float(scale_factor) if scale_factor else None
        self.mode = mode
        self.align_corners = align_corners

    def forward(self, input: Tensor) -> Tensor:
        return F.interpolate(input, self.size, self.scale_factor, self.mode, self.align_corners)

    def extra_repr(self) -> str:
        if self.scale_factor is not None:
            info = 'scale_factor=' + str(self.scale_factor)
        else:
            info = 'size=' + str(self.size)
        info += ', mode=' + self.mode
        return info

对函数调用的实例如下:

import torch.nn as nn

x = nn.Upsample(scale_factor=2, mode='nearest')

如果觉得有帮助,欢迎点赞+收藏,笔芯~

你可能感兴趣的:(笔记,机器学习,卷积,深度学习,python,神经网络)