卷积函数

注:
函数语法、参数介绍、shape、变量、Example,均转自 PyTorch 中文手册
说实话 PyTorch 中文手册 对于参数in_channelsout_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 or tuple) - 卷积核的尺寸
  • stride(int or tuple, optional) - 卷积步长
  • padding (int or tuple, optional)- 输入的每一条边补充0的层数
  • dilation(int or tuple, optional) – 卷积核元素之间的间距
  • groups(int, optional) – 从输入通道到输出通道的阻塞连接数
  • bias(bool, optional) - 如果bias=True,添加偏置

shape

  • 一维卷积层:
    输入: (N,Cin,Lin)
    输出: (N,Cout,Lout)
    输入输出的计算方式
    pytorch 卷积vae pytorch 卷积层函数_卷积
  • 二维卷积层:
    输入: (N,C_in,H_in,W_in)
    输出: (N,C_out,H_out,W_out)
    输入输出的计算方式
    pytorch 卷积vae pytorch 卷积层函数_Pytorch_02pytorch 卷积vae pytorch 卷积层函数_卷积_03
  • 三维卷积层
    输入: (N,C_in,D_in,H_in,W_in)
    输出: (N,C_out,D_out,H_out,W_out)
    输入输出的计算方式
    pytorch 卷积vae pytorch 卷积层函数_Conv2d_04pytorch 卷积vae pytorch 卷积层函数_卷积_05pytorch 卷积vae pytorch 卷积层函数_Pytorch_06

变量

  • 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 dilation
 m = 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_channelsout_channels的意义(参考文首博客):

nn.Conv2d()为例(因为Conv2d用来处理图像问题,而且nn.的使用频率大于F.

in_channels指输入图像的通道数。
灰度图像in_channels1RGB图像的in_channels3(忽略alpha通道)。

out_channels直观理解是输入图像经过该卷积层之后的输出通道数。往深里说是“这个卷积核将输入图像从多少个通道 映射 到多少个通道上”。
而这个输出通道数,其实就是卷积核的种类数一种卷积核对应一个输出通道)。
对于卷积核的种类数的种类数,在后面的示例中会有更直观的体现。

再单独把计算输出维度(非通道)的公式拿出来(默认步长stride = 1)

  • 不加padding:out_size = in_size - kernel_size + 1
  • 加padding:out_size = in_size + 2*padding - kernel_size + 1

当步长stride2 时,把步长stride为 1 时的out_size2 即可。

基本用法的示例:

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,注意改视作操作可视作解卷积操作,但并不是真正的解卷积操作) 该模块可以看作是Conv1dConv2d、相对于其输入的梯度,有时(但不正确地)被称为解卷积操作

三维的转置卷积操作(transposed convolution operator,注意改视作操作可视作解卷积操作,但并不是真正的解卷积操作) 转置卷积操作将每个输入值和一个可学习权重的卷积核相乘,输出所有输入通道的求和。
该模块可以看作是Conv3d相对于其输入的梯度,有时(但不正确地)被称为解卷积操作

注意
由于内核的大小,输入的最后的一些列的数据可能会丢失。因为输入和输出不是完全的互相关。因此,用户可以进行适当的填充(padding操作)。

参数

  • in_channels(int) – 输入信号的通道数
  • out_channels(int) – 卷积产生的通道
  • kernel_size(int or tuple) - 卷积核的大小
  • stride(int or tuple, optional) - 卷积步长
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数
  • output_padding(int or tuple, optional) - 输出的每一条边补充0的层数
  • dilation(int or tuple, optional) – 卷积核元素之间的间距
  • groups(int, optional) – 从输入通道到输出通道的阻塞连接数
  • bias(bool, optional) - 如果bias=True,添加偏置

shape:

  • 一维解卷积
    输入: (N,C_in,L_in)
    输出: (N,C_out,L_out)
    pytorch 卷积vae pytorch 卷积层函数_ide_07
  • 二维转置卷积
    输入: (N,C_in,H_in,W_in)
    输出: (N,C_out,H_out,W_out)
    pytorch 卷积vae pytorch 卷积层函数_pytorch 卷积vae_08 pytorch 卷积vae pytorch 卷积层函数_pytorch 卷积vae_09
  • 三维转置卷积
    输入: (N,C_in,H_in,W_in)
    输出: (N,C_out,H_out,W_out)
    pytorch 卷积vae pytorch 卷积层函数_ide_10 pytorch 卷积vae pytorch 卷积层函数_ide_11 pytorch 卷积vae pytorch 卷积层函数_卷积_12

变量:

  • 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)