记录一下pytorch上采样操作的几种简单方法(暂存,后续待补充)

一、反池化操作

反池化操作有两种,一种是反最大池化,另一种是反平均池化。反池化是池化的逆操作,是无法通过池化的结果还原出全部的原始数据。因为池化的过程就只保留了主要信息,舍去部分信息。

反最大池化

图源网络
主要原理就是在Maxpooling的时候保留最大值的位置信息,之后在unPooling阶段使用该信息扩充Feature Map,除最大值位置以外,其余补0。如上图,(图源网络)以下是我用在自编码结构中的一个上采样类,仅做参考。

class UpSamplingBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(UpSamplingBlock, self).__init__()
        self.unpool = nn.MaxUnpool2d(2, stride=2)  # kernel =2
        self.pool = nn.MaxPool2d(2, stride=2, return_indices=True)
        # return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助,经过kernel=2,stride=2后,尺度缩减为原来的1/4
        self.conv1 = conv5x5(in_channels, out_channels)
        self.bn1 = nn.BatchNorm2d(out_channels)  # out_channels为输入通道数
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(out_channels, out_channels)
        self.bn2 = nn.BatchNorm2d(out_channels)

    def forward(self, x):
        # create indices for unpool
        size = x.size()
        _, indices = self.pool(torch.empty(size[0], size[1], size[2] * 2, size[3] * 2))
        # torch.empty创建一个未被初始化数值的tensor,tensor的大小是由size确定,随机找出最大值安插的位置
        '''m=nn.MaxPool2d((3,3),stride=(1,1),return_indices=True)
           upm=nn.MaxUnpool2d((3,3),stride=(1,1))
           data4=torch.randn(1,1,3,3)
           output5,indices=m(data4),  indices记录下下采样操作时,其中最大值的位置,即索引
           output6=upm(output5,indices)'''
        # unpool and assign residual
        out = self.unpool(x, indices.to(device))
        residual = self.conv1(out)  # 5X5卷积的残差网络的分支道路
        residual = self.bn1(residual)
        # forward and projection,上采样网络的主道路
        out = self.conv1(out)  # 5X5卷积,经过paddig
        out = self.bn1(out)  # 应该对输出结果out归一化
        out = self.relu(out)
        out = self.conv2(out)  # 3X3卷积,经过padding
        out = self.bn2(out)
        out += residual
        return out

反平均池化

反平均池化的操作其实与反最大值池化操作类似,如反最大值池化上图只不过是除了索引位置,其他对应位置也用均值来代替。如下图,(图源网络 )
图源网络

二、PixelShuffle(直译:像素重组)

pixelshuffle的原理:
pixelshuffle的主要原理就是将rr个通道的特征图转换成新的w∗r,h∗r 的上采样结果(比如原来特征图大小为4128128,现在就调整成大小1256256)。具体来说,就是按照一定规则将每个像素点的rr个通道依次转换为对应的r*r的图像块。最开始好像是用于超分辨率领域,原理如下图(图源网络)
在这里插入图片描述
在pytorch中有此函数,可以直接拿来使用,在TensorFlow1.x中好像没有这个函数,得自己写代码,

# 上采样操作之亚像素卷积,
          ps = nn.PixelShuffle(3)	#3为放大倍数,即h与w方向上均扩大3倍
          input = autograd.Variable(torch.Tensor(1, 9, 4, 4))
          output = ps(input)
          print(output.size())
          torch.Size([1, 1, 12, 12])

三、最近邻插值UpsamplingNearest2d函数

torch.nn.UpsamplingNearest2d(size=None, scale_factor=None)对输入信号做2D最近邻上采样。原理如下图,(图源网络)
在这里插入图片描述

在这里插入图片描述

input = torch.arange(1, 5).view(1, 1, 2, 2)
upnear = nn.UpsamplingNearest2d(scale_factor=2)
out = upnear(input)

四、双线性插值UpsamplingBilinear2d函数

torch.nn.UpsamplingBilinear2d(size=None, scale_factor=None)对输入信号做2D双线性上采样。

size – 一个包含两个整数的元组 (H_out, W_out)指定了输出的长宽,scale_factor – 长和宽的一个乘子。
在这里插入图片描述
代码使用与最近邻插值基本一样,他的原理相对烦一点,想详细了解的可以参考这篇博客:CV03-双线性差值pytorch实现

五、pytorch有一个函数可以直接代替上面两种插值方法使用,interpolate函数

interpolate函数即为:torch.nn.functional.interpolate(input,size=None,scale_factor=None,mode='nearest',align_corners=None),

其中scale_factor 在高度、宽度和深度上面的放大倍数。mode 上采样的方法,包括最近邻(nearest),线性插值(linear),双线性插值(bilinear),三次线性插值(trilinear),默认是最近邻(nearest)。使用起来很方便。

六、转置卷积操作

pytorch中的转置卷积函数:nn.ConvTranspose2d(in_channels=, out_channels=, kernel_size=, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1)
函数的使用按照自己需要的得到的通道数和尺寸来设计参数,具体公式如下:
在这里插入图片描述

x = torch.ones((1, 3, 3, 3))
ct = nn.ConvTranspose2d(in_channels=3, out_channels=1, kernel_size=3, stride=2, padding=1, output_padding=0)
print(ct(x).shape)		# 最后的输出为torch.Size([1, 1, 5, 5])

具体的原理比较复杂,可以参考这篇博客,讲的比较详细:抽丝剥茧,带你理解转置卷积(反卷积)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值