当前位置:网站首页>【CNN基础】转置卷积学习笔记
【CNN基础】转置卷积学习笔记
2022-08-04 07:37:00 【sin(豪)】
目录
1. 转置卷积的直观理解
1.1 卷积和转置卷积
卷积的直观理解:卷积用来抽取输入的特征,底层的卷积抽取的是纹理、颜色等底层特征,上层的卷积抽取的是语义特征。卷积的输出一般称为feature map,在pytorch中一般为四维的tensor:[B, C, H, W],其中,
B | batch size,一个小批量中的图片个数 |
---|---|
C | 通道数,输入图片一般有R,G,B三个通道,一般情况下后续feature map的H和W减少, 通道数C增加,保证信息不损失 |
H,W | feature map的高H和宽W |
卷积我们可以看作是将输入图片的H和W逐层减少,通道数C逐层增加的操作。
转置卷积的直观理解:转置卷积直观上是想将H和W较小的feature map还原到输入图像尺寸的过程。注意,只是将尺寸还原到和输入图像相同,具体的权重是不同的。这样做是因为在某些应用如语义分割中,最后要求的输出是一个和输入尺寸相同的feature map,而不是像图像分类要求的输出是一个一维的tensor。
简单来说:
1. 卷积是让feature map尺寸减小,通道数增加;而转置卷积是让feature map尺寸增大,通道数减小。
2.卷积做下采样,转置卷积做上采用。
3. 如果卷积操作使得输入feature map由(h, w)变为(h’, w’),则同样超参数下,转置卷积操作会使得feature map由(h’, w’)变为(h, w)。
2. 转置卷积的计算过程
我之前写了计算卷积操作输出Feature Map的size和计算机如何计算卷积操作。
下面介绍两种计算转置卷积输出结果的思路。
2.1 思路一:将转置卷积看成几个矩阵相加
假设转置卷积的步幅stride=1,填充padding=0。假设输入为X,卷积核为K,输出为Y,则:
其中,h,w为卷积核的高和宽,下面的示意图比较容易看明白具体的含义:
图片来源:【李沐】动手学深度学习
我们用pytorch简单实验下看看:
import torch
from torch import nn
X = torch.arange(4.).reshape(1, 1, 2, 2) # 从前到后分别代表:batch size, channel, h, w
K = torch.arange(4.).reshape(1, 1, 2, 2)
tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, stride=1, padding=0, bias=False)
tconv.weight.data = K
print(f"X:\n{
X}\nK:\n{
tconv.weight.data}")
Y = tconv(X)
print(f"Y:\n{
Y.data}")
输出:
X:
tensor([[[[0., 1.],
[2., 3.]]]])
K:
tensor([[[[0., 1.],
[2., 3.]]]])
Y:
tensor([[[[ 0., 0., 1.],
[ 0., 4., 6.],
[ 4., 12., 9.]]]])
当stride=2, padding=0时,计算过程如下:
我们用pytorch简单实验下看看:
X = torch.arange(4.).reshape(1, 1, 2, 2) # 从前到后分别代表:batch size, channel, h, w
K = torch.arange(4.).reshape(1, 1, 2, 2)
tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, stride=2, padding=0, bias=False)
tconv.weight.data = K
print(f"X:\n{
X}\nK:\n{
tconv.weight.data}")
Y = tconv(X)
print(f"Y:\n{
Y.data}")
输出:
X:
tensor([[[[0., 1.],
[2., 3.]]]])
K:
tensor([[[[0., 1.],
[2., 3.]]]])
Y:
tensor([[[[0., 0., 0., 1.],
[0., 0., 2., 3.],
[0., 2., 0., 3.],
[4., 6., 6., 9.]]]])
2.2 思路二:转置卷积是一种卷积
个人感觉这个计算思路更加通用一些,不需要像思路一一样涉及几个矩阵的相加,直接一开始就将转置卷积当作卷积来做。
p为填充padding,s为步幅stride,k为卷积核大小,则具体计算过程如下:
计算过程示意图为:
s = 1, p = 0, k = 2
s = 1, p = 1, k = 3
用Pytorch简单实验下:
X = torch.arange(16.).reshape(1, 1, 4, 4) # 从前到后分别代表:batch size, channel, h, w
K = torch.tensor([[1., 1., 1.], [1., 0., 0.], [0., 0., 0.]]).reshape(1, 1, 3, 3)
tconv = nn.ConvTranspose2d(1, 1, kernel_size=3, stride=1, padding=1, bias=False)
tconv.weight.data = K
print(f"X:\n{
X}\nK:\n{
tconv.weight.data}")
Y = tconv(X)
print(f"Y:\n{
Y.data}")
输出:
X:
tensor([[[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]]])
K:
tensor([[[[1., 1., 1.],
[1., 0., 0.],
[0., 0., 0.]]]])
Y:
tensor([[[[10., 17., 21., 13.],
[22., 33., 37., 21.],
[34., 49., 53., 29.],
[13., 14., 15., 0.]]]])
3. 如何计算转置卷积输出feature map的size
我们规定:
符号 | 含义 |
---|---|
n | 输入feature map的高宽 |
k | 转置卷积核的高宽 |
p | 填充padding |
s | 步幅stride |
则:转置卷积输出的feature map 的大小 n’ = sn + k - 2p - s
因此,如果想让高宽整数倍增加,则要求:k - 2p - s = 0,即k = 2p + s。
Pytorch做实验:
# n = 10, k = 64, s = 32, p = 16
X = torch.arange(100.).reshape(1, 1, 10, 10) # 从前到后分别代表:batch size, channel, h, w
tconv = nn.ConvTranspose2d(1, 1, kernel_size=64, stride=32, padding=16, bias=False)
Y = tconv(X)
Y.shape
输出:
torch.Size([1, 1, 320, 320])
可以看到输出size相较于输入扩大了32倍。(由10x10到320x320)
参考:
边栏推荐
- Lightweight Backbone VGNetG Achieves "No Choice, All" Lightweight Backbone Network
- 全国职业院校技能大赛网络安全竞赛之应急响应
- C# 实用的第三方库
- The national vocational skills contest competition of network security emergency response
- 将回调函数转为Flow
- 使用requests post请求爬取申万一级行业指数行情
- 一天学会JDBC04:ResultSet的用法
- 『递归』递归概念与典型实例
- data:image/jpg;base64格式数据转化为图片
- <jsp:useBean>动作的使用
猜你喜欢
随机推荐
经典新诗九首
虚拟机没有USB网卡选项怎么解决
经典动态规划问题的递归实现方法——LeetCode39 组合总和
安装GBase 8c数据库的时候,报错显示“Resource:gbase8c already in use”,这怎么处理呢?
FCN - the originator of semantic segmentation (based on tf-Kersa reproduction code)
Typora颜色公式代码大全
两日总结七
金仓数据库KingbaseES客户端编程接口指南-JDBC(9. JDBC 读写分离)
Cross-species regulatory sequence activity prediction
Secondary network security competition C module MS17-010 batch scanning
并查集介绍和基于并查集解决问题——LeetCode 952 按公因数计算最大组件大小
解决报错: YarnScheduler: Initial job has not accepted any resources
24.循环神经网络RNN
金仓数据库的单节点如何转集群?
一天搞定JDBC02:开启事务
在线问题反馈模块实战(十八):实现excel台账文件记录批量导入功能
C语言指针
在GBase 8c数据库后台,使用什么样的命令来对gtm、dn节点进行主备切换的操作?
leetcode 22.7.31(1)两数之和 (2)整数除法
一天学会JDBC06:PrepaerdStatemtnt