カスタム深層学習演算の定義
ヒント
このトピックでは、問題に合わせてカスタム深層学習演算を定義する方法について説明します。ニューラル ネットワークの組み込み層の一覧については、深層学習層の一覧を参照してください。カスタム層や、関数として定義された深層学習モデルをサポートする関数の一覧については、dlarray をサポートする関数の一覧を参照してください。
カスタム損失関数やカスタム層 forward 関数を定義したり、深層学習モデルを関数として定義したりする際、目的のタスクに必要な深層学習演算がソフトウェアに用意されていない場合は、dlarray オブジェクトを使用して独自の関数を定義できます。詳細については、MATLAB 関数としてのカスタム演算の定義を参照してください。
ほとんどの深層学習ワークフローでは、勾配を使用してモデルに学習させます。関数が dlarray オブジェクトをサポートする関数のみを使用する場合は、関数を直接使用することができます。また、ソフトウェアは自動微分を使用して勾配を自動的に求めます。たとえば、crossentropy などの dlarray オブジェクト関数を損失関数として trainnet 関数に渡したり、dlconv などの dlarray オブジェクト関数をカスタム層関数で使用したりできます。dlarray オブジェクトをサポートしている関数の一覧については、dlarray をサポートする関数の一覧を参照してください。
dlarray オブジェクトをサポートしていない関数を使用する場合、または特定のアルゴリズムを使用して勾配を計算する場合は、微分可能な関数オブジェクトとしてカスタム深層学習演算を定義できます。詳細については、DifferentiableFunction オブジェクトとしてのカスタム演算の定義を参照してください。
深層学習演算のアーキテクチャ
学習時には、深層学習モデルのフォワード パスとバックワード パスが反復して実行されます。
モデルのフォワード パスでは、各演算は前の演算の出力と追加のパラメーター (学習可能パラメーターと状態パラメーターを含む) を取得し、関数を適用して、結果と更新状態パラメーターを次の演算に出力 (順伝播) します。
深層学習演算では複数の入力または出力を使用できます。たとえば、ある演算は、複数の前の演算から X1、…、XN を受け取り、出力 Y1、…、YM を後続の演算に順伝播できます。
深層学習モデルのフォワード パスの最後に、ソフトウェアは予測とターゲットの間の損失 L を計算します。
モデルのバックワード パスでは、各演算は演算の出力についての損失の微分を受け取り、入力についての損失 L の微分を計算し、その結果を逆伝播します。ソフトウェアはこれらの微分を使用して学習可能なパラメーターを更新します。計算量を節約するために、forward 関数はオプションのメモリ出力を使用して backward 関数と情報を共有できます。
次の図は、深層学習演算におけるデータのフローを描いたもので、1 つの入力 X と 1 つの出力 Y をもつ演算のデータ フローを示しています。

MATLAB 関数としてのカスタム演算の定義
MATLAB® で dlarray オブジェクトの関数を定義します。
たとえば、SReLU 演算を適用する関数を作成するには、次を使用します。
function Y = srelu(X,tl,al,tr,ar) % Y = srelu(X,tl,al,tr,ar) applies the SReLU operation to the input % data X using the specified left threshold and slope tl and al, % respectively, and the right threshold and slope tr and ar, % respectively. Y = (X <= tl) .* (tl + al.*(X-tl)) ... + ((tl < X) & (X < tr)) .* X ... + (tr <= X) .* (tr + ar.*(X-tr)); end
この関数は dlarray オブジェクトを完全にサポートしているため、関数は自動微分をサポートします。自動微分のサポートにより、この関数をカスタム損失関数、カスタム層関数、関数として定義された深層学習モデルの一部として使用できます。
関数は、カスタム損失関数、カスタム層関数、および関数として定義された深層学習モデルで使用できます。たとえば、ランダム データで関数を評価するには、次のようにします。
X = rand([224 224 3 128]); Y = srelu(X);
DifferentiableFunction オブジェクトとしてのカスタム演算の定義
dlarray オブジェクトをサポートしていない関数を使用する場合、または特定のアルゴリズムを使用して勾配を計算する場合は、カスタム深層学習関数を定義できます。
カスタム演算テンプレート
カスタム深層学習演算を定義するには、このクラス定義テンプレートを使用します。このテンプレートは、カスタム演算クラス定義の構造を提供します。概要は次のとおりです。
演算のプロパティを定義するオプションの
propertiesブロック。コンストラクター関数。
forward関数。backward関数。
classdef myFunction < deep.DifferentiableFunction properties % (Optional) Operation properties. % Declare operation properties here. end methods function fcn = myFunction % Create a myFunction. % This function must have the same name as the class. fcn@deep.DifferentiableFunction(numOutputs, ... SaveInputsForBackward=tf, ... SaveOutputsForBackward=tf, ... NumMemoryValues=K); end function [Y,memory] = forward(fcn,X) % Forward input data through the function and output the result % and a memory value. % % Inputs: % fcn - Function object to forward propagate through % X - Function input data % Outputs: % Y - Output of function forward function % memory - (Optional) Memory value for backward % function % % - For functions with multiple inputs, replace X with % X1,...,XN, where N is the number of inputs. % - For functions with multiple outputs, replace Y with % Y1,...,YM, where M is the number of outputs. % - For functions with multiple memory outputs, replace % memory with memory1,...,memoryK, where K is the % number of memory outputs. % Define forward function here. end function dLdX = backward(fcn,dLdY,computeGradients,X,Y,memory) % Backward propagate the derivative of the loss function % through the function. % % Inputs: % fcn - Function object to backward % propagate through % dLdY - Derivative of loss with respect to % function output % computeGradients - Logical flag indicating whether to % compute gradients % X - (Optional) Function input data % Y - (Optional) Function output data % memory - (Optional) Memory value from % forward function % Outputs: % dLdX - Derivative of loss with respect to function % input % % - For functions with multiple inputs, replace X and dLdX % with X1,...,XN and dLdX1,...,dLdXN, respectively, where N % is the number of inputs. In this case, computeGradients is % a logical vector of size N, where non-zero elements % indicate to compute gradients for the corresponding input. % - For functions with multiple outputs, replace Y and dLdY % with Y1,...,YM and dLdY,...,dLdYM, respectively, where M % is the number of outputs. % Define backward function here. end end end
forward 関数
forward 関数は、深層学習フォワード パス演算を定義します。構文は [Y,memory] = forward(~,X) となります。この関数は次の入力と出力をもちます。
X— 演算入力データ。Y— 演算出力データ。memory(オプション) — backward 関数用のメモリ値。backward 関数での計算の繰り返しを回避するには、この出力を使用して backward 関数とデータを共有します。メモリ値を使用するには、コンストラクター関数のdeep.DifferentiableFunctionのNumMemoryValues引数を正の整数に設定します。
次のようにして、この構文を複数の入力、出力、およびメモリ値をもつ演算用に調整できます。
複数の入力をもつ演算の場合、
XをX1,...,XNに置き換えます。ここで、Nは入力の数です。複数の出力をもつ演算の場合、
YをY1,...,YMに置き換えます。ここで、Mは出力の数です。複数のメモリ値をもつ演算の場合、
memoryをmemory1,...,memoryKに置き換えます。ここで、Kはメモリ値の数です。
ヒント
演算への入力の数が変化する可能性がある場合、X1,…,XN ではなく varargin を使用します。この場合、varargin は入力の cell 配列です。ここで、varargin{i} は Xi に対応します。
backward 関数
backward 関数は、operation backward 関数を定義します。構文は dLdX = backward(fcn,dLdY,computeGradients,X,Y,memory) となります。この関数は次の入力と出力をもちます。
fcn— 逆伝播する微分可能な関数オブジェクト。dLdY— 演算出力データYに対する損失の勾配。computeGradients— 入力の勾配を計算するかどうかを示す論理フラグ。1(true) または0(false) として指定します。X(オプション) — 演算入力データ。演算入力データを使用するには、コンストラクター関数のdeep.DifferentiableFunctionのSaveInputsForBackward引数を1(true) に設定します。Y(オプション) — 演算出力データ。演算出力データを使用するには、コンストラクター関数のdeep.DifferentiableFunctionのSaveOutputsForBackward引数を1(true) に設定します。memory(オプション) — forward 関数からのメモリ値。メモリ値を使用するには、コンストラクター関数のdeep.DifferentiableFunctionのNumMemoryValues引数を正の整数に設定します。dLdX— 演算入力データXに対する損失の勾配。
X と Y の値は forward 関数の場合と同じです。dLdY の次元は Y の次元と同じです。
dLdX の次元およびデータ型は、X の次元およびデータ型と同じです。
この構文は、複数の入力と複数の出力をもつ演算用に調整できます。
複数の入力をもつ演算の場合、
XとdLdXをそれぞれX1,...,XNとdLdX1,...,dLdXNに置き換えます。ここで、Nは入力の数です。この場合、computeGradientsはサイズNの logical ベクトルであり、ゼロでない要素は対応する入力の勾配を計算することを示します。複数の出力をもつ演算の場合、
YとdLdYをそれぞれY1,...,YMとdLdY1,...,dLdYMに置き換えます。ここで、Mは出力の数です。複数のメモリ出力をもつ演算の場合、
memoryをmemory1,...,memoryKに置き換えます。ここで、Kはメモリ値の数です。
フォワード パスとバックワード パスの間に使用されない変数が保存されることを防いでメモリ使用量を削減するには、対応する入力引数を ~ に置き換えます。
ヒント
backward への入力の数が変化する可能性がある場合、fcn の後に入力引数ではなく varargin を使用します。この場合、varargin は入力の cell 配列です。これは、以下のようになります。
最初の
M個の要素は、M個の微分dLdY1,...,dLdYMに対応する。次の要素は
computeGradientsに対応する。次の
N個の要素は、N個の入力X1,...,XNに対応する。次の
M個の要素は、M個の出力Y1,...,YMに対応する。残りの要素はメモリ値に対応する。
入力データに対する損失の微分を計算するには、出力データに対する損失の微分と入力データに対する出力データの微分を使って、連鎖律を使用できます。
インターフェイス関数の作成
微分可能な関数オブジェクトのインスタンスを作成した後、そのオブジェクトを MATLAB 関数の場合と同様にして評価できます。この関数を他の dlarray オブジェクト関数と一緒に簡単に組み込めるようにするには、dlarray オブジェクトを入力として受け取り、dlarray オブジェクトを返す関数を作成します。この関数内で、微分可能な関数オブジェクトを作成および構成し、評価します。
たとえば、微分可能な関数を作成して評価するカスタム SReLU 関数を作成するには、次を使用します。
function Y = srelu(X,tl,al,tr,ar) format = dims(X); fcn = sreluFunction(format); Y = fcn(X,tl,al,tr,ar); Y = dlarray(Y,format); end
GPU 互換性
MATLAB 関数として定義されたカスタム演算は GPU 互換になります。関数が dlarray オブジェクトを完全にサポートしている場合、関数は GPU 互換になります。
DifferentiableFunction オブジェクトとして定義されたカスタム演算では、forward 関数と backward 関数が gpuArray (Parallel Computing Toolbox) オブジェクトを完全にサポートしている場合、関数オブジェクトは GPU 互換になります。
多くの MATLAB 組み込み関数が入力引数 gpuArray (Parallel Computing Toolbox) および dlarray をサポートしています。GPU で実行される関数の一覧については、GPU での MATLAB 関数の実行 (Parallel Computing Toolbox)を参照してください。深層学習に GPU を使用するには、サポートされている GPU デバイスもなければなりません。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。MATLAB での GPU の使用の詳細は、MATLAB での GPU 計算 (Parallel Computing Toolbox)を参照してください。
参考
trainnet | trainingOptions | dlnetwork | functionLayer