参考:
公式ドキュメントTORCH.NN.FUNCTIONAL.GRID_SAMPLEを確認してください。
grid_sample の関数シグネチャは次のとおりですtorch.nn.functional.grid_sample(input, grid, mode='bilinear', padding_mode='zeros', align_corners=None)
。
4Dの場合、
- input (Tensor) – 形状の入力( N , C , H in , W in ) (N, C, H_{in}, W_{in})( N 、C 、Hで、Wで)、これは入力イメージに相当し、N は batch_size、C はチャネルです。
- grid (Tensor) – 形状の流れ場( N , H out , W out , 2 ) (N, H_{out}, W_{out}, 2)( N 、Hあなたの_、Wあなたの_、2 )の場合、最後の次元は、2 次元平面上の座標点 (x, y) を表す長さ 2 の配列でなければなりません。W out W_{out}Wあなたの_和H out H_{out}Hあなたの_クエリ マトリックスの幅と高さに相当するこの関数は、クエリ マトリックスの各座標のサンプリング値を返します。サンプリング結果は補間戦略に依存します
mode
align_corners=True と False の場合、関数は異なる動作をし、異なる結果を返します。
基本的な例の説明
まず例を見てみましょう。まず、入力行列は inp で、次に 2 つの行列 new_h、new_w を作成し、それらを「クエリ座標行列」グリッドに合成します。出力行列の次元は、クエリ行列の次元と同じです。
この例は一般的な印象を与えるだけであり、特定の点数の計算は含まれていません。
# This is a sample Python script.
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import torch
import torch.nn.functional as F
inp = torch.arange(0, 16)
inp = inp.reshape((1, 1, 4, 4)).float()
print("inp", inp)
# inp tensor([[[[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.],
# [12., 13., 14., 15.]]]])
out_h = 3
out_w = 3
new_h = torch.linspace(-1, 1, out_h).view(-1, 1).repeat(1, out_w)
new_w = torch.linspace(-1, 1, out_w).repeat(out_h, 1)
print("new_h", new_h)
print("new_w", new_w)
# new_h tensor([[-1., -1., -1.],
# [ 0., 0., 0.],
# [ 1., 1., 1.]])
#new_w tensor([[-1., 0., 1.],
# [-1., 0., 1.],
# [-1., 0., 1.]])
grid = torch.cat((new_w.unsqueeze(2), new_h.unsqueeze(2)), dim=2)
print("grid", grid)
#grid tensor([[[-1., -1.],
# [ 0., -1.],
# [ 1., -1.]],
#
# [[-1., 0.],
# [ 0., 0.],
# [ 1., 0.]],
#
# [[-1., 1.],
# [ 0., 1.],
# [ 1., 1.]]])
grid = grid.unsqueeze(0)
outp = F.grid_sample(inp, grid=torch.Tensor(grid), mode='bilinear', align_corners=False)
# outp = F.grid_sample(inp, grid=grid, mode='bilinear', align_corners=False)
print("outp", outp)
# outp tensor([[[[0.0000, 0.7500, 0.7500],
# [3.0000, 7.5000, 4.5000],
# [3.0000, 6.7500, 3.7500]]]])
2 つの align_corners 設定での関数の動作
入力パラメータを受け取った後、関数はそれをx ∈ [ − 1 , 1 ] , y ∈ [ − 1 , 1 ] x \in [-1, 1], y \in [-1, 1] にマッピングします。バツε[ − 1 ,1 ] 、yε[ − 1 ,1 ]行列の範囲内。align_corners は、関数がコーナー座標の要素をマトリックスのコーナー位置にマップするかどうかを制御します。
詳細については、Pytorch grid_sample 分析を参照してください。
入力行列のサイズが 4x4 で、要素の値が 0 から 15 に増加するとします。
align_corners=True の場合、入力の四隅の座標値が座標系範囲の四隅にマッピングされます。したがって、座標 (-1, -1) の値は 0 で、(1, 1) の値は 15 です。
align_corners=False の場合、入力の各値は 4x4 ピクセル マトリックスのピクセル中心になります。ピクセル マトリックスの 4 つの角は、座標系の範囲の 4 つの角にマッピングされます。
したがって、(0.7143, -0.7143) の値 (図の赤い線の交差位置) を計算する場合は、2、3、6、および 7 (茶色のボックス) の 4 つの値を見つける必要があります。 )、双一次補間を行います。
クエリ マトリックスに重複した要素があります
クエリ座標マトリックス グリッドに重複する要素がある場合、grid_sample の動作はどのように変化しますか? たとえば、次のコードの実行:
outp = F.grid_sample(inp, grid=torch.Tensor(
[[[[0, 0],
[0, 1],
[1, 0],
[1, 1],
[1, 1],
[1, 1]]]]
), mode='bilinear', align_corners=True)
次の結果が得られます.最後の 3 つのクエリ座標はすべて [1,1] であるため、クエリ結果はすべて 15 に等しいことが観察からわかります.
outp tensor([[[[ 7.5000, 13.5000, 9.0000, 15.0000, 15.0000, 15.0000]]]])