图片中的上采样,下采样和通道融合(up-sample, down-sample, channel confusion)

前言

以conv2d为例(即图片),Pytorch中输入的数据格式为tensor,格式为:

[N, C, W, H, W]

  • 第一维N.代表图片个数,类似一个batch里面有N张图片
  • 第二维C. 代表通道数,
    在模型中输入如果为彩色,常用RGB三色图,那么就是3维,即C=3。如果是黑白的,即灰度图,那么只有一个通道,即C=1
  • 第三维H. 代表图片的高度,H的数量是图片像素的列数
  • 第四维W. 代表图片的宽度,W的数量是图片像素的行数
    如果H=W,那么图片是正方形的,总像素为H*W, 和分辨率是同义词。

1.通过池化完成下采样(down-sample)

这个就是融合HW的信息,降低其维度,例如分辨率为[1024,1024]的图像,降低为[512,512],类似压缩。
常用池化pooling完成,pooling常见用平均池化和最大池化,其实就是把周围像素的平均值压缩为其平均值,还是压缩为其中像素的最大值,效果上有一点差异。

  • Pytoch代码如下(平均池化avg):
import torch
import torch.nn as nn
x = torch.randn(5,3,8,8)#5张彩色图片(即有RGB,3个通道)。图像分辨率为8*8
avg = nn.AvgPool2d(2)#参数的意思是2倍池化,其实就是压缩为原来的1/2
y = avg(x)
print(y.shape)#[5,3,4,4]

2.通过插值完成上采样(up-sample)

和下采样相反,图片的上采样是完成图片的“解压缩”操作,即把原先的图片放大[512,512]->[1024,1024]。 插值的意思就是在原有像素之间插入和周围像素相同或类似的值(插值也有几种方式,插入和周围一样的值是最基础的方式)。另外注意这样的放大会造成图片模糊。

  • Pytoch代码如下(默认插值方法):
import torch
import torch.nn as nn
x = torch.randn(5,3,8,8)#5张彩色图片(即有RGB,3个通道)。图像分辨率为8*8
insert = nn.functional.interpolate(x,scale_factor=2)#2倍插值,效果是图片像素放大为原来的2倍
y = insert(x)
print(y.shape)#[5,3,16,16]

3.通过1*1卷积核完成上下采样

这个在深度模型中比较流行,主要是深度模型的基础层大多是卷积核尺寸为33和44,加上cudann对卷积核运算的加成,这个操作比较灵活,即可完成对图片像素的上下采样,也可以完成通道维度C的压缩和扩张。

  • 下采样像素
    通过卷积核的移动步数 (即操作stride参数)。可以这么理解,即stride是卷积核移动的步数,步子大了,就能压缩像素。(注意步子太大容易扯着蛋)
  • 上采样像素
    通过控制对输入数据的填充 (即操作padding参数)。填充大了,即操作的输入像素变大了,那么一轮1核卷积计算,输出的像素也就大了
  • 融合通道,这个也比较简单,之间默认卷积核的stride和padding,改变conv2d的通道输入和输出即可,可以随意改变输入和输出的大小。但是要注意,如果输入和输出的通道数相差太多的化,信息损失就越严重。
import torch
import torch.nn as nn
x = torch.randn(5,3,8,8)#5张彩色图片(即有RGB,3个通道)。图像分辨率为8*8

#-----------dowm sample--------------
#参数1代表输入通道C为3,
#参数2代表输出通道C为也为3,
#参数3代表卷积核尺寸为1
#参数4代表步数为2.其他默认(如padding为1)
conv1k2s = nn.Conv2d(3,3,1,stride=2)
y = insert(x)
print(y.shape)#[5,3,4,4]

#----------------up sample---------------
#参数1代表输入通道C为3,
#参数2代表输出通道C为也为3,
#参数3代表卷积核尺寸为1
#参数4代表输入图片填充为2.其他默认(如stride为1)
conv1k2p = nn.Conv2d(3,3,1,padding=2)
y = conv1k2p(x)
print(y.shape)#[5,3,12,12],由8*8->12*12

#------------------channel confusion----------
conv1k_upC = nn.Conv2d(3,6,1)
y = conv1k_upC(x)
print(y.shape)#[5,6,8,8],通道由3升为6

conv1k_downC = nn.Conv2d(3,1,1)
y = conv1k_downC(x)
print(y.shape)#5,1,8,8],通道降为1
  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值