[PyTorch] 卷积函数 and 解卷积函数
卷积函数
注:
函数语法、参数介绍、shape、变量、Example,均转自 PyTorch 中文手册。
说实话 PyTorch 中文手册 对于参数in_channels
和out_channels
的讲解还是不够详细。
所以我参考了另一篇博客 【PyTorch学习笔记】17:2D卷积,nn.Conv2d和F.conv2d 来讲解这两个参数的意义。
函数语法:
- 一维
class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
- 二维
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
- 三维
class torch.nn.Conv3d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
关于卷积层函数各参数的含义,详见Convolution arithmetic
,其动态图演示很形象。
参数介绍:
- in_channels(
int
) – 输入信号的通道 - out_channels(
int
) – 卷积产生的通道 - kerner_size(
int
ortuple
) - 卷积核的尺寸 - stride(
int
ortuple
,optional
) - 卷积步长 - padding (
int
ortuple
,optional
)- 输入的每一条边补充0的层数 - dilation(
int
ortuple
,optional
) – 卷积核元素之间的间距 - groups(
int
,optional
) – 从输入通道到输出通道的阻塞连接数 - bias(
bool
,optional
) - 如果bias=True,添加偏置
shape:
一维卷积层:
输入: (N,Cin,Lin)
输出: (N,Cout,Lout)
输入输出的计算方式
Lout=floor((Lin+2padding−dilation(kernerlsize−1)−1)/stride+1)L_{out}=floor((L_{in}+2padding-dilation(kernerl_size-1)-1)/stride+1)Lout=floor((Lin+2padding−dilation(kernerlsize−1)−1)/stride+1)二维卷积层:
输入: (N,C_in,H_in,W_in)
输出: (N,C_out,H_out,W_out)
输入输出的计算方式
Hout=floor((Hin+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)H_{out}=floor((H_{in}+2padding[0]-dilation[0](kernerl_size[0]-1)-1)/stride[0]+1)Hout=floor((Hin+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)Wout=floor((Win+2padding[1]−dilation[1](kernerlsize[1]−1)−1)/stride[1]+1)W_{out}=floor((W_{in}+2padding[1]-dilation[1](kernerl_size[1]-1)-1)/stride[1]+1)Wout=floor((Win+2padding[1]−dilation[1](kernerlsize[1]−1)−1)/stride[1]+1)三维卷积层
输入: (N,C_in,D_in,H_in,W_in)
输出: (N,C_out,D_out,H_out,W_out)
输入输出的计算方式
Dout=floor((Din+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)D_{out}=floor((D_{in}+2padding[0]-dilation[0](kernerl_size[0]-1)-1)/stride[0]+1)Dout=floor((Din+2padding[0]−dilation[0](kernerlsize[0]−1)−1)/stride[0]+1)Hout=floor((Hin+2padding[1]−dilation[2](kernerlsize[1]−1)−1)/stride[1]+1)H_{out}=floor((H_{in}+2padding[1]-dilation[2](kernerl_size[1]-1)-1)/stride[1]+1)Hout=floor((Hin+2padding[1]−dilation[2](kernerlsize[1]−1)−1)/stride[1]+1)Wout=floor((Win+2padding[2]−dilation[2](kernerlsize[2]−1)−1)/stride[2]+1)W_{out}=floor((W_{in}+2padding[2]-dilation[2](kernerl_size[2]-1)-1)/stride[2]+1)Wout=floor((Win+2padding[2]−dilation[2](kernerlsize[2]−1)−1)/stride[2]+1)
变量
- weight(
tensor
) - 卷积的权重,大小是(out_channels
,in_channels
,kernel_size
) - bias(
tensor
) - 卷积的偏置系数,大小是(out_channel
)
Example:
一维卷积层
m = nn.Conv1d(16, 33, 3, stride=2)
input = autograd.Variable(torch.randn(20, 16, 50))
output = m(input)
二维卷积层
# With square kernels and equal stride
m = nn.Conv2d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
# non-square kernels and unequal stride and with padding and dilationm = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)
三维卷积层
# With square kernels and equal stride
m = nn.Conv3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(4, 2, 0))
input = autograd.Variable(torch.randn(20, 16, 10, 50, 100))
output = m(input)
参数in_channels
和 out_channels
的意义(参考文首博客):
以nn.Conv2d()
为例(因为Conv2d
用来处理图像问题,而且nn.
的使用频率大于F.
)
in_channels
指输入图像的通道数。
如灰度图像的in_channels
为 1;RGB图像的in_channels
为 3(忽略alpha通道)。
out_channels
直观理解是输入图像经过该卷积层之后的输出通道数。往深里说是“这个卷积核将输入图像从多少个通道 映射 到多少个通道上”。
而这个输出通道数,其实就是卷积核的种类数(一种卷积核对应一个输出通道)。
对于卷积核的种类数的种类数,在后面的示例中会有更直观的体现。
再单独把计算输出维度(非通道)的公式拿出来(默认步长stride
= 1)
- 不加padding:out_size = in_size - kernel_size + 1
- 加padding:out_size = in_size + 2*padding - kernel_size + 1
当步长stride
为 2 时,把步长stride
为 1 时的out_size
除 2 即可。
基本用法的示例:
import torch
from torch import nn"""2维的卷积层,用于图片的卷积"""
# 输入图像的通道数=1(灰度图像),卷积核的种类数=3
# 卷积核的shape是3乘3的,扫描步长为1,不加padding
layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=0)"""要输入的原始图像"""
# 样本数=1,通道数=1,图像的shape是28乘28的
x = torch.rand(1, 1, 28, 28)"""使用上面定义的卷积层layer和输入x,完成一次卷积的前向运算"""
out = layer.forward(x)
# 得到的还是1张图片,因为用了3种kernel所以输出的通道数变成3了
# 因为没加padding,原来28乘28的图像在3乘3卷积下得到的边长是28-3+1=26
print(out.shape) # torch.Size([1, 3, 26, 26])"""添加padding看看"""
# 这次使用padding为1.所以原始图像上下左右都加了一层0
layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=1)
print(layer.forward(x).shape) # torch.Size([1, 3, 28, 28])"""步长设置为2看看"""
# stride设置为2,也就是每次移动2格子(向上或者向右)
layer = nn.Conv2d(1, 3, kernel_size=3, stride=2, padding=1)
# 相当于每次跳1个像素地扫描,输出的Feature Map直接小了一半
print(layer.forward(x).shape) # torch.Size([1, 3, 14, 14])"""实际使用时,应该这样用!"""
out = layer(x)
print(out.shape) # torch.Size([1, 3, 14, 14])
运行结果:
torch.Size([1, 3, 26, 26])
torch.Size([1, 3, 28, 28])
torch.Size([1, 3, 14, 14])
torch.Size([1, 3, 14, 14])
查看卷积层信息:
print(layer.weight)
print(layer.bias)
tensor([[[[ 0.1277, -0.1672, 0.1102],[ 0.3176, 0.0236, 0.2537],[ 0.0737, 0.0904, 0.0261]]],[[[ 0.0349, -0.2042, 0.1766],[-0.0938, -0.0470, 0.2011],[-0.2460, 0.0876, 0.3124]]],[[[-0.2361, -0.0971, -0.1031],[-0.0756, -0.3073, 0.3227],[-0.1951, -0.2395, -0.0769]]]], requires_grad=True)Parameter containing:
tensor([ 0.0790, -0.3261, 0.0697], requires_grad=True)
解卷积函数(可近似视为)
- 一维
class torch.nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
- 二维
class torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
- 三维
torch.nn.ConvTranspose3d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
一维的解卷积操作、二维的转置卷积操作(transposed convolution operator
,注意改视作操作可视作解卷积操作,但并不是真正的解卷积操作) 该模块可以看作是Conv1d
、Conv2d
、相对于其输入的梯度,有时(但不正确地)被称为解卷积操作。
三维的转置卷积操作(transposed convolution operator
,注意改视作操作可视作解卷积操作,但并不是真正的解卷积操作) 转置卷积操作将每个输入值和一个可学习权重的卷积核相乘,输出所有输入通道的求和。
该模块可以看作是Conv3d
相对于其输入的梯度,有时(但不正确地)被称为解卷积操作。
注意
由于内核的大小,输入的最后的一些列的数据可能会丢失。因为输入和输出不是完全的互相关。因此,用户可以进行适当的填充(padding操作)。
参数
- in_channels(
int
) – 输入信号的通道数 - out_channels(
int
) – 卷积产生的通道 - kernel_size(
int
ortuple
) - 卷积核的大小 - stride(
int
ortuple
,optional
) - 卷积步长 - padding(
int
ortuple
,optional
) - 输入的每一条边补充0的层数 - output_padding(
int
ortuple
,optional
) - 输出的每一条边补充0的层数 - dilation(
int
ortuple
,optional
) – 卷积核元素之间的间距 - groups(
int
,optional
) – 从输入通道到输出通道的阻塞连接数 - bias(
bool
,optional
) - 如果bias=True,添加偏置
shape:
- 一维解卷积
输入: (N,C_in,L_in)
输出: (N,C_out,L_out)
Lout=(Lin−1)stride−2padding+kernelsize+outputpaddingL_{out}=(L_{in}-1)stride-2padding+kernel_size+output_paddingLout=(Lin−1)stride−2padding+kernelsize+outputpadding - 二维转置卷积
输入: (N,C_in,H_in,W_in)
输出: (N,C_out,H_out,W_out)
Hout=(Hin−1)stride[0]−2padding[0]+kernelsize[0]+outputpadding[0]H_{out}=(H_{in}-1)stride[0]-2padding[0]+kernel_size[0]+output_padding[0]Hout=(Hin−1)stride[0]−2padding[0]+kernelsize[0]+outputpadding[0] Wout=(Win−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[1]W_{out}=(W_{in}-1)stride[1]-2padding[1]+kernel_size[1]+output_padding[1]Wout=(Win−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[1] - 三维转置卷积
输入: (N,C_in,H_in,W_in)
输出: (N,C_out,H_out,W_out)
Dout=(Din−1)stride[0]−2padding[0]+kernelsize[0]+outputpadding[0]D_{out}=(D_{in}-1)stride[0]-2padding[0]+kernel_size[0]+output_padding[0]Dout=(Din−1)stride[0]−2padding[0]+kernelsize[0]+outputpadding[0] Hout=(Hin−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[0]H_{out}=(H_{in}-1)stride[1]-2padding[1]+kernel_size[1]+output_padding[0]Hout=(Hin−1)stride[1]−2padding[1]+kernelsize[1]+outputpadding[0] Wout=(Win−1)stride[2]−2padding[2]+kernelsize[2]+outputpadding[2]W_{out}=(W_{in}-1)stride[2]-2padding[2]+kernel_size[2]+output_padding[2]Wout=(Win−1)stride[2]−2padding[2]+kernelsize[2]+outputpadding[2]
变量:
- weight(
tensor
) - 卷积的权重,大小是(in_channels
,in_channels
,kernel_size
) - bias(
tensor
) - 卷积的偏置系数,大小是(out_channel
)
Example:
二维
# With square kernels and equal stride
m = nn.ConvTranspose2d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.ConvTranspose2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)
# exact output size can be also specified as an argument
input = autograd.Variable(torch.randn(1, 16, 12, 12))
downsample = nn.Conv2d(16, 16, 3, stride=2, padding=1)
upsample = nn.ConvTranspose2d(16, 16, 3, stride=2, padding=1)
h = downsample(input)
h.size()
# torch.Size([1, 16, 6, 6])
output = upsample(h, output_size=input.size())
output.size()
# torch.Size([1, 16, 12, 12])
三维
# With square kernels and equal stride
m = nn.ConvTranspose3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(0, 4, 2))
input = autograd.Variable(torch.randn(20, 16, 10, 50, 100))
output = m(input)
[PyTorch] 卷积函数 and 解卷积函数相关推荐
- gather torch_浅谈Pytorch中的torch.gather函数的含义
pytorch中的gather函数 pytorch比tensorflow更加编程友好,所以准备用pytorch试着做最近要做的一些实验. 立个flag开始学习pytorch,新开一个分类整理学习pyt ...
- matlab狄利克雷函数,数论入门1——莫比乌斯函数,欧拉函数,狄利克雷卷积,线性筛,莫比乌斯反演,杜教筛...
数论入门1 一个菜鸡对数论的一点点理解... 莫比乌斯函数 定义函数$\mu(n)$为: 当n有平方因子时,$\mu(n)=0$. 当n没有平方因子时,$\mu(n)=(-1)^{\omega(n)} ...
- 狄利克雷卷积_积性函数和狄利克雷卷积小结
1.积性函数:对于函数$f(n)$,若满足对任意互质的数字a,b,a*b=n且$f(n)=f(a)f(b)$,那么称函数f为积性函数.显然f(1)=1. 2.狄利克雷卷积:对于函数f,g,定义它们的卷 ...
- python中squeeze函数_详解pytorch中squeeze()和unsqueeze()函数介绍
squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...
- pytorch自定义forward和backward函数
pytorch会自动求导,但是当遇到无法自动求导的时候,需要自己认为定义求导过程,这个时候就涉及到要定义自己的forward和backward函数. 举例如下: 看到这里,大家应该会有很多疑问,比如: ...
- pytorch 中 expand ()函数
pytorch 中 expand ()函数 expand函数的功能就是 用来扩展张量中某维数据的尺寸,它返回输入张量在某维扩展为更大尺寸后的张量. 例如: x = torch.tensor([1, 2 ...
- OpenCV 图像卷积:cv.filter2D() 函数详解
API 照例,我们搬一下官网的 API: C++ void cv::filter2D(InputArray src,OutputArray dst,int ddepth,InputArray kern ...
- **Pytorch 中view函数和reshape函数的区别*
Pytorch 中view函数和reshape函数的区别(我是一名大一刚学计算机的学生 希望我的说法对你有帮助) 首先:要了解这个问题我们要先了解一个基本知识 张量的储存方式 跟据图片我们可以清楚的看 ...
- [一起学习pytorch吧]之torch.sign函数
Hello,大家好!今天为大家讲解以下pytorch的sign函数. torch.sign(input, out=None) → Tensor 该函数的作用就是输出input通过sign函数后的张量, ...
最新文章
- 使用RNN神经网络自动生成名字 (不使用深度学习框架,源码)
- ios 接收 c# socket udp 组播
- 【零基础】了解一下前端HTML与CSS
- 使用dwz框架配合MVC使用
- Cannot check for MySQL Daemon startup because of mysqladmin failure
- python 温度插值nan处理_Python处理inf和Nan值,pytorch,nan,数值
- vue --- 修饰符.lazy、.number、.trim
- springboot系列(十)springboot整合shiro实现登录认证
- (三)Appium-desktop 打包
- 一人身兼多个项目时的“课程表”工作模式实践
- 国产达梦数据库管理系统-通过Excel文件导入数据
- ppt生成eps文件_eps是什么格式怎么打开?全面解析图片的eps是什么格式
- win10计算机删除了怎么恢复,win10文件误删除怎么恢复-互盾数据恢复软件
- 在VB中如何使IE窗口最大化
- 完全数据驱动的对话模型和社交机器人
- 对面装修,办公室放置绿萝,袋装活性炭,空气净化器,有用吗?
- CentOS7安装Nextcloud+ocDownloader+aria2使用Nextcloud网盘做离线下载服务器
- 使用Quagga在Mininet节点上进行OSPF实验
- 异常处理try_except-else-finally
- 实对称阵的谱半径是连续函数
热门文章
- python入门-零基础 Python 入门
- python刚出来多少薪资-Python薪资待遇到底是多少?老男孩python学习
- python基础30个常用代码-即学即用的 30 段 Python 实用代码
- python和java选择哪个-Python和Java该如何选择?选哪个好?
- 有关语音识别技术的一些信息点
- mysql中Group_concat,查找列名,将字符串转换为数字比较大小等杂项记录
- java商城源码_盘点这些年被黑的最惨的语言,Java瑟瑟发抖
- Vue图片上传删除预览操作
- polyfill 与 transform-runtime
- perl linux 独立运行,Perl脚本打包为独立执行程序