F.pad的使用与报错记录

原始文档:https://www.yuque.com/lart/ugkv9f/iftd9v

函数原型

函数文档:https://pytorch.org/docs/1.12/generated/torch.nn.functional.pad.html#torch-nn-functional-pad

torch.nn.functional.pad(input, pad, mode='constant', value=None) → Tensor

Padding格式

  • 1D-tensor:(p_left, p_right)
  • 2D-tensor:(p_left, p_right, p_top, p_bottom)
  • 3D-tensor:(p_left, p_right, p_top, p_bottom, p_front, p_back)

四种模式

这一函数用于实现对高维tensor的形状补齐操作。PyTorch本身提供了四种padding模式:

  • constant:使用指定的常数value补齐指定的维度。对于数据012,使用0补齐,结果可以为0001200
  • reflect:使用tensor自身的值按照“反射”的方式补齐指定的维度。对于数据012,结果可以为2101210
  • replicate:使用tensor自身边界值补齐指定的维度。对于数据012,结果可以为0001222
  • circular:使用tensor自身的值按照“循环”的方式补齐指定的维度。对于数据012,结果可以为1201201

需要注意的是,文档强调了这一点:

Constant padding is implemented for arbitrary dimensions.
Replicate and reflection padding are implemented for padding the last 3 dimensions of a 4D or 5D input tensor, the last 2 dimensions of a 3D or 4D input tensor, or the last dimension of a 2D or 3D input tensor.

这四种模式使用输出展示会更便于理解一些,下面是一个例子:

import torch
import torch.nn.functional as F
pad = [2, 2, 2, 2]
x = torch.arange(9, dtype=torch.float32).reshape(1, 1, 3, 3)
print("x")
print(x)
print("F.pad(x, pad=pad, mode='constant', value=0)")
print(F.pad(x, pad=pad, mode='constant', value=0))
print("F.pad(x, pad=pad, mode='replicate')")
print(F.pad(x, pad=pad, mode='replicate'))
print("F.pad(x, pad=pad, mode='reflect')")
print(F.pad(x, pad=pad, mode='reflect'))
print("F.pad(x, pad=pad, mode='circular')")
print(F.pad(x, pad=pad, mode='circular'))

对应的输出为:

x
tensor([[[[0., 1., 2.],
          [3., 4., 5.],
          [6., 7., 8.]]]])
F.pad(x, pad=pad, mode='constant', value=0)
tensor([[[[0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 1., 2., 0., 0.],
          [0., 0., 3., 4., 5., 0., 0.],
          [0., 0., 6., 7., 8., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0.]]]])
F.pad(x, pad=pad, mode='replicate')
tensor([[[[0., 0., 0., 1., 2., 2., 2.],
          [0., 0., 0., 1., 2., 2., 2.],
          [0., 0., 0., 1., 2., 2., 2.],
          [3., 3., 3., 4., 5., 5., 5.],
          [6., 6., 6., 7., 8., 8., 8.],
          [6., 6., 6., 7., 8., 8., 8.],
          [6., 6., 6., 7., 8., 8., 8.]]]])
F.pad(x, pad=pad, mode='reflect')
tensor([[[[8., 7., 6., 7., 8., 7., 6.],
          [5., 4., 3., 4., 5., 4., 3.],
          [2., 1., 0., 1., 2., 1., 0.],
          [5., 4., 3., 4., 5., 4., 3.],
          [8., 7., 6., 7., 8., 7., 6.],
          [5., 4., 3., 4., 5., 4., 3.],
          [2., 1., 0., 1., 2., 1., 0.]]]])
F.pad(x, pad=pad, mode='circular')
tensor([[[[4., 5., 3., 4., 5., 3., 4.],
          [7., 8., 6., 7., 8., 6., 7.],
          [1., 2., 0., 1., 2., 0., 1.],
          [4., 5., 3., 4., 5., 3., 4.],
          [7., 8., 6., 7., 8., 6., 7.],
          [1., 2., 0., 1., 2., 0., 1.],
          [4., 5., 3., 4., 5., 3., 4.]]]])

可能会遇到的报错

常见的错误主要是因为padding的数量超过了对应模式的要求。

对于constantreplicate对于padding并没有限制。

但是另外两种模式replicatecircular就有要求了。

RuntimeError: Argument #4: Padding size should be less than the corresponding input dimension, but got: padding (3, 3) at dimension 3 of input 4

这发生在reflect模式中,padding的数量必须小于对应维度的大小。

import torch
import torch.nn.functional as F
pad = [3, 3, 3, 3]
x = torch.arange(9, dtype=torch.float32).reshape(1, 1, 3, 3)
print("F.pad(x, pad=pad, mode='reflect')")
print(F.pad(x, pad=pad, mode='reflect'))
"""
F.pad(x, pad=pad, mode='reflect')
Traceback (most recent call last):
  File "e:/Coding/PythonTools/TorchPadding/main.py", line 20, in <module>
    print(F.pad(x, pad=pad, mode='reflect'))
  File "D:\Programming\Python\envs\pt1102\lib\site-packages\torch\nn\functional.py", line 4189, in _pad
    return torch._C._nn.reflection_pad2d(input, pad)
RuntimeError: Argument #4: Padding size should be less than the corresponding input dimension, but got: padding (3, 3) at 
dimension 3 of input 4
"""

AssertionError: Padding value causes wrapping around more than once.

这发生在circular模式中,padding的数量不得超出原始tensor对应维度的大小。

import torch
import torch.nn.functional as F
pad = [4, 4, 4, 4]
x = torch.arange(9, dtype=torch.float32).reshape(1, 1, 3, 3)
print("F.pad(x, pad=pad, mode='circular')")
print(F.pad(x, pad=pad, mode='circular'))
"""
F.pad(x, pad=pad, mode='circular')
Traceback (most recent call last):
  File "e:/Coding/PythonTools/TorchPadding/main.py", line 17, in <module>
    print(F.pad(x, pad=pad, mode='circular'))
  File "D:\Programming\Python\envs\pt1102\lib\site-packages\torch\nn\functional.py", line 4193, in _pad
    return _pad_circular(input, pad)
  File "D:\Programming\Python\envs\pt1102\lib\site-packages\torch\nn\functional.py", line 4585, in _pad_circular
    assert padding[-(idx * 2 + 1)] <= size, "Padding value causes wrapping around more than once."
AssertionError: Padding value causes wrapping around more than once.
"""
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。