1. pytorch nn.Con2d のフィルモード
torch.nn.Conv2d(in_channels、out_channels、kernel_size、stride=1、padding=0、dilation=1、groups=1、bias=True、padding_mode=‘zeros’、device=None、dtype=None)
1.1 パディングパラメータの意味
まず、pad = N です。これは、N 個の値が上下左右の 4 方向にそれぞれ埋められることを意味します。
たとえば、pad = N = 1 の場合、上下左右に 1 つの値が埋められることを意味します。すると、元の入力行列は 2* N 行と 2* N 列を追加します。ここでは、2 行と 2列が追加されます。
このようにして、2 次元畳み込みの出力を計算するときに、なぜ
はい
[ i + 2 ∗ pad d i n g − k e r n e l s i z e ] 下取整 / s t r i d e + 1 ; [ i + 2*padding -kernel_{size} ]下取整 / stride + 1;[i+2∗padding−kernelとiから]下取整/stedir+1;
1.2padding_modeパラメータ
このパラメータは、パディング中にこれらのパディングの特定の値を生成する方法を指定します。
つまり、パディング値の生成に使用される方法です。
PyTorch の 2 次元畳み込み関数 torch.nn.Conv2d() には「padding_mode」パラメータがあり、「zeros」、「reflect」、
の 4 つのオプションがあります。 ' または 'circular' の場合、デフォルトのオプションは 'zeros' (ゼロ埋め込み) です。この4つの充填方法とは一体何なのでしょうか?
padding_mode (string, optional): `'zeros'`, `'reflect'`,
`'replicate'` or `'circular'`. Default: `'zeros'`
これら 4 つの充填方法を直感的に観察するために、1*1 畳み込みを定義し、畳み込みカーネルの重みを 1 に設定します。これにより、さまざまな充填方法で畳み込み計算を実行した後、充填行列を取得できます。この例では、1 ~ 16 で構成される 4*4 行列を生成し、それに対してさまざまな充填方法で畳み込み計算を実行します。
In [51]: x = torch.nn.Parameter(torch.reshape(torch.range(1,16),(1,1,4,4)))
In [52]: x
Out[52]:
Parameter containing:
tensor([[[[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.],
[13., 14., 15., 16.]]]], requires_grad=True)
1.「ゼロ」
'zeros' は最も一般的なゼロ パディングです。つまり、行列の高さと幅 パディング、パディングは寸法の両側で行われます。
In [53]: conv_zeros = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)
In [54]: conv_zeros
Out[54]: Conv2d(1, 1, kernel_size=(1, 1), stride=(1, 1), padding=(1, 1), bias=False)
In [55]: conv_zeros.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
In [56]: conv_zeros.weight
Out[56]:
Parameter containing:
tensor([[[[1.]]]], requires_grad=True)
In [57]: conv_zeros(x)
Out[57]:
tensor([[[[ 0., 0., 0., 0., 0., 0.],
[ 0., 1., 2., 3., 4., 0.],
[ 0., 5., 6., 7., 8., 0.],
[ 0., 9., 10., 11., 12., 0.],
[ 0., 13., 14., 15., 16., 0.],
[ 0., 0., 0., 0., 0., 0.]]]], grad_fn=<ThnnConv2DBackward>)
如果 将其中的 bias 参数设置 为 True
:
x = torch.nn.Parameter(torch.reshape(torch.range(1,16),(1,1,4,4)))
conv_zeros = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)
conv_zeros_bias = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=True)
conv_zeros.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
conv_zeros(x)
tensor([[[[ 0., 0., 0., 0., 0., 0.],
[ 0., 1., 2., 3., 4., 0.],
[ 0., 5., 6., 7., 8., 0.],
[ 0., 9., 10., 11., 12., 0.],
[ 0., 13., 14., 15., 16., 0.],
[ 0., 0., 0., 0., 0., 0.]]]],
grad_fn=<MkldnnConvolutionBackward>)
conv_zeros_bias(x)
tensor([[[[ 0.5259, 0.5259, 0.5259, 0.5259, 0.5259, 0.5259],
[ 0.5259, 0.4084, 0.2909, 0.1734, 0.0559, 0.5259],
[ 0.5259, -0.0616, -0.1791, -0.2966, -0.4141, 0.5259],
[ 0.5259, -0.5316, -0.6492, -0.7667, -0.8842, 0.5259],
[ 0.5259, -1.0017, -1.1192, -1.2367, -1.3542, 0.5259],
[ 0.5259, 0.5259, 0.5259, 0.5259, 0.5259, 0.5259]]]],
grad_fn=<MkldnnConvolutionBackward>)
問題は、バイアスを True
、
同じ入力、同じ学習可能なパラメータの重みに設定するかどうかです。< a i =3> バイアスが設定されていれば、異なる結果が得られますか?
那么 bias 到底 起到什么作用呢?
2.「反省する」
「Reflect」は行列の端を対称軸として、行列の要素を最外周まで対称に埋めていきます。
In [58]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='reflect',bias=False)
In [59]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
In [60]: conv_reflect(x)
Out[60]:
tensor([[[[ 6., 5., 6., 7., 8., 7.],
[ 2., 1., 2., 3., 4., 3.],
[ 6., 5., 6., 7., 8., 7.],
[10., 9., 10., 11., 12., 11.],
[14., 13., 14., 15., 16., 15.],
[10., 9., 10., 11., 12., 11.]]]], grad_fn=<ThnnConv2DBackward>)
3.「複製」
「replicate」は行列のエッジをコピーし、行列の外側に塗りつぶします。
In [61]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='replicate',bias=False)
In [62]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
In [63]: conv_replicate(x)
Out[63]:
tensor([[[[ 1., 1., 2., 3., 4., 4.],
[ 1., 1., 2., 3., 4., 4.],
[ 5., 5., 6., 7., 8., 8.],
[ 9., 9., 10., 11., 12., 12.],
[13., 13., 14., 15., 16., 16.],
[13., 13., 14., 15., 16., 16.]]]], grad_fn=<ThnnConv2DBackward>)
4.「円形」
名前が示すように、「円形」はループを埋めることを意味しますが、どのようにループするのでしょうか?まず例を見てみましょう。
In [64]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='circular',bias=False)
In [65]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
In [66]: conv_circular(x)
Out[66]:
tensor([[[[16., 13., 14., 15., 16., 13.],
[ 4., 1., 2., 3., 4., 1.],
[ 8., 5., 6., 7., 8., 5.],
[12., 9., 10., 11., 12., 9.],
[16., 13., 14., 15., 16., 13.],
[ 4., 1., 2., 3., 4., 1.]]]], grad_fn=<ThnnConv2DBackward>)
入力行列を左から右、上から下に無限に拡張すると、次の形式になります。
tensor([[[[ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 5., 6., 7., 8., 5., 6., 7., 8.],
[ 9., 10., 11., 12., 9., 10., 11., 12., 9., 10., 11., 12.],
[13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.],
[ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 5., 6., 7., 8., 5., 6., 7., 8.],
[ 9., 10., 11., 12., 9., 10., 11., 12., 9., 10., 11., 12.],
[13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.],
[ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 5., 6., 7., 8., 5., 6., 7., 8.],
[ 9., 10., 11., 12., 9., 10., 11., 12., 9., 10., 11., 12.],
[13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.]]]])
画像.png
あなたはそれを見ましたか?無限に拡張した場合、これは元の 4*4 行列のループです。上記の行列は、高さ、幅の寸法の両方で 4 つのユニットを埋めた結果です。1 つのユニットのみを埋めた場合は、1 つのユニットを埋めた後の結果のみですユニットがインターセプトされます。行列:
画像.png
この例では 1 ユニットのみを埋めた結果です。
参照する
https://www.jianshu.com/p/a6da4ad8e8e7
推荐阅读: https://blog.csdn.net/g11d111/article/details/82665265