Deep Learning Toolbox での自動微分の使用
自動微分を使用したカスタム学習と計算
自動微分は、カスタム学習ループ、カスタム層、および深層学習のその他のカスタマイズの作成を容易にします。
一般的に、深層学習における学習をカスタマイズする最も簡単な方法は、dlnetwork
を作成することです。必要な層をネットワークに含めます。次に、ある種の勾配降下を使用して、カスタム ループの学習を実行します。ここで、勾配は目的関数の勾配です。目的関数には、分類誤差、交差エントロピー、またはネットワークの重みのその他の関連スカラー関数を使用できます。dlarray をサポートする関数の一覧を参照してください。
次の例は、高度なカスタム学習ループを示します。ここで、f
は損失などの目的関数、g
はネットワーク net
の重みについての目的関数の勾配です。関数 update
は、ある種の勾配降下を表します。
% High-level training loop n = 1; while (n < nmax) [f,g] = dlfeval(@model,net,X,T); net = update(net,g); n = n + 1; end
dlfeval
を呼び出して目的関数と勾配の数値を計算します。勾配の自動計算を有効にするには、データ X
が dlarray
でなければなりません。
X = dlarray(X);
目的関数には dlgradient
の呼び出しによる勾配の計算が含まれます。dlgradient
の呼び出しは、dlfeval
で評価を行う関数に含まれていなければなりません。
function [f,g] = model(net,X,T) % Calculate objective using supported functions for dlarray Y = forward(net,X); f = fcnvalue(Y,T); % crossentropy or similar g = dlgradient(f,net.Learnables); % Automatic gradient end
dlfeval
-dlgradient
-dlarray
構文とカスタム学習ループを使った dlnetwork
の使用例については、カスタム学習ループを使用したネットワークの学習を参照してください。自動微分を使用するカスタム学習の詳細は、カスタム学習ループ、損失関数、およびネットワークの定義を参照してください。
自動微分への dlgradient
と dlfeval
の併用
自動微分を使用するには、関数に含まれる dlgradient
を呼び出し、dlfeval
を使用して関数を評価しなければなりません。微分を取得する点を dlarray
オブジェクトとして表します。これにより、データ構造が管理され、評価のトレースが有効になります。たとえば、Rosenbrock 関数は最適化の一般的なテスト関数です。
function [f,grad] = rosenbrock(x) f = 100*(x(2) - x(1).^2).^2 + (1 - x(1)).^2; grad = dlgradient(f,x); end
点 x0
= [–1,2] で Rosenbrock 関数の値と勾配を計算します。Rosenbrock 関数で自動微分を有効にするには、x0
を dlarray
として渡します。
x0 = dlarray([-1,2]); [fval,gradval] = dlfeval(@rosenbrock,x0)
fval = 1x1 dlarray 104 gradval = 1x2 dlarray 396 200
自動微分の使用例については、カスタム学習ループを使用したネットワークの学習を参照してください。
微分のトレース
勾配を数値的に評価するために、dlarray
は、自動微分の背景で説明するように、リバース モードの微分用のデータ構造を構築します。このデータ構造は、微分計算の "トレース" です。自動微分と微分のトレースを使用する際には、次のガイドラインに留意してください。
新しい
dlarray
を目的関数の計算に含めたり、そのオブジェクトについて微分を試みないでください。次に例を示します。function [dy,dy1] = fun(x1) x2 = dlarray(0); y = x1 + x2; dy = dlgradient(y,x2); % Error: x2 is untraced dy1 = dlgradient(y,x1); % No error even though y has an untraced portion end
extractdata
をトレースされた引数と使用しないでください。これを行うと、トレースが破損します。次に例を示します。fun = @(x)dlgradient(x + atan(extractdata(x)),x); % Gradient for any point is 1 due to the leading 'x' term in fun. dlfeval(fun,dlarray(2.5))
ans = 1x1 dlarray 1
ただし、
extractdata
を使用すると、従属変数から新しい独立変数を導入できます。並列処理中にトレース対象の dlarray オブジェクトをクライアントとワーカーの間で移動すると、トレースが中断します。トレース対象の dlarray オブジェクトは、ワーカーに保存され、未トレースの dlarray オブジェクトとしてクライアントに読み込まれます。並列処理中にトレースが中断されないようにするには、必要な勾配をワーカー上ですべて計算してから、それらの勾配をクライアント上で結合します。例については、カスタム学習ループを使用したネットワークの並列学習を参照してください。
サポートされている関数のみを使用してください。サポートされている関数のリストについては、dlarray をサポートする関数の一覧を参照してください。サポートされていない関数 f を使用するには、サポートされている関数を使用して f の実装を試みます。
自動微分の特性
自動微分を使用した勾配の評価は、スカラー値関数に対してのみ行えます。中間の計算には任意の数の変数を使用できますが、最終関数値はスカラーでなければなりません。ベクトル値関数の微分を取得する必要がある場合、一度に 1 つの成分の微分を取得します。この場合、
dlgradient
の名前と値のペアの引数'RetainData'
をtrue
に設定することを検討してください。dlgradient
を呼び出すと、特定の点での微分が評価されます。理論値がない場合、一般的に、微分の値について任意の選択が行われます。たとえば、関数relu
のrelu(x) = max(x,0)
はx = 0
では微分不可能です。一方、dlgradient
は微分の値を返します。x = dlarray(0); y = dlfeval(@(t)dlgradient(relu(t),t),x)
y = 1x1 dlarray 0
近傍点
eps
での値は異なります。x = dlarray(eps); y = dlfeval(@(t)dlgradient(relu(t),t),x)
y = 1x1 dlarray 1
参考
dlarray
| dlgradient
| dlfeval
| dlnetwork