DML_ROI_ALIGN_GRAD_OPERATOR_DESC
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 |
|---|---|---|---|---|---|
| InputTensor | DML_TENSOR_DESC* | 8/4 | +0 | +0 | 順伝播パスの入力データを含むテンソルで、次元は { BatchCount, ChannelCount, InputHeight, InputWidth } です。このテンソルは、OutputROIGradientTensor を指定する場合、または ReductionFunction == DML_REDUCE_FUNCTION_MAX の場合には 必ず 指定しなければなりません。これは、DML_OPERATOR_ROI_ALIGN または DML_OPERATOR_ROI_ALIGN1 の InputTensor に指定するものと同じテンソルです。 |
| InputGradientTensor | DML_TENSOR_DESC* | 8/4 | +8 | +4 | |
| ROITensor | DML_TENSOR_DESC* | 8/4 | +16 | +8 | 関心領域 (ROI) のデータを含むテンソルです—これは、入力テンソルの X 次元および Y 次元を指す浮動小数点座標で表された一連の境界ボックスです。ROITensor に許可される次元は { NumROIs, 4 }、{ 1, NumROIs, 4 }、または { 1, 1, NumROIs, 4 } です。各 ROI について、値はその左上隅と右下隅の座標を [x1, y1, x2, y2] の順で表します。領域は空でもかまいません。その場合、すべての出力ピクセルは単一の入力座標から得られます。また領域は反転していてもかまいません (たとえば x2 が x1 より小さい場合)。その場合、出力には入力を鏡像化/反転したものが得られます。これらの座標はまず SpatialScaleX と SpatialScaleY によってスケーリングされますが、両方が 1.0 であれば、領域の矩形は入力テンソルの座標に直接対応します。これは、DML_OPERATOR_ROI_ALIGN または DML_OPERATOR_ROI_ALIGN1 の ROITensor に指定するものと同じテンソルです。 |
| BatchIndicesTensor | DML_TENSOR_DESC* | 8/4 | +24 | +12 | ROI の抽出元となるバッチインデックスを含むテンソルです。BatchIndicesTensor に許可される次元は { NumROIs }、{ 1, NumROIs }、{ 1, 1, NumROIs }、または { 1, 1, 1, NumROIs } です。各値は InputTensor 内のバッチのインデックスです。値が [0, BatchCount) の範囲にない場合、動作は未定義です。これは、DML_OPERATOR_ROI_ALIGN または DML_OPERATOR_ROI_ALIGN1 の BatchIndicesTensor に指定するものと同じテンソルです。 |
| OutputGradientTensor | DML_TENSOR_DESC* | 8/4 | +32 | +16 | InputTensor に関する逆伝播された勾配を格納する出力テンソルです。通常、このテンソルは順伝播パスにおける対応する DML_OPERATOR_ROI_ALIGN1 の 入力 と同じサイズになります。OutputROIGradientTensor を指定しない場合は、OutputGradientTensor を 必ず 指定しなければなりません。 |
| OutputROIGradientTensor | DML_TENSOR_DESC* | 8/4 | +40 | +20 | ROITensor に関する逆伝播された勾配を格納する出力テンソルです。このテンソルは ROITensor と同じサイズである必要があります。OutputGradientTensor を指定しない場合は、OutputROIGradientTensor を 必ず 指定しなければなりません。 |
| ReductionFunction | DML_REDUCE_FUNCTION | 4 | +48 | +24 | DML_ROI_ALIGN1_OPERATOR_DESC::ReductionFunction を参照してください。 |
| InterpolationMode | DML_INTERPOLATION_MODE | 4 | +52 | +28 | DML_ROI_ALIGN1_OPERATOR_DESC::InterpolationMode を参照してください。 |
| SpatialScaleX | FLOAT | 4 | +56 | +32 | DML_ROI_ALIGN1_OPERATOR_DESC::SpatialScaleX を参照してください。 |
| SpatialScaleY | FLOAT | 4 | +60 | +36 | DML_ROI_ALIGN1_OPERATOR_DESC::SpatialScaleY を参照してください。 |
| InputPixelOffset | FLOAT | 4 | +64 | +40 | DML_ROI_ALIGN1_OPERATOR_DESC::InputPixelOffset を参照してください。 |
| OutputPixelOffset | FLOAT | 4 | +68 | +44 | DML_ROI_ALIGN1_OPERATOR_DESC::OutputPixelOffset を参照してください。 |
| MinimumSamplesPerOutput | DWORD | 4 | +72 | +48 | DML_ROI_ALIGN1_OPERATOR_DESC::MinimumSamplesPerOutput を参照してください。 |
| MaximumSamplesPerOutput | DWORD | 4 | +76 | +52 | DML_ROI_ALIGN1_OPERATOR_DESC::MaximumSamplesPerOutput を参照してください。 |
| AlignRegionsToCorners | BOOL | 4 | +80 | +56 | DML_ROI_ALIGN1_OPERATOR_DESC::AlignRegionsToCorners を参照してください。 |
公式ドキュメント
ROI_ALIGN および ROI_ALIGN1 の逆伝播勾配を計算します。
DML_ROI_ALIGN1_OPERATOR_DESC は、最近傍サンプリングまたはバイリニア補間のいずれかを使用して、入力テンソルの部分領域を切り出してスケール変更することを思い出してください。同等の DML_OPERATOR_ROI_ALIGN1 の 出力 と同じサイズを持つ InputGradientTensor が与えられると、この演算子は DML_OPERATOR_ROI_ALIGN1 の 入力 と同じサイズを持つ OutputGradientTensor を生成します。
例として、次元 [1, 1, 4, 4] を持つ入力の重複しない 4 つの切り出しに対して、幅方向に 1.5 倍、高さ方向に 0.5 倍の 最近傍 スケーリングを行う DML_OPERATOR_ROI_ALIGN1 を考えます。
ROITensor
[[0, 0, 2, 2],
[2, 0, 4, 2],
[0, 2, 2, 4],
[2, 2, 4, 4]]
BatchIndicesTensor
[0, 0, 0, 0]
InputTensor
[[[[1, 2, | 3, 4], RoiAlign1 [[[[ 1, 1, 2]]],
[5, 6, | 7, 8], --> [[[ 3, 3, 4]]],
------------------ [[[ 9, 9, 10]]],
[9, 10, | 11, 12], [[[11, 11, 12]]]]
[13, 14, | 15, 16]]]]
各領域の 0 番目の要素が出力の 2 つの要素に寄与していることに注目してください—1 番目の要素は出力の 1 つの要素に寄与し、2 番目と 3 番目の要素は出力のどの要素にも寄与しません。
対応する DML_OPERATOR_ROI_ALIGN_GRAD は次の処理を行います。
InputGradientTensor OutputGradientTensor
[[[[ 1, 2, 3]]], ROIAlignGrad [[[[ 3, 3, | 9, 6],
[[[ 4, 5, 6]]], --> [ 0, 0, | 0, 0],
[[[ 7, 8, 9]]], ------------------
[[[10, 11, 12]]]] [15, 9, | 21, 12],
[ 0, 0, | 0, 0]]]]
まとめると、領域が重複しない場合、DML_OPERATOR_ROI_ALIGN_GRAD は InputGradientTensor の各バッチに対して実行される DML_OPERATOR_RESAMPLE_GRAD と同様に動作します。
OutputROIGradientTensor については計算が少し異なり、次の擬似コードで要約できます (MinimumSamplesPerOutput == 1 かつ MaximumSamplesPerOutput == 1 と仮定します)。
for each region of interest (ROI):
for each inputGradientCoordinate:
for each inputCoordinate that contributed to this inputGradient element:
topYIndex = floor(inputCoordinate.y)
bottomYIndex = ceil(inputCoordinate.y)
leftXIndex = floor(inputCoordinate.x)
rightXIndex = ceil(inputCoordinate.x)
yLerp = inputCoordinate.y - topYIndex
xLerp = inputCoordinate.x - leftXIndex
topLeft = InputTensor[topYIndex][leftXIndex]
topRight = InputTensor[topYIndex][rightXIndex]
bottomLeft = InputTensor[bottomYIndex][leftXIndex]
bottomRight = InputTensor[bottomYIndex][rightXIndex]
inputGradientWeight = InputGradientTensor[inputGradientCoordinate.y][inputGradientCoordinate.x]
imageGradY = (1 - xLerp) * (bottomLeft - topLeft) + xLerp * (bottomRight - topRight)
imageGradX = (1 - yLerp) * (topRight - topLeft) + yLerp * (bottomRight - bottomLeft)
imageGradY *= inputGradientWeight
imageGradX *= inputGradientWeight
OutputROIGradientTensor[roiIndex][0] += imageGradX * (inputWidth - inputGradientCoordinate.x)
OutputROIGradientTensor[roiIndex][1] += imageGradY * (inputHeight - inputGradientCoordinate.y)
OutputROIGradientTensor[roiIndex][2] += imageGradX * inputGradientCoordinate.x
OutputROIGradientTensor[roiIndex][3] += imageGradY * inputGradientCoordinate.y
一方のみが必要な場合は OutputGradientTensor または OutputROIGradientTensor を省略できますが、少なくとも一方は指定しなければなりません。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// DML_ROI_ALIGN_GRAD_OPERATOR_DESC (x64 88 / x86 60 バイト)
typedef struct DML_ROI_ALIGN_GRAD_OPERATOR_DESC {
DML_TENSOR_DESC* InputTensor;
DML_TENSOR_DESC* InputGradientTensor;
DML_TENSOR_DESC* ROITensor;
DML_TENSOR_DESC* BatchIndicesTensor;
DML_TENSOR_DESC* OutputGradientTensor;
DML_TENSOR_DESC* OutputROIGradientTensor;
DML_REDUCE_FUNCTION ReductionFunction;
DML_INTERPOLATION_MODE InterpolationMode;
FLOAT SpatialScaleX;
FLOAT SpatialScaleY;
FLOAT InputPixelOffset;
FLOAT OutputPixelOffset;
DWORD MinimumSamplesPerOutput;
DWORD MaximumSamplesPerOutput;
BOOL AlignRegionsToCorners;
} DML_ROI_ALIGN_GRAD_OPERATOR_DESC;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DML_ROI_ALIGN_GRAD_OPERATOR_DESC
{
public IntPtr InputTensor;
public IntPtr InputGradientTensor;
public IntPtr ROITensor;
public IntPtr BatchIndicesTensor;
public IntPtr OutputGradientTensor;
public IntPtr OutputROIGradientTensor;
public int ReductionFunction;
public int InterpolationMode;
public float SpatialScaleX;
public float SpatialScaleY;
public float InputPixelOffset;
public float OutputPixelOffset;
public uint MinimumSamplesPerOutput;
public uint MaximumSamplesPerOutput;
[MarshalAs(UnmanagedType.Bool)] public bool AlignRegionsToCorners;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure DML_ROI_ALIGN_GRAD_OPERATOR_DESC
Public InputTensor As IntPtr
Public InputGradientTensor As IntPtr
Public ROITensor As IntPtr
Public BatchIndicesTensor As IntPtr
Public OutputGradientTensor As IntPtr
Public OutputROIGradientTensor As IntPtr
Public ReductionFunction As Integer
Public InterpolationMode As Integer
Public SpatialScaleX As Single
Public SpatialScaleY As Single
Public InputPixelOffset As Single
Public OutputPixelOffset As Single
Public MinimumSamplesPerOutput As UInteger
Public MaximumSamplesPerOutput As UInteger
<MarshalAs(UnmanagedType.Bool)> Public AlignRegionsToCorners As Boolean
End Structureimport ctypes
from ctypes import wintypes
class DML_ROI_ALIGN_GRAD_OPERATOR_DESC(ctypes.Structure):
_fields_ = [
("InputTensor", ctypes.c_void_p),
("InputGradientTensor", ctypes.c_void_p),
("ROITensor", ctypes.c_void_p),
("BatchIndicesTensor", ctypes.c_void_p),
("OutputGradientTensor", ctypes.c_void_p),
("OutputROIGradientTensor", ctypes.c_void_p),
("ReductionFunction", ctypes.c_int),
("InterpolationMode", ctypes.c_int),
("SpatialScaleX", ctypes.c_float),
("SpatialScaleY", ctypes.c_float),
("InputPixelOffset", ctypes.c_float),
("OutputPixelOffset", ctypes.c_float),
("MinimumSamplesPerOutput", wintypes.DWORD),
("MaximumSamplesPerOutput", wintypes.DWORD),
("AlignRegionsToCorners", wintypes.BOOL),
]#[repr(C)]
pub struct DML_ROI_ALIGN_GRAD_OPERATOR_DESC {
pub InputTensor: *mut core::ffi::c_void,
pub InputGradientTensor: *mut core::ffi::c_void,
pub ROITensor: *mut core::ffi::c_void,
pub BatchIndicesTensor: *mut core::ffi::c_void,
pub OutputGradientTensor: *mut core::ffi::c_void,
pub OutputROIGradientTensor: *mut core::ffi::c_void,
pub ReductionFunction: i32,
pub InterpolationMode: i32,
pub SpatialScaleX: f32,
pub SpatialScaleY: f32,
pub InputPixelOffset: f32,
pub OutputPixelOffset: f32,
pub MinimumSamplesPerOutput: u32,
pub MaximumSamplesPerOutput: u32,
pub AlignRegionsToCorners: i32,
}import "golang.org/x/sys/windows"
type DML_ROI_ALIGN_GRAD_OPERATOR_DESC struct {
InputTensor uintptr
InputGradientTensor uintptr
ROITensor uintptr
BatchIndicesTensor uintptr
OutputGradientTensor uintptr
OutputROIGradientTensor uintptr
ReductionFunction int32
InterpolationMode int32
SpatialScaleX float32
SpatialScaleY float32
InputPixelOffset float32
OutputPixelOffset float32
MinimumSamplesPerOutput uint32
MaximumSamplesPerOutput uint32
AlignRegionsToCorners int32
}type
DML_ROI_ALIGN_GRAD_OPERATOR_DESC = record
InputTensor: Pointer;
InputGradientTensor: Pointer;
ROITensor: Pointer;
BatchIndicesTensor: Pointer;
OutputGradientTensor: Pointer;
OutputROIGradientTensor: Pointer;
ReductionFunction: Integer;
InterpolationMode: Integer;
SpatialScaleX: Single;
SpatialScaleY: Single;
InputPixelOffset: Single;
OutputPixelOffset: Single;
MinimumSamplesPerOutput: DWORD;
MaximumSamplesPerOutput: DWORD;
AlignRegionsToCorners: BOOL;
end;const DML_ROI_ALIGN_GRAD_OPERATOR_DESC = extern struct {
InputTensor: ?*anyopaque,
InputGradientTensor: ?*anyopaque,
ROITensor: ?*anyopaque,
BatchIndicesTensor: ?*anyopaque,
OutputGradientTensor: ?*anyopaque,
OutputROIGradientTensor: ?*anyopaque,
ReductionFunction: i32,
InterpolationMode: i32,
SpatialScaleX: f32,
SpatialScaleY: f32,
InputPixelOffset: f32,
OutputPixelOffset: f32,
MinimumSamplesPerOutput: u32,
MaximumSamplesPerOutput: u32,
AlignRegionsToCorners: i32,
};type
DML_ROI_ALIGN_GRAD_OPERATOR_DESC {.bycopy.} = object
InputTensor: pointer
InputGradientTensor: pointer
ROITensor: pointer
BatchIndicesTensor: pointer
OutputGradientTensor: pointer
OutputROIGradientTensor: pointer
ReductionFunction: int32
InterpolationMode: int32
SpatialScaleX: float32
SpatialScaleY: float32
InputPixelOffset: float32
OutputPixelOffset: float32
MinimumSamplesPerOutput: uint32
MaximumSamplesPerOutput: uint32
AlignRegionsToCorners: int32struct DML_ROI_ALIGN_GRAD_OPERATOR_DESC
{
void* InputTensor;
void* InputGradientTensor;
void* ROITensor;
void* BatchIndicesTensor;
void* OutputGradientTensor;
void* OutputROIGradientTensor;
int ReductionFunction;
int InterpolationMode;
float SpatialScaleX;
float SpatialScaleY;
float InputPixelOffset;
float OutputPixelOffset;
uint MinimumSamplesPerOutput;
uint MaximumSamplesPerOutput;
int AlignRegionsToCorners;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; DML_ROI_ALIGN_GRAD_OPERATOR_DESC サイズ: 60 バイト(x86)
dim st, 15 ; 4byte整数×15(構造体サイズ 60 / 4 切り上げ)
; InputTensor : DML_TENSOR_DESC* (+0, 4byte) varptr(st)+0 を基点に操作(4byte:入れ子/配列)
; InputGradientTensor : DML_TENSOR_DESC* (+4, 4byte) varptr(st)+4 を基点に操作(4byte:入れ子/配列)
; ROITensor : DML_TENSOR_DESC* (+8, 4byte) varptr(st)+8 を基点に操作(4byte:入れ子/配列)
; BatchIndicesTensor : DML_TENSOR_DESC* (+12, 4byte) varptr(st)+12 を基点に操作(4byte:入れ子/配列)
; OutputGradientTensor : DML_TENSOR_DESC* (+16, 4byte) varptr(st)+16 を基点に操作(4byte:入れ子/配列)
; OutputROIGradientTensor : DML_TENSOR_DESC* (+20, 4byte) varptr(st)+20 を基点に操作(4byte:入れ子/配列)
; ReductionFunction : DML_REDUCE_FUNCTION (+24, 4byte) st.6 = 値 / 値 = st.6 (lpoke/lpeek も可)
; InterpolationMode : DML_INTERPOLATION_MODE (+28, 4byte) st.7 = 値 / 値 = st.7 (lpoke/lpeek も可)
; SpatialScaleX : FLOAT (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; SpatialScaleY : FLOAT (+36, 4byte) st.9 = 値 / 値 = st.9 (lpoke/lpeek も可)
; InputPixelOffset : FLOAT (+40, 4byte) st.10 = 値 / 値 = st.10 (lpoke/lpeek も可)
; OutputPixelOffset : FLOAT (+44, 4byte) st.11 = 値 / 値 = st.11 (lpoke/lpeek も可)
; MinimumSamplesPerOutput : DWORD (+48, 4byte) st.12 = 値 / 値 = st.12 (lpoke/lpeek も可)
; MaximumSamplesPerOutput : DWORD (+52, 4byte) st.13 = 値 / 値 = st.13 (lpoke/lpeek も可)
; AlignRegionsToCorners : BOOL (+56, 4byte) st.14 = 値 / 値 = st.14 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; DML_ROI_ALIGN_GRAD_OPERATOR_DESC サイズ: 88 バイト(x64)
dim st, 22 ; 4byte整数×22(構造体サイズ 88 / 4 切り上げ)
; InputTensor : DML_TENSOR_DESC* (+0, 8byte) varptr(st)+0 を基点に操作(8byte:入れ子/配列)
; InputGradientTensor : DML_TENSOR_DESC* (+8, 8byte) varptr(st)+8 を基点に操作(8byte:入れ子/配列)
; ROITensor : DML_TENSOR_DESC* (+16, 8byte) varptr(st)+16 を基点に操作(8byte:入れ子/配列)
; BatchIndicesTensor : DML_TENSOR_DESC* (+24, 8byte) varptr(st)+24 を基点に操作(8byte:入れ子/配列)
; OutputGradientTensor : DML_TENSOR_DESC* (+32, 8byte) varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; OutputROIGradientTensor : DML_TENSOR_DESC* (+40, 8byte) varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; ReductionFunction : DML_REDUCE_FUNCTION (+48, 4byte) st.12 = 値 / 値 = st.12 (lpoke/lpeek も可)
; InterpolationMode : DML_INTERPOLATION_MODE (+52, 4byte) st.13 = 値 / 値 = st.13 (lpoke/lpeek も可)
; SpatialScaleX : FLOAT (+56, 4byte) st.14 = 値 / 値 = st.14 (lpoke/lpeek も可)
; SpatialScaleY : FLOAT (+60, 4byte) st.15 = 値 / 値 = st.15 (lpoke/lpeek も可)
; InputPixelOffset : FLOAT (+64, 4byte) st.16 = 値 / 値 = st.16 (lpoke/lpeek も可)
; OutputPixelOffset : FLOAT (+68, 4byte) st.17 = 値 / 値 = st.17 (lpoke/lpeek も可)
; MinimumSamplesPerOutput : DWORD (+72, 4byte) st.18 = 値 / 値 = st.18 (lpoke/lpeek も可)
; MaximumSamplesPerOutput : DWORD (+76, 4byte) st.19 = 値 / 値 = st.19 (lpoke/lpeek も可)
; AlignRegionsToCorners : BOOL (+80, 4byte) st.20 = 値 / 値 = st.20 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global DML_ROI_ALIGN_GRAD_OPERATOR_DESC
#field intptr InputTensor
#field intptr InputGradientTensor
#field intptr ROITensor
#field intptr BatchIndicesTensor
#field intptr OutputGradientTensor
#field intptr OutputROIGradientTensor
#field int ReductionFunction
#field int InterpolationMode
#field float SpatialScaleX
#field float SpatialScaleY
#field float InputPixelOffset
#field float OutputPixelOffset
#field int MinimumSamplesPerOutput
#field int MaximumSamplesPerOutput
#field bool AlignRegionsToCorners
#endstruct
stdim st, DML_ROI_ALIGN_GRAD_OPERATOR_DESC ; NSTRUCT 変数を確保
st->ReductionFunction = 100
mes "ReductionFunction=" + st->ReductionFunction