当前位置:首页 » 《随便一记》 » 正文

PyTorch常用函数(5)_david123_xw的博客

19 人参与  2021年11月30日 12:03  分类 : 《随便一记》  评论

点击全文阅读


1. torch.Storage

一个 torch.Storage 是一个单一数据类型的连续一维数组。每个 torch.Tensor 都有一个对应的、相同数据类型的存储。

  • byte():将此存储转为byte类型
  • char():将此存储转为char类型
  • clone():返回此存储的一个副本
  • cpu():如果当前此存储不在 CPU 上,则返回一个它的 CPU 副本
  • cuda(device=None, async=False):返回此对象在 CUDA 内存中的一个副本。如果此对象已在 CUDA 内存中且在正确的设备上,那么不会执行复制操作,直接返回原对象。
    参数:
    (1)device (int) - 目标 GPU 的 id。默认值是当前设备。
    (2)async (bool) -如果值为 True,且源在锁定内存中,则副本相对于宿主是异步的。否则此参数不起效果。
  • double():将此存储转为 double 类型
  • float():将此存储转为 float 类型
  • half():将此存储转为 half 类型
  • int():将此存储转为 int 类型
  • long():将此存储转为 long 类型
  • short():将此存储转为 short 类型
  • tolist():返回一个包含此存储中元素的列表
  • type(new_type=None, async=False):将此对象转为指定类型。如果已经是正确类型,不会执行复制操作,直接返回原对象。参数:
    (1)new_type (type or string) -需要转成的类型
    (2)async (bool) -如果值为 True,且源在锁定内存中,则副本相对于宿主是异步的。否则此参数不起效果。

2.torch.nn

  • class torch.nn.Parameter()
    Variable 的一种,常被用于模块参数(module parameter)。Parameters 是 Variable 的子类。 Paramenters 和 Modules 一起使用的时候会有一些特殊的属性,即:当Paramenters 赋值给 Module 的属性的时候,他会自动的被加到 Module 的 参数列表中(即:会出现在 parameters() 迭代器中)。将 Varibale 赋值给 Module 属性则不会有这样的影响。 这样做的原因是:我们有时候会需要缓存一些临时的状态(state), 比如:模型中 RNN 的最后一个隐状态。如果没有Parameter 这个类的话,那么这些临时变量也会注册成为模型变量。Variable 与 Parameter 的另一个不同之处在于, Parameter 不能被 volatile(即:无法设置 volatile=True)而且默认 requires_grad=True。 Variable 默认 requires_grad=False。
  • class torch.nn.Module:所有网络的基类。你的模型也应该继承这个类
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)# submodule: Conv2d
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))

通过上面方式赋值的 submodule 会被注册。当调用 .cuda() 的时候,submodule 的参数也会转换为 cuda Tensor。

  • add_module(name, module):将一个 child module 添加到当前 modle。 被添加的 module 可以通过 name 属性来获取。
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
	super(Model, self).__init__()
	self.add_module("conv", nn.Conv2d(10, 20, 4))
	#self.conv = nn.Conv2d(10, 20, 4) 和上面这个增加 module 的方式等价
model = Model()
print(model.conv)
# Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
print(model.children())
  • children():返回当前模型 子模块的迭代器。
import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.add_module("conv", nn.Conv2d(10, 20, 4))
        self.add_module("conv1", nn.Conv2d(20 ,10, 4))
model = Model()
for sub_module in model.children():
    print(sub_module)
# Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
# Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))
  • cpu(device_id=None):将所有的模型参数(parameters)和 buffers 复制到 CPU
  • cuda(device_id=None):将所有的模型参数(parameters)和 buffers 赋值 GPU
  • eval():将模型设置成 evaluation 模式,仅仅当模型中有 Dropout 和 BatchNorm 是才会有影响。
  • float():将 parameters 和 buffers 的数据类型转换成 float。
  • forward(* input):定义了每次执行的 计算步骤。 在所有的子类中都需要重写这个函数。
  • half():将 parameters 和 buffers 的数据类型转换成 half。
  • load_state_dict(state_dict):将 state_dict 中的 parameters 和 buffers 复制到此 module 和它的子类中。 state_dict 中的 key 必须和 model.state_dict()返回的 key 一致。 NOTE:用来加载模型参数。
  • modules():返回一个包含 当前模型 所有模块的迭代器。
import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.add_module("conv", nn.Conv2d(10, 20, 4))
        self.add_module("conv1", nn.Conv2d(20 ,10, 4))
model = Model()
for module in model.modules():
    print(module)
# Model(
#   (conv): Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
#   (conv1): Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))
# )
# Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
# Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))

可以看出, modules()返回的 iterator 不止包含 子模块。这是和 children()的不同。NOTE: 重复的模块只被返回一次(children()也是)。 在下面的例子中, submodule 只会被返回一次:

import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        submodule = nn.Conv2d(10, 20, 4)
        self.add_module("conv", submodule )
        self.add_module("conv1", submodule )
model = Model()
for module in model.modules():
    print(module)
# Model(
#   (conv): Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
#   (conv1): Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))
# )
# Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
  • named_children():返回 包含 模型当前子模块 的 模块名字和模块本身的迭代器。
import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        submodule = nn.Conv2d(10, 20, 4)
        self.add_module("conv", submodule )
        self.add_module("conv1", submodule )
model = Model()
for name, module in model.named_children():
    if name in ["conv"]:
        print(module)
# Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))

注意:重复的模块只被返回一次(children()也是)。

  • parameters(memo=None):返回一个 包含模型所有参数 的迭代器。一般用来当作 optimizer 的参数。
import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.add_module("conv", nn.Conv2d(10, 20, 4))
        self.add_module("conv1", nn.Conv2d(20 ,10, 4))
model = Model()
for param in model.parameters():
	print(type(param.data), param.size())
# <class 'torch.Tensor'> torch.Size([20, 10, 4, 4])
# <class 'torch.Tensor'> torch.Size([20])
# <class 'torch.Tensor'> torch.Size([10, 20, 4, 4])
# <class 'torch.Tensor'> torch.Size([10])
  • register_backward_hook(hook):
    在 module 上注册一个 bachward hook。每次计算 module 的 inputs 的梯度的时候,这个 hook 会被调用。 hook 应该拥有下面的 signature。hook(module, grad_input, grad_output) -> Variable or None如果 module 有多个输入输出的话,那么 grad_input grad_output 将会是个 tuple。 hook 不应该修改它的arguments,但是它可以选择性的返回关于输入的梯度,这个返回的梯度在后续的计算中会替代grad_input。这个函数返回一个句柄(handle)。它有一个方法 handle.remove(),可以用这个方法将 hook 从 module移除。
  • register_buffer(name, tensor):给 module 添加一个 persistent buffer。persistent buffer 通常被用在这么一种情况:我们需要保存一个状态,但是这个状态不能看作成为模型参数。 例如: , BatchNorm’s running_mean 不是一个 parameter, 但是它也是需要保存的状态之一。Buffers 可以通过注册时候的 name 获取。
    NOTE:我们可以用 buffer 保存移动平均
self.register_buffer('running_mean', torch.zeros(num_features))
  • register_forward_hook(hook):在 module 上注册一个 forward hook。 每次调用forward()计算输出的时候,这个 hook 就会被调用。它应该拥有以下签名:hook(module, input, output) -> None,hook 不 应 该 修 改 input 和 output 的 值 。 这 个 函 数 返 回 一 个 句 柄 (handle) 。 它 有 一 个 方 法 handle.remove(),可以用这个方法将 hook 从 module 移除。
  • register_parameter(name, param):向 module 添加 parameter。parameter 可以通过注册时候的 name 获取。
  • state_dict(destination=None, prefix=’’):返回一个字典,保存着module的所有状态。parameters和persistent buffers都会包含在字典中,字典的key就是parameter和buffer的names。
import torch
import torch.nn as nn
class Model(nn.Module):
	def __init__(self):
		super(Model, self).__init__()
		self.conv2 = nn.Linear(1,2)
		self.vari = torch.rand([1])
		self.par = torch.rand([1])
		self.register_buffer("buffer", torch.randn([2,3]))
model = Model()
print(model.state_dict().keys())
# odict_keys(['buffer', 'conv2.weight', 'conv2.bias'])		
  • train(mode=True):将 module 设置为 training mode。仅仅当模型中有 Dropout 和 BatchNorm 是才会有影响。
  • zero_grad():将 module 中的所有模型参数的梯度设置为 0.
  • class torch.nn.Sequential(* args):一个时序容器。 Modules 会以他们传入的顺序被添加到容器中。当然,也可以传入一个 OrderedDict。为了更容易的理解如何使用 Sequential, 下面给出了一个例子:
import torch
import torch.nn as nn
from collections import OrderedDict
model1 = nn.Sequential(nn.Conv2d(1, 20, 5),
						nn.ReLU(),
						nn.Conv2d(20,64,5),
						nn.ReLU())
model2 = nn.Sequential(OrderedDict([
						("conv1",nn.Conv2d(1, 20, 5)),
						("relu1",nn.ReLU()),
						("conv2",nn.Conv2d(20, 64, 5)),
						("relu2",nn.ReLU())
						]))
print(model1.state_dict().keys())
print(model2.state_dict().keys())
# odict_keys(['0.weight', '0.bias', '2.weight', '2.bias'])
# odict_keys(['conv1.weight', 'conv1.bias', 'conv2.weight', 'conv2.bias'])
  • class torch.nn.ModuleList(modules=None):将 submodules 保存在一个 list 中。ModuleList 可以像一般的 Python list 一样被索引。而且 ModuleList 中包含的 modules 已经被正确的注册,对所有的 module method 可见。

import torch
from torch import nn
class MyModule(nn.Module):
	def __init__(self):
		super(MyModule, self).__init__()
		self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
	def forward(self, x):
		for i, l in enumerate(self.linears):
			x = self.linears[i//2](x) + l(x)
		return x
model1 = MyModule()
print(model1.state_dict().keys())
# odict_keys(['linears.0.weight', 'linears.0.bias', 'linears.1.weight', 
# 'linears.1.bias', 'linears.2.weight', 'linears.2.bias', 'linears.3.weight', 
# 'linears.3.bias', 'linears.4.weight', 'linears.4.bias', 'linears.5.weight', 
# 'linears.5.bias', 'linears.6.weight', 'linears.6.bias', 'linears.7.weight', 
# 'linears.7.bias', 'linears.8.weight', 'linears.8.bias', 'linears.9.weight',
# 'linears.9.bias'])
  • class torch.nn.ParameterList(parameters=None):ParameterList 可以像一般的 Python list 一样被索引。而且 ParameterList 中包含的 parameters 已经被正确的注册,对所有的 module method 可见。
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.params = nn.ParameterList([nn.Parameter(torch.randn(10, 10)) for i in range(10)])

    def forward(self, x):
        # ParameterList can act as an iterable, or be indexed using ints
        for i, p in enumerate(self.params):
            x = self.params[i // 2].mm(x) + p.mm(x)
        return x

有像python一样的append和extend方法。

3.卷积层

  • class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True):一维卷积层,输入的尺度是 ( N , C i n , L ) (N, C_{in},L) (N,Cin,L),输出尺度 ( N , C o u t , L o u t ) ( N,C_{out},L_{out}) N,Cout,Lout的计算方式:
    o u t ( N i , C o u t j ) = b i a s ( C o u t j ) + ∑ k = 0 C i n − 1 w e i g h t ( C o u t j , k ) ⨂ i n p u t ( N i , k ) out(N_i, C_{out_j})=bias(C {out_j})+\sum^{C{in}-1}_{k=0}weight(C{out_j},k)\bigotimes input(N_i,k) out(Ni,Coutj)=bias(Coutj)+k=0Cin1weight(Coutj,k)input(Ni,k)
    主要参数:
    (1)dilation:用于控制kernel的核点之间的距离,参考这里
    (2)groups:控制输入和输出之间的连接, group=1,输出是所有的输入的卷积; group=2,此时相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将这两个输出连接起来。
    假设输入尺度: ( N , C i n , L i n ) (N, C_{in},L_{in}) (N,Cin,Lin),输出尺度 ( N , C o u t , L o u t ) (N, C_{out},L_{out}) (N,Cout,Lout),输入输出的计算方式: L o u t = f l o o r ( ( L i n + 2 p a d d i n g − d i l a t i o n ( k e r n e r l _ s i z e − 1 ) − 1 ) / s t r i d e + 1 ) L_{out}=floor((L_{in}+2padding-dilation(kernerl\_size-1)-1)/stride+1) Lout=floor((Lin+2paddingdilation(kernerl_size1)1)/stride+1)
import torch
import torch.nn as nn
m = nn.Conv1d(16, 33, 3, stride=2)
input = torch.randn(20, 16, 50)
output = m(input)
print(output.shape)
# torch.Size([20, 33, 24])
  • class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
    参数 kernel_size, stride,padding, dilation 也可以是一个 int 的数据,此时卷积 height 和 width 值相同;也可以是一个 tuple 数组, tuple 的第一维度表示 height 的数值, tuple 的第二维度表示 width 的数值。如果 bias=True,添加偏置。
    假设输入尺度: ( N , C i n , H i n , W i n ) (N, C_{in},H_{in},W_{in}) (N,Cin,Hin,Win),输出尺度 ( N , C o u t , H o u t , W o u t ) (N, C_{out},H_{out},W_{out}) (N,Cout,Hout,Wout),输入输出的计算方式:
    H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e r l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e r l _ s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) H_{out}=floor((H_{in}+2padding[0]-dilation[0](kernerl\_size[0]-1)-1)/stride[0]+1)\\W_{out}=floor((W_{in}+2padding[1]-dilation[1](kernerl\_size[1]-1)-1)/stride[1]+1) Hout=floor((Hin+2padding[0]dilation[0](kernerl_size[0]1)1)/stride[0]+1)Wout=floor((Win+2padding[1]dilation[1](kernerl_size[1]1)1)/stride[1]+1)
import torch
import torch.nn as nn
m = nn.Conv2d(16, 33, 3, stride=2)
input = torch.randn(20, 16, 50, 100)
output = m(input)
print(output.shape)
# torch.Size([20, 33, 24, 49])
  • class torch.nn.Conv3d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
    三维卷积层, 输入的尺度是 ( N , C i n , D , H , W ) (N, C_{in},D,H,W) (N,Cin,D,H,W),输出尺度 ( N , C o u t , D o u t , H o u t , W o u t ) ( N,C_{out},D_{out},H_{out},W_{out}) N,Cout,Dout,Hout,Wout
    D o u t = f l o o r ( ( D i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e r l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 2 ] ( k e r n e r l _ s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 2 ] − d i l a t i o n [ 2 ] ( k e r n e r l _ s i z e [ 2 ] − 1 ) − 1 ) / s t r i d e [ 2 ] + 1 ) D_{out}=floor((D_{in}+2padding[0]-dilation[0](kernerl\_size[0]-1)-1)/stride[0]+1) \\H_{out}=floor((H_{in}+2padding[1]-dilation[2](kernerl\_size[1]-1)-1)/stride[1]+1)\\W_{out}=floor((W_{in}+2padding[2]-dilation[2](kernerl\_size[2]-1)-1)/stride[2]+1) Dout=floor((Din+2padding[0]dilation[0](kernerl_size[0]1)1)/stride[0]+1)Hout=floor((Hin+2padding[1]dilation[2](kernerl_size[1]1)1)/stride[1]+1)Wout=floor((Win+2padding[2]dilation[2](kernerl_size[2]1)1)/stride[2]+1)
    参数 kernel_size, stride, padding, dilation 可以是一个 int 的数据 - 卷积 height 和 width 值相同,也可以是一个有三个 int 数据的 tuple 数组, tuple 的第一维度表示 depth 的数值, tuple 的第二维度表示height 的数值, tuple 的第三维度表示 width 的数值
import torch
import torch.nn as nn
m1 = nn.Conv3d(16, 33, 3, stride=2)
m2 = nn.Conv3d(16, 33, (3, 5, 2), stride=(2,1,1), padding=(4, 2, 0))
input = torch.randn(20, 16, 10, 50, 100)
output1 = m1(input)
print(output1.shape)
# torch.Size([20, 33, 4, 24, 49])
output2 = m2(input)
print(output2.shape)
# torch.Size([20, 33, 8, 50, 99])
  • torch.nn.ConvTranspose1d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True):由于内核的大小,输入的最后的一些列的数据可能会丢失。用户可以进行适当的填充(padding 操作)。
    重要参数:
    (1):padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    (2):output_padding(int or tuple, optional) - 输出的每一条边补充 0 的层数
    输入尺寸: ( N , C i n , L i n ) (N,C_{in},L_{in}) (N,Cin,Lin)
    输出尺寸: ( N , C o u t , L o u t ) (N,C_{out},L_{out}) (N,Cout,Lout)
    L o u t = ( L i n − 1 ) s t r i d e − 2 p a d d i n g + k e r n e l _ s i z e + o u t p u t _ p a d d i n g L_{out}=(L_{in}-1)stride-2padding+kernel\_size+output\_padding Lout=(Lin1)stride2padding+kernel_size+output_padding
import torch
import torch.nn as nn
m = nn.ConvTranspose1d(16, 33, 3, stride=2, padding=1, output_padding=1)
input = torch.randn(20, 16, 100)
output = m(input)
print(output.shape)
# torch.Size([20, 33, 200])
  • torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True):2 维的转置卷积操作,由于内核的大小,输入的最后的一些列的数据可能会丢失。用户可以进行适当的填充(padding 操作)。
    重要参数:
    (1):padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    (2):output_padding(int or tuple, optional) - 输出的每一条边补充 0 的层数

输入尺寸: ( N , C _ i n , H _ i n , W _ i n ) (N,C\_in,H\_in, W\_in) (N,C_in,H_inW_in)
输出尺寸: ( N , C _ o u t , H _ o u t , W _ o u t ) (N,C\_out,H\_out,W\_out) (N,C_out,H_out,W_out)
H o u t = ( H i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] + o u t p u t _ p a d d i n g [ 0 ] W o u t = ( W i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l _ s i z e [ 1 ] + o u t p u t _ p a d d i n g [ 1 ] H_{out}=(H_{in}-1)stride[0]-2padding[0]+kernel\_size[0]+output\_padding[0]\\W_{out}=(W_{in}-1)stride[1]-2padding[1]+kernel\_size[1]+output\_padding[1] Hout=(Hin1)stride[0]2padding[0]+kernel_size[0]+output_padding[0]Wout=(Win1)stride[1]2padding[1]+kernel_size[1]+output_padding[1]

import torch
import torch.nn as nn
m1 = nn.ConvTranspose2d(16, 33, 3, stride=2)
m2 = nn.ConvTranspose2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
input = torch.randn(20, 16, 50, 100)
output1 = m1(input)
output2 = m2(input)
print(output1.shape)
# torch.Size([20, 33, 101, 201])
print(output2.shape)
# torch.Size([20, 33, 93, 100])

input = 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)
down = downsample(input)
print(down.shape)
# torch.Size([1, 16, 6, 6])
up = upsample(down, output_size=input.size())
print(up.shape)
# torch.Size([1, 16, 12, 12])
  • torch.nn.ConvTranspose3d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True):3 维的转置卷积操作
    由于内核的大小,输入的最后的一些列的数据可能会丢失。用户可以进行适当的填充(padding 操作)。
    重要参数:
    (1):padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    (2):output_padding(int or tuple, optional) - 输出的每一条边补充 0 的层数
    输入: ( N , C i n , D i n , H i n , W i n ) (N,C_{in},D_{in},H_{in},W_{in}) (N,Cin,Din,Hin,Win)
    输出: ( N , C o u t , D o u t , H o u t , W o u t ) (N,C_{out},D_{out},H_{out},W_{out}) (N,Cout,Dout,Hout,Wout)
    D o u t = ( D i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] + o u t p u t _ p a d d i n g [ 0 ] H o u t = ( H i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l _ s i z e [ 1 ] + o u t p u t _ p a d d i n g [ 0 ] W o u t = ( W i n − 1 ) s t r i d e [ 2 ] − 2 p a d d i n g [ 2 ] + k e r n e l _ s i z e [ 2 ] + o u t p u t _ p a d d i n g [ 2 ] D_{out}=(D_{in}-1)stride[0]-2padding[0]+kernel\_size[0]+output\_padding[0]\\H_{out}=(H_{in}-1)stride[1]-2padding[1]+kernel\_size[1]+output\_padding[0]\\W_{out}=(W_{in}-1)stride[2]-2padding[2]+kernel\_size[2]+output\_padding[2] Dout=(Din1)stride[0]2padding[0]+kernel_size[0]+output_padding[0]Hout=(Hin1)stride[1]2padding[1]+kernel_size[1]+output_padding[0]Wout=(Win1)stride[2]2padding[2]+kernel_size[2]+output_padding[2]
import torch
import torch.nn as nn
m1 = nn.ConvTranspose3d(16, 33, 3, stride=2)
m2 = nn.ConvTranspose3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(0, 4, 2))
input = torch.randn(20, 16, 10, 50, 100)
output1 = m1(input)
output2 = m2(input)
print(output1.shape)
# torch.Size([20, 33, 21, 101, 201])
print(output2.shape)
# torch.Size([20, 33, 21, 46, 97])
  • torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False):对于输入信号的输入通道,提供 1 维最大池化(max pooling)操作。
    输入: ( N , C i n , L i n ) (N,C_{in},L_{in}) (N,Cin,Lin)
    输出: ( N , C o u t , L o u t ) (N,C_{out},L_{out}) (N,Cout,Lout)
    L o u t = f l o o r ( ( L i n + 2 p a d d i n g − d i l a t i o n ( k e r n e l _ s i z e − 1 ) − 1 ) / s t r i d e + 1 ) L_{out}=floor((L_{in} + 2padding - dilation(kernel\_size - 1) - 1)/stride + 1) Lout=floor((Lin+2paddingdilation(kernel_size1)1)/stride+1)
import torch
import torch.nn as nn
m = nn.MaxPool1d(3, stride=2)
input = torch.randn(20, 16, 50)
output1 = m(input)
print(output.shape)
# torch.Size([20, 33, 200])
  • torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False):对于输入信号的输入通道,提供 2 维最大池化(max pooling)操作
    输入: ( N , C i n , H i n , W i n ) (N,C_{in},H_{in},W_{in}) (N,Cin,Hin,Win)
    输出: ( N , C o u t , H o u t , W o u t ) (N,C_{out},H_{out},W_{out}) (N,Cout,Hout,Wout)
    H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e l _ s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) H_{out}=floor((H_{in} + 2padding[0] - dilation[0](kernel\_size[0] - 1) - 1)/stride[0] + 1)\\W_{out}=floor((W_{in} + 2padding[1] - dilation[1](kernel\_size[1] - 1) - 1)/stride[1] + 1) Hout=floor((Hin+2padding[0]dilation[0](kernel_size[0]1)1)/stride[0]+1)Wout=floor((Win+2padding[1]dilation[1](kernel_size[1]1)1)/stride[1]+1)
import torch
import torch.nn as nn
m1 = nn.MaxPool2d(3, stride=2)
m2 = nn.MaxPool2d((3,2), stride=(2,1))
input = torch.randn(20, 16, 50, 32)
output1 = m1(input)
output2 = m2(input)
print(output1.shape)
# torch.Size([20, 16, 24, 15])
print(output2.shape)
# torch.Size([20, 16, 24, 31])
  • torch.nn.MaxPool3d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False):对于输入信号的输入通道,提供 3 维最大池化(max pooling)操作
    输入: ( N , C i n , D i n , H i n , W i n ) (N,C_{in},D_{in},H_{in},W_{in}) (N,Cin,Din,Hin,Win)
    输出: ( N , C o u t , D o u t , H o u t , W o u t ) (N,C_{out},D_{out},H_{out},W_{out}) (N,Cout,Dout,Hout,Wout)
    D o u t = f l o o r ( ( D i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 2 ] − d i l a t i o n [ 2 ] ( k e r n e l _ s i z e [ 2 ] − 1 ) − 1 ) / s t r i d e [ 2 ] + 1 ) D_{out}=floor((D_{in} + 2padding[0] - dilation[0](kernel\_size[0] - 1) - 1)/stride[0] + 1)\\H_{out}=floor((H_{in} + 2padding[1] - dilation[1](kernel\_size[0] - 1) - 1)/stride[1] + 1)\\W_{out}=floor((W_{in} + 2padding[2] - dilation[2](kernel\_size[2] - 1) - 1)/stride[2] + 1) Dout=floor((Din+2padding[0]dilation[0](kernel_size[0]1)1)/stride[0]+1)Hout=floor((Hin+2padding[1]dilation[1](kernel_size[0]1)1)/stride[1]+1)Wout=floor((Win+2padding[2]dilation[2](kernel_size[2]1)1)/stride[2]+1)
import torch
import torch.nn as nn
m1 = nn.MaxPool3d(3, stride=2)
m2 = nn.MaxPool3d((3,2,2), stride=(2,1,2))
input = torch.randn(20, 16, 50, 44, 31)
output1 = m1(input)
output2 = m2(input)
print(output1.shape)
# torch.Size([20, 16, 24, 21, 15])
print(output2.shape)
# torch.Size([20, 16, 24, 43, 15])
  • torch.nn.MaxUnpool1d(kernel_size, stride=None, padding=0):MaxUnpool1d 输入 MaxPool1d 的输出,包括最大值的索引。MaxPool1d 可以将多个输入大小映射到相同的输出大小。
    重要参数:
    (1)kernel_size(int or tuple) - max pooling 的窗口大小
    (2)stride(int or tuple, optional) - max pooling 的窗口移动的步长。默认值是 kernel_size
    (3)padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    输入:
    1)input:需要转换的 tensor
    2)indices: Maxpool1d 的索引号
    3)output_size:一个指定输出大小的 torch.Size
    输入尺寸: ( N , C , H i n ) (N,C,H_{in}) (N,C,Hin)
    输出尺寸: ( N , C , H o u t ) (N,C,H_{out}) (N,C,Hout)
    H o u t = ( H i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] H_{out}=(H_{in}-1)stride[0]-2padding[0]+kernel\_size[0] Hout=(Hin1)stride[0]2padding[0]+kernel_size[0]
import torch
import torch.nn as nn
pool = nn.MaxPool1d(2, stride=2, return_indices=True)
unpool = nn.MaxUnpool1d(2, stride=2)
input = torch.Tensor([[[1, 2, 3, 4, 5, 6, 7, 8]]])
output, indices = pool(input)
print(output, indices)
# tensor([[[2., 4., 6., 8.]]]) tensor([[[1, 3, 5, 7]]])
print(unpool(output, indices))
# tensor([[[0., 2., 0., 4., 0., 6., 0., 8.]]])
  • torch.nn.MaxUnpool2d(kernel_size, stride=None, padding=0):Maxpool2d 的逆过程,不过并不是完全的逆过程,因为在 maxpool2d 的过程中,一些最大值的已经丢失。 MaxUnpool2d 的输入是 MaxPool2d 的输出,包括最大值的索引。
    重要参数:
    (1)kernel_size(int or tuple) - max pooling 的窗口大小
    (2)stride(int or tuple, optional) - max pooling 的窗口移动的步长。默认值是 kernel_size
    (3)padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    输入:
    1)input:需要转换的 tensor
    2)indices: Maxpool2d 的索引号
    3)output_size:一个指定输出大小的 torch.Size
    输入尺寸: ( N , C , H i n , W i n ) (N,C,H_{in},W_{in}) (N,C,Hin,Win)
    输出尺寸: ( N , C , H o u t , W o u t ) (N,C,H_{out},W_{out}) (N,C,Hout,Wout)
    H o u t = ( H i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] W o u t = ( W i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 1 ] + k e r n e l _ s i z e [ 1 ] H_{out}=(H_{in}-1)stride[0]-2padding[0]+kernel\_size[0]\\W_{out}=(W_{in}-1)stride[1]-2padding[1]+kernel\_size[1] Hout=(Hin1)stride[0]2padding[0]+kernel_size[0]Wout=(Win1)stride[1]2padding[1]+kernel_size[1]
import torch
import torch.nn as nn
pool = nn.MaxPool2d(2, stride=2, return_indices=True)
unpool = nn.MaxUnpool2d(2, stride=2)
input = torch.Tensor([[[[ 1, 2, 3, 4],
						[ 5, 6, 7, 8],
						[ 9, 10, 11, 12],
						[13, 14, 15, 16]]]])
output, indices = pool(input)
print(output, indices)
# tensor([[[[ 6.,  8.],[14., 16.]]]]) 
# tensor([[[[ 5,  7],[13, 15]]]])
print(unpool(output, indices))
# tensor([[[[ 0.,  0.,  0.,  0.],
#           [ 0.,  6.,  0.,  8.],
#           [ 0.,  0.,  0.,  0.],
#           [ 0., 14.,  0., 16.]]]])
  • torch.nn.MaxUnpool3d(kernel_size, stride=None, padding=0):Maxpool3d 的逆过程,不过并不是完全的逆过程,因为在 maxpool3d 的过程中,一些最大值的已经丢失。 MaxUnpool3d 的输入就是 MaxPool3d 的输出,包括最大值的索引。
    重要参数:
    (1)kernel_size(int or tuple) - max pooling 的窗口大小
    (2)stride(int or tuple, optional) - max pooling 的窗口移动的步长。默认值是 kernel_size
    (3)padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
    输入:
    1)input:需要转换的 tensor
    2)indices: Maxpool3d 的索引号
    3)output_size:一个指定输出大小的 torch.Size
    输入尺寸: ( N , C , D i n , H i n , W i n ) (N,C,D_{in},H_{in},W_{in}) (N,C,Din,Hin,Win)
    输出尺寸: ( N , C , D o u t , H o u t , W o u t ) (N,C,D_{out},H_{out},W_{out}) (N,C,Dout,Hout,Wout)
    D o u t = ( D i n − 1 ) s t r i d e [ 0 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] H o u t = ( H i n − 1 ) s t r i d e [ 1 ] − 2 p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 1 ] W o u t = ( W i n − 1 ) s t r i d e [ 2 ] − 2 p a d d i n g [ 2 ] + k e r n e l _ s i z e [ 2 ] D_{out}=(D_{in}-1)stride[0]-2padding[0]+kernel\_size[0]\\ H_{out}=(H_{in}-1)stride[1]-2padding[0]+kernel\_size[1]\\ W_{out}=(W_{in}-1)stride[2]-2padding[2]+kernel\_size[2] Dout=(Din1)stride[0]2padding[0]+kernel_size[0]Hout=(Hin1)stride[1]2padding[0]+kernel_size[1]Wout=(Win1)stride[2]2padding[2]+kernel_size[2]
import torch
import torch.nn as nn
pool = nn.MaxPool3d(3, stride=2, return_indices=True)
unpool = nn.MaxUnpool3d(3, stride=2)
input = torch.randn(20, 16, 51, 33, 15)
output, indices = pool(input)
unpooled_output = unpool(output, indices)
print(unpooled_output.shape)
# torch.Size([20, 16, 51, 33, 15])
  • torch.nn.AvgPool1d(kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True):对信号的输入通道,提供 1 维平均池化
    重要参数:
    (1)ceil_mode - 如果等于 True,计算输出信号大小的时候,会使用向上取整,代替默认
    的向下取整的操作
    (2)count_include_pad - 如果等于 True,计算平均池化时,将包括 padding 填充的 0
    输入尺寸: ( N , C , L i n ) (N,C,L_{in}) (N,C,Lin)
    输出尺寸: ( N , C , L o u t ) (N,C,L_{out}) (N,C,Lout)
    L o u t = f l o o r ( ( L i n + 2 ∗ p a d d i n g − k e r n e l _ s i z e ) / s t r i d e + 1 ) L_{out}=floor((L_{in}+2∗padding−kernel\_size)/stride+1) Lout=floor((Lin+2paddingkernel_size)/stride+1)
import torch
import torch.nn as nn
m = nn.AvgPool1d(3, stride=2)
input = torch.Tensor([[[1,2,3,4,5,6,7]]])
output = m(input)
print(output)
# tensor([[[2., 4., 6.]]])
  • torch.nn.AvgPool2d(kernel_size, stride=None, padding=0, ceil_mode=False,count_include_pad=True):对信号的输入通道,提供 2 维的平均池化
    输入尺寸: ( N , C , H i n , W i n ) (N,C,H_{in},W_{in}) (N,C,Hin,Win)
    输出尺寸: ( N , C , H o u t , W o u t ) (N,C,H_{out},W_{out}) (N,C,Hout,Wout)
    H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 0 ] − k e r n e l _ s i z e [ 0 ] ) / s t r i d e [ 0 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − k e r n e l _ s i z e [ 1 ] ) / s t r i d e [ 1 ] + 1 ) H_{out}=floor((H_{in}+2padding[0]-kernel\_size[0])/stride[0]+1)\\ W_{out}=floor((W_{in}+2padding[1]-kernel\_size[1])/stride[1]+1) Hout=floor((Hin+2padding[0]kernel_size[0])/stride[0]+1)Wout=floor((Win+2padding[1]kernel_size[1])/stride[1]+1)
import torch
import torch.nn as nn
m1 = nn.AvgPool2d(3, stride=2)
m2 = nn.AvgPool2d((3, 2), stride=(2, 1))
input = torch.randn(20, 16, 50, 32)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape,)
# torch.Size([20, 16, 24, 15]) torch.Size([20, 16, 24, 31])
  • torch.nn.AvgPool3d(kernel_size, stride=None):对信号的输入通道,提供 3 维的平均池化
    输入大小: ( N , C , D i n , H i n , W i n ) (N,C,D_{in},H_{in},W_{in}) (N,C,Din,Hin,Win)
    输出大小: ( N , C , D o u t , H o u t , W o u t ) (N,C,D_{out},H_{out},W_{out}) (N,C,Dout,Hout,Wout)
    D o u t = f l o o r ( ( D i n + 2 p a d d i n g [ 0 ] − k e r n e l _ s i z e [ 0 ] ) / s t r i d e [ 0 ] + 1 ) H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 1 ] − k e r n e l _ s i z e [ 1 ] ) / s t r i d e [ 1 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 ∗ p a d d i n g [ 2 ] − k e r n e l _ s i z e [ 2 ] ) / s t r i d e [ 2 ] + 1 ) D_{out}=floor((D_{in}+2padding[0]-kernel\_size[0])/stride[0]+1)\\ H_{out}=floor((H_{in}+2padding[1]-kernel\_size[1])/stride[1]+1)\\ W_{out}=floor((W_{in}+2*padding[2]-kernel\_size[2])/stride[2]+1) Dout=floor((Din+2padding[0]kernel_size[0])/stride[0]+1)Hout=floor((Hin+2padding[1]kernel_size[1])/stride[1]+1)Wout=floor((Win+2padding[2]kernel_size[2])/stride[2]+1)
import torch
import torch.nn as nn
m1 = nn.AvgPool3d(3, stride=2)
m2 = nn.AvgPool3d((3, 2, 2), stride=(2, 1, 2))
input = torch.randn(20, 16, 50, 44, 31)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape,)
# torch.Size([20, 16, 24, 21, 15]) torch.Size([20, 16, 24, 43, 15])
  • torch.nn.FractionalMaxPool2d(kernel_size, output_size=None, output_ratio=None, return_indices=False, _random_samples=None):对输入的信号,提供 2 维的分数最大化池化操作
    重要参数:
    (1)output_ratio – 将输入图像的大小的百分比指定为输出图片的大小,使用一个范围在(0,1)之间的数字指定
    (2)return_indices - 默认值 False,如果设置为 True,会返回输出的索引,索引对 nn.MaxUnpool2d 有用。
import torch
import torch.nn as nn
m1 = nn.FractionalMaxPool2d(3, output_size=(13, 12))
m2 = nn.FractionalMaxPool2d(3, output_ratio=(0.5, 0.5))
input = torch.randn(20, 16, 50, 32)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape,)
# torch.Size([20, 16, 13, 12]) torch.Size([20, 16, 25, 16])
  • torch.nn.LPPool2d(norm_type, kernel_size, stride=None, ceil_mode=False):对输入信号提供 2 维的幂平均池化操作
    f ( X ) = ∑ x ∈ X x p p f(X)=\sqrt[p]{\sum_{x\in X}x^p} f(X)=pxXxp
    (1)当 p 为无穷大的时候时,等价于最大池化操作
    (2)当 p=1 时,等价于平均池化操作
    输入尺寸: ( N , C , H i n , W i n ) (N,C,H_{in},W_{in}) (N,C,Hin,Win)
    输出尺寸: ( N , C , H o u t , W o u t ) (N,C,H_{out},W_{out}) (N,C,Hout,Wout)
    H o u t = f l o o r ( ( H i n + 2 p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 ) / s t r i d e [ 0 ] + 1 ) W o u t = f l o o r ( ( W i n + 2 p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] ( k e r n e l _ s i z e [ 1 ] − 1 ) − 1 ) / s t r i d e [ 1 ] + 1 ) H_{out} = floor((H_{in}+2padding[0]-dilation[0](kernel\_size[0]-1)-1)/stride[0]+1)\\ W_{out} = floor((W_{in}+2padding[1]-dilation[1](kernel\_size[1]-1)-1)/stride[1]+1) Hout=floor((Hin+2padding[0]dilation[0](kernel_size[0]1)1)/stride[0]+1)Wout=floor((Win+2padding[1]dilation[1](kernel_size[1]1)1)/stride[1]+1)
import torch
import torch.nn as nn
m1 = nn.LPPool2d(2, 3, stride=2)
m2 = nn.LPPool2d(1.2, (3, 2), stride=(2, 1))
input = torch.randn(20, 16, 50, 32)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape,)
# torch.Size([20, 16, 24, 15]) torch.Size([20, 16, 24, 31])
  • torch.nn.AdaptiveMaxPool1d(output_size, return_indices=False):对输入信号,提供 1 维的自适应最大池化操作 对于任何输入大小的输入,可以将输出尺寸指定为 output_size,但是输入和输出特征的数目(通道数)不会变化。
    重要参数:
    (1)output_size: 输出信号的尺寸
    (2)return_indices - 默认值 False,如果设置为 True,会返回输出的索引,索引对 nn.MaxUnpool2d 有用。
import torch
import torch.nn as nn
m = nn.AdaptiveMaxPool1d(5)
input = torch.randn(1, 64, 8)
output = m(input)
print(output.shape)
# torch.Size([1, 64, 5])
  • torch.nn.AdaptiveMaxPool2d(output_size, return_indices=False):对输入信号,提供 2 维的自适应最大池化操作 对于任何输入大小的输入,可以将输出尺寸指定为output_size,但是输入和输出特征的数目(通道数)不会变化
    重要参数:
    (1)output_size: 输出信号的尺寸
    (2)return_indices - 默认值 False,如果设置为 True,会返回输出的索引,索引对 nn.MaxUnpool2d 有用。
import torch
import torch.nn as nn
m1 = nn.AdaptiveMaxPool2d((5,7))
m2 = nn.AdaptiveMaxPool2d(7)
input = torch.randn(1, 64, 8, 9)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape)
# torch.Size([1, 64, 5, 7]) torch.Size([1, 64, 7, 7])
  • torch.nn.AdaptiveAvgPool1d(output_size):对输入信号,提供 1 维的自适应平均池化操作 对于任何输入大小的输入,可以将输出尺寸指定为output_size,但是输入和输出特征的数目(通道数)不会变化。
import torch
import torch.nn as nn
m = nn.AdaptiveMaxPool1d(5)
input = torch.randn(1, 64, 8)
output = m(input)
print(output.shape)
# torch.Size([1, 64, 5])
  • torch.nn.AdaptiveAvgPool2d(output_size):对输入信号,提供 2 维的自适应平均池化操作 对于任何输入大小的输入,可以将输出尺寸指定为output_size,但是输入和输出特征的数目(通道数)不会变化。
import torch
import torch.nn as nn
m1 = nn.AdaptiveAvgPool2d((5,7))
m2 = nn.AdaptiveAvgPool2d(7)
input = torch.randn(1, 64, 8, 9)
output1 = m1(input)
output2 = m2(input)
print(output1.shape, output2.shape)
# torch.Size([1, 64, 5, 7]) torch.Size([1, 64, 7, 7])

参考目录

https://blog.csdn.net/weixin_40920183/article/details/119814472


点击全文阅读


本文链接:http://zhangshiyu.com/post/31439.html

输入  输出  参数  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1