DML_ADAM_OPTIMIZER_OPERATOR_DESC
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 |
|---|---|---|---|---|---|
| InputParametersTensor | DML_TENSOR_DESC* | 8/4 | +0 | +0 | このオプティマイザーを適用するパラメーター (重み) を格納したテンソルです。このテンソルで指定された重みの値に対して勾配降下を実行するために、勾配、一次および二次モーメント推定値、現在のトレーニングステップ、さらにハイパーパラメーターである LearningRate、Beta1、Beta2 が使用されます。 |
| InputFirstMomentTensor | DML_TENSOR_DESC* | 8/4 | +8 | +4 | 各重みの値に対する勾配の一次モーメント推定値を格納したテンソルです。これらの値は通常、この演算子を前回実行した結果として OutputFirstMomentTensor から取得します。 一連の重みにこのオプティマイザーを初めて適用する場合 (最初のトレーニングステップなど)、このテンソルの値は通常 0 に初期化します。以降の実行では、OutputFirstMomentTensor で返された値を使用します。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| InputSecondMomentTensor | DML_TENSOR_DESC* | 8/4 | +16 | +8 | 各重みの値に対する勾配の二次モーメント推定値を格納したテンソルです。これらの値は通常、この演算子を前回実行した結果として OutputSecondMomentTensor から取得します。 一連の重みにこのオプティマイザーを初めて適用する場合 (最初のトレーニングステップなど)、このテンソルの値は通常 0 に初期化します。以降の実行では、OutputSecondMomentTensor で返された値を使用します。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| GradientTensor | DML_TENSOR_DESC* | 8/4 | +24 | +12 | 勾配降下のために入力パラメーター (重み) に適用する勾配です。勾配は通常、トレーニング中の逆伝播パスで取得されます。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| TrainingStepTensor | DML_TENSOR_DESC* | 8/4 | +32 | +16 | 現在のトレーニングステップ数を表す単一の整数値を格納したスカラーテンソルです。この値は Beta1 および Beta2 とともに、一次および二次モーメント推定値テンソルの指数減衰を計算するために使用されます。 通常、トレーニングステップの値はトレーニング開始時に 0 から始まり、トレーニングステップごとに 1 ずつ加算されます。この演算子はトレーニングステップの値を更新しません。たとえば DML_OPERATOR_ELEMENT_WISE_ADD を使用するなどして、手動で更新する必要があります。 このテンソルはスカラー (つまり、すべての Sizes が 1) でなければならず、データ型は DML_TENSOR_DATA_TYPE_UINT32 でなければなりません。 |
| OutputParametersTensor | DML_TENSOR_DESC* | 8/4 | +40 | +20 | 勾配降下の適用後の、更新されたパラメーター (重み) の値を保持する出力テンソルです。 バインド時に、このテンソルは条件を満たす入力テンソルとエイリアスにすることが許可されており、これによりこのテンソルのインプレース更新を実行できます。詳細については 解説 セクションを参照してください。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| OutputFirstMomentTensor | DML_TENSOR_DESC* | 8/4 | +48 | +24 | 更新後の一次モーメント推定値を格納する出力テンソルです。このテンソルの値は保存しておき、次のトレーニングステップで InputFirstMomentTensor に指定します。 バインド時に、このテンソルは条件を満たす入力テンソルとエイリアスにすることが許可されており、これによりこのテンソルのインプレース更新を実行できます。詳細については 解説 セクションを参照してください。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| OutputSecondMomentTensor | DML_TENSOR_DESC* | 8/4 | +56 | +28 | 更新後の二次モーメント推定値を格納する出力テンソルです。このテンソルの値は保存しておき、次のトレーニングステップで InputSecondMomentTensor に指定します。 バインド時に、このテンソルは条件を満たす入力テンソルとエイリアスにすることが許可されており、これによりこのテンソルのインプレース更新を実行できます。詳細については 解説 セクションを参照してください。 このテンソルの Sizes と DataType は、InputParametersTensor のものと完全に一致していなければなりません。 |
| LearningRate | FLOAT | 4 | +64 | +32 | 学習率です。一般に ステップサイズ とも呼ばれます。学習率は、各トレーニングステップにおける勾配ベクトルに沿った重み更新の大きさを決定するハイパーパラメーターです。 |
| Beta1 | FLOAT | 4 | +68 | +36 | 勾配の一次モーメント推定値の指数減衰率を表すハイパーパラメーターです。この値は 0.0 から 1.0 の間でなければなりません。一般的な値は 0.9f です。 |
| Beta2 | FLOAT | 4 | +72 | +40 | 勾配の二次モーメント推定値の指数減衰率を表すハイパーパラメーターです。この値は 0.0 から 1.0 の間でなければなりません。一般的な値は 0.999f です。 |
| Epsilon | FLOAT | 4 | +76 | +44 | 0 による除算を防いで数値的な安定性を高めるために使用される小さな値です。32 ビット浮動小数点の入力の場合、一般的な値は 1e-8 や FLT_EPSILON です。 |
公式ドキュメント
Adam (ADAptive Moment estimation) アルゴリズムに基づき、指定された勾配を使用して更新後の重み (パラメーター) を計算します。この演算子はオプティマイザーであり、通常はトレーニングループの重み更新ステップで勾配降下を実行するために使用されます。
この演算子は次の計算を実行します。
X = InputParametersTensor
M = InputFirstMomentTensor
V = InputSecondMomentTensor
G = GradientTensor
T = TrainingStepTensor
// Compute updated first and second moment estimates.
M = Beta1 * M + (1.0 - Beta1) * G
V = Beta2 * V + (1.0 - Beta2) * G * G
// Compute bias correction factor for first and second moment estimates.
Alpha = sqrt(1.0 - pow(Beta2, T)) / (1.0 - pow(Beta1, T))
X -= LearningRate * Alpha * M / (sqrt(V) + Epsilon)
OutputParametersTensor = X
OutputFirstMomentTensor = M
OutputSecondMomentTensor = V
この演算子は、更新後の重みパラメーター (OutputParametersTensor で返されます) を計算するのに加えて、更新後の一次モーメント推定値と二次モーメント推定値をそれぞれ OutputFirstMomentTensor と OutputSecondMomentTensor で返します。通常、これらの一次モーメント推定値および二次モーメント推定値は保存しておき、次のトレーニングステップで入力として指定します。
解説(Remarks)
この演算子はインプレース実行をサポートします。つまり、バインド時に各出力テンソルを条件を満たす入力テンソルとエイリアスにすることが許可されています。たとえば、InputParametersTensor と OutputParametersTensor の両方に同じリソースをバインドすることで、入力パラメーターのインプレース更新を実質的に実現できます。この演算子の入力テンソルは、TrainingStepTensor を除きすべて、このようにエイリアスにすることができます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// DML_ADAM_OPTIMIZER_OPERATOR_DESC (x64 80 / x86 48 バイト)
typedef struct DML_ADAM_OPTIMIZER_OPERATOR_DESC {
DML_TENSOR_DESC* InputParametersTensor;
DML_TENSOR_DESC* InputFirstMomentTensor;
DML_TENSOR_DESC* InputSecondMomentTensor;
DML_TENSOR_DESC* GradientTensor;
DML_TENSOR_DESC* TrainingStepTensor;
DML_TENSOR_DESC* OutputParametersTensor;
DML_TENSOR_DESC* OutputFirstMomentTensor;
DML_TENSOR_DESC* OutputSecondMomentTensor;
FLOAT LearningRate;
FLOAT Beta1;
FLOAT Beta2;
FLOAT Epsilon;
} DML_ADAM_OPTIMIZER_OPERATOR_DESC;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DML_ADAM_OPTIMIZER_OPERATOR_DESC
{
public IntPtr InputParametersTensor;
public IntPtr InputFirstMomentTensor;
public IntPtr InputSecondMomentTensor;
public IntPtr GradientTensor;
public IntPtr TrainingStepTensor;
public IntPtr OutputParametersTensor;
public IntPtr OutputFirstMomentTensor;
public IntPtr OutputSecondMomentTensor;
public float LearningRate;
public float Beta1;
public float Beta2;
public float Epsilon;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure DML_ADAM_OPTIMIZER_OPERATOR_DESC
Public InputParametersTensor As IntPtr
Public InputFirstMomentTensor As IntPtr
Public InputSecondMomentTensor As IntPtr
Public GradientTensor As IntPtr
Public TrainingStepTensor As IntPtr
Public OutputParametersTensor As IntPtr
Public OutputFirstMomentTensor As IntPtr
Public OutputSecondMomentTensor As IntPtr
Public LearningRate As Single
Public Beta1 As Single
Public Beta2 As Single
Public Epsilon As Single
End Structureimport ctypes
from ctypes import wintypes
class DML_ADAM_OPTIMIZER_OPERATOR_DESC(ctypes.Structure):
_fields_ = [
("InputParametersTensor", ctypes.c_void_p),
("InputFirstMomentTensor", ctypes.c_void_p),
("InputSecondMomentTensor", ctypes.c_void_p),
("GradientTensor", ctypes.c_void_p),
("TrainingStepTensor", ctypes.c_void_p),
("OutputParametersTensor", ctypes.c_void_p),
("OutputFirstMomentTensor", ctypes.c_void_p),
("OutputSecondMomentTensor", ctypes.c_void_p),
("LearningRate", ctypes.c_float),
("Beta1", ctypes.c_float),
("Beta2", ctypes.c_float),
("Epsilon", ctypes.c_float),
]#[repr(C)]
pub struct DML_ADAM_OPTIMIZER_OPERATOR_DESC {
pub InputParametersTensor: *mut core::ffi::c_void,
pub InputFirstMomentTensor: *mut core::ffi::c_void,
pub InputSecondMomentTensor: *mut core::ffi::c_void,
pub GradientTensor: *mut core::ffi::c_void,
pub TrainingStepTensor: *mut core::ffi::c_void,
pub OutputParametersTensor: *mut core::ffi::c_void,
pub OutputFirstMomentTensor: *mut core::ffi::c_void,
pub OutputSecondMomentTensor: *mut core::ffi::c_void,
pub LearningRate: f32,
pub Beta1: f32,
pub Beta2: f32,
pub Epsilon: f32,
}import "golang.org/x/sys/windows"
type DML_ADAM_OPTIMIZER_OPERATOR_DESC struct {
InputParametersTensor uintptr
InputFirstMomentTensor uintptr
InputSecondMomentTensor uintptr
GradientTensor uintptr
TrainingStepTensor uintptr
OutputParametersTensor uintptr
OutputFirstMomentTensor uintptr
OutputSecondMomentTensor uintptr
LearningRate float32
Beta1 float32
Beta2 float32
Epsilon float32
}type
DML_ADAM_OPTIMIZER_OPERATOR_DESC = record
InputParametersTensor: Pointer;
InputFirstMomentTensor: Pointer;
InputSecondMomentTensor: Pointer;
GradientTensor: Pointer;
TrainingStepTensor: Pointer;
OutputParametersTensor: Pointer;
OutputFirstMomentTensor: Pointer;
OutputSecondMomentTensor: Pointer;
LearningRate: Single;
Beta1: Single;
Beta2: Single;
Epsilon: Single;
end;const DML_ADAM_OPTIMIZER_OPERATOR_DESC = extern struct {
InputParametersTensor: ?*anyopaque,
InputFirstMomentTensor: ?*anyopaque,
InputSecondMomentTensor: ?*anyopaque,
GradientTensor: ?*anyopaque,
TrainingStepTensor: ?*anyopaque,
OutputParametersTensor: ?*anyopaque,
OutputFirstMomentTensor: ?*anyopaque,
OutputSecondMomentTensor: ?*anyopaque,
LearningRate: f32,
Beta1: f32,
Beta2: f32,
Epsilon: f32,
};type
DML_ADAM_OPTIMIZER_OPERATOR_DESC {.bycopy.} = object
InputParametersTensor: pointer
InputFirstMomentTensor: pointer
InputSecondMomentTensor: pointer
GradientTensor: pointer
TrainingStepTensor: pointer
OutputParametersTensor: pointer
OutputFirstMomentTensor: pointer
OutputSecondMomentTensor: pointer
LearningRate: float32
Beta1: float32
Beta2: float32
Epsilon: float32struct DML_ADAM_OPTIMIZER_OPERATOR_DESC
{
void* InputParametersTensor;
void* InputFirstMomentTensor;
void* InputSecondMomentTensor;
void* GradientTensor;
void* TrainingStepTensor;
void* OutputParametersTensor;
void* OutputFirstMomentTensor;
void* OutputSecondMomentTensor;
float LearningRate;
float Beta1;
float Beta2;
float Epsilon;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; DML_ADAM_OPTIMIZER_OPERATOR_DESC サイズ: 48 バイト(x86)
dim st, 12 ; 4byte整数×12(構造体サイズ 48 / 4 切り上げ)
; InputParametersTensor : DML_TENSOR_DESC* (+0, 4byte) varptr(st)+0 を基点に操作(4byte:入れ子/配列)
; InputFirstMomentTensor : DML_TENSOR_DESC* (+4, 4byte) varptr(st)+4 を基点に操作(4byte:入れ子/配列)
; InputSecondMomentTensor : DML_TENSOR_DESC* (+8, 4byte) varptr(st)+8 を基点に操作(4byte:入れ子/配列)
; GradientTensor : DML_TENSOR_DESC* (+12, 4byte) varptr(st)+12 を基点に操作(4byte:入れ子/配列)
; TrainingStepTensor : DML_TENSOR_DESC* (+16, 4byte) varptr(st)+16 を基点に操作(4byte:入れ子/配列)
; OutputParametersTensor : DML_TENSOR_DESC* (+20, 4byte) varptr(st)+20 を基点に操作(4byte:入れ子/配列)
; OutputFirstMomentTensor : DML_TENSOR_DESC* (+24, 4byte) varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; OutputSecondMomentTensor : DML_TENSOR_DESC* (+28, 4byte) varptr(st)+28 を基点に操作(4byte:入れ子/配列)
; LearningRate : FLOAT (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; Beta1 : FLOAT (+36, 4byte) st.9 = 値 / 値 = st.9 (lpoke/lpeek も可)
; Beta2 : FLOAT (+40, 4byte) st.10 = 値 / 値 = st.10 (lpoke/lpeek も可)
; Epsilon : FLOAT (+44, 4byte) st.11 = 値 / 値 = st.11 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; DML_ADAM_OPTIMIZER_OPERATOR_DESC サイズ: 80 バイト(x64)
dim st, 20 ; 4byte整数×20(構造体サイズ 80 / 4 切り上げ)
; InputParametersTensor : DML_TENSOR_DESC* (+0, 8byte) varptr(st)+0 を基点に操作(8byte:入れ子/配列)
; InputFirstMomentTensor : DML_TENSOR_DESC* (+8, 8byte) varptr(st)+8 を基点に操作(8byte:入れ子/配列)
; InputSecondMomentTensor : DML_TENSOR_DESC* (+16, 8byte) varptr(st)+16 を基点に操作(8byte:入れ子/配列)
; GradientTensor : DML_TENSOR_DESC* (+24, 8byte) varptr(st)+24 を基点に操作(8byte:入れ子/配列)
; TrainingStepTensor : DML_TENSOR_DESC* (+32, 8byte) varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; OutputParametersTensor : DML_TENSOR_DESC* (+40, 8byte) varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; OutputFirstMomentTensor : DML_TENSOR_DESC* (+48, 8byte) varptr(st)+48 を基点に操作(8byte:入れ子/配列)
; OutputSecondMomentTensor : DML_TENSOR_DESC* (+56, 8byte) varptr(st)+56 を基点に操作(8byte:入れ子/配列)
; LearningRate : FLOAT (+64, 4byte) st.16 = 値 / 値 = st.16 (lpoke/lpeek も可)
; Beta1 : FLOAT (+68, 4byte) st.17 = 値 / 値 = st.17 (lpoke/lpeek も可)
; Beta2 : FLOAT (+72, 4byte) st.18 = 値 / 値 = st.18 (lpoke/lpeek も可)
; Epsilon : FLOAT (+76, 4byte) st.19 = 値 / 値 = st.19 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global DML_ADAM_OPTIMIZER_OPERATOR_DESC
#field intptr InputParametersTensor
#field intptr InputFirstMomentTensor
#field intptr InputSecondMomentTensor
#field intptr GradientTensor
#field intptr TrainingStepTensor
#field intptr OutputParametersTensor
#field intptr OutputFirstMomentTensor
#field intptr OutputSecondMomentTensor
#field float LearningRate
#field float Beta1
#field float Beta2
#field float Epsilon
#endstruct
stdim st, DML_ADAM_OPTIMIZER_OPERATOR_DESC ; NSTRUCT 変数を確保
st->LearningRate = 100
mes "LearningRate=" + st->LearningRate