torch.nn.ReflectionPad2d(size)
size:可以为整数或者元组
解析:该函数对输入的图像以其边界像素为对称轴做四周的轴对称镜像填充,填充的顺序是左→右→上→下。
这么说,可能听着有点迷糊,那下面就以实例来进行讲解。
import torch
from torch import nn
# 生成一个(1,1,5,5)四维的浮点型张量,ReflectionPad2d()仅针对浮点型张量实现。
tensor = torch.randint(1,3,(1,1,5,5)).float()
print(tensor)
----------------------------------------
tensor([[[[1., 1., 2., 2., 1.],
[2., 2., 1., 1., 2.],
[2., 1., 2., 1., 1.],
[2., 1., 2., 2., 2.],
[1., 2., 2., 2., 1.]]]])
-----------------------------------------
# 对于一个4维的Tensor,当只指定一个padding参数时,则表示对四周填充相同的行数,这里对左、右、上、下都填充3行
ref = nn.ReflectionPad2d(3)
print(ref(tensor))
-----------------------------------------
tensor([[[[2., 2., 1., 2., 1., 2., 2., 2., 2., 2., 1.],
[1., 2., 1., 2., 1., 2., 1., 1., 1., 2., 1.],
[1., 1., 2., 2., 2., 1., 1., 2., 1., 1., 2.],
[2., 2., 1., 1., 1., 2., 2., 1., 2., 2., 1.],
[1., 1., 2., 2., 2., 1., 1., 2., 1., 1., 2.],
[1., 2., 1., 2., 1., 2., 1., 1., 1., 2., 1.],
[2., 2., 1., 2., 1., 2., 2., 2., 2., 2., 1.],
[2., 2., 2., 1., 2., 2., 2., 1., 2., 2., 2.],
[2., 2., 1., 2., 1., 2., 2., 2., 2., 2., 1.],
[1., 2., 1., 2., 1., 2., 1., 1., 1., 2., 1.],
[1., 1., 2., 2., 2., 1., 1., 2., 1., 1., 2.]]]])
将上述的运算过程,以图解的方式来进行讲解,以左侧填充3列为例,黄色虚线表示原来的tensor。
接着进行右侧填充3列:
再接着进行上侧填充3列:
最后进行下侧填充3列:
如果分别对4个维度进行不同行数的填充,则需分别指定填充行数,用一个元组来表示。
# 左侧填充1行,右侧填充2行,上方填充3行,下方填充4行
nn.ReflectionPad2d((1, 2, 3, 4))
nn.ReflectionPad2d()意义:因为卷积核是围绕中心像素进行卷积操作,而卷积核中心到不了最边缘的像素,所以最边缘的像素一般无法处理,图像就会缩小;为了使最边缘的像素也能发挥作用和维持图像的尺寸,因此需要在最边缘的像素进行填充,使得卷积核也能处理到最边缘的像素。例如,使用3*3的卷积核从图像左上角(即坐标为(0,0)像素)开始进行卷积,如果把最左上角坐标(0, 0)的像素作为中心像素,由于(0,0)左侧、上方和左上方没有像素了,此时就无法运算,图像就会缩小。ReflectionPad2d()镜像填充的方式相比于使用固定数值进行填充,有可能获得更好的卷积结果。