Main Content

dlfeval

カスタム学習ループ用の深層学習モデルの評価

説明

dlfeval を使用して、カスタム学習ループ用のカスタム深層学習モデルを評価します。

ヒント

ほとんどの深層学習タスクでは、事前学習済みのネットワークを使用して独自のデータに適応させることができます。転移学習を使用して、畳み込みニューラル ネットワークの再学習を行い、新しい一連のイメージを分類する方法を示す例については、新しいイメージを分類するための深層学習ネットワークの学習を参照してください。または、layerGraph オブジェクトを関数 trainNetwork および関数 trainingOptions と共に使用して、ネットワークを作成してゼロから学習させることができます。

タスクに必要な学習オプションが関数 trainingOptions に用意されていない場合、自動微分を使用してカスタム学習ループを作成できます。詳細については、カスタム学習ループ向けの深層学習ネットワークの定義を参照してください。

[y1,...,yk] = dlfeval(fun,x1,...,xn) は、入力引数 x1,...,xn に基づいて深層学習配列関数 fun を評価します。dlfeval に渡される関数には、dlgradient の呼び出しを含めることができます。これは、自動微分を使用し、入力 x1,...,xn から勾配を計算します。

すべて折りたたむ

Rosenbrock 関数は、最適化の標準的なテスト関数です。補助関数 rosenbrock.m は、関数の値を計算し、自動微分を使用してその勾配を計算します。

type rosenbrock.m
function [y,dydx] = rosenbrock(x)

y = 100*(x(2) - x(1).^2).^2 + (1 - x(1)).^2;
dydx = dlgradient(y,x);

end

[–1,2] における Rosenbrock 関数とその勾配を評価するには、その点の dlarray を作成してから、関数ハンドル @rosenbrock を指定して dlfeval を呼び出します。

x0 = dlarray([-1,2]);
[fval,gradval] = dlfeval(@rosenbrock,x0)
fval = 
  1x1 dlarray

   104

gradval = 
  1x2 dlarray

   396   200

または、2 つの入力 x1 および x2 をもつ関数として Rosenbrock 関数を定義します。

type rosenbrock2.m
function [y,dydx1,dydx2] = rosenbrock2(x1,x2)

y = 100*(x2 - x1.^2).^2 + (1 - x1).^2;
[dydx1,dydx2] = dlgradient(y,x1,x2);

end

入力 –1 および 2 を表す 2 つの dlarray 引数を指定して dlfeval を呼び出し、rosenbrock2 を評価します。

x1 = dlarray(-1);
x2 = dlarray(2);
[fval,dydx1,dydx2] = dlfeval(@rosenbrock2,x1,x2)
fval = 
  1x1 dlarray

   104

dydx1 = 
  1x1 dlarray

   396

dydx2 = 
  1x1 dlarray

   200

単位正方形内のいくつかの点について、Rosenbrock 関数の勾配をプロットします。まず、関数の評価点と出力を表す配列を初期化します。

[X1 X2] = meshgrid(linspace(0,1,10));
X1 = dlarray(X1(:));
X2 = dlarray(X2(:));
Y = dlarray(zeros(size(X1)));
DYDX1 = Y;
DYDX2 = Y;

ループ内で関数を評価します。quiver を使用して結果をプロットします。

for i = 1:length(X1)
    [Y(i),DYDX1(i),DYDX2(i)] = dlfeval(@rosenbrock2,X1(i),X2(i));
end
quiver(extractdata(X1),extractdata(X2),extractdata(DYDX1),extractdata(DYDX2))
xlabel('x1')
ylabel('x2')

Figure contains an axes object. The axes object contains an object of type quiver.

dlgradient および dlfeval を使用して、複素数を含む関数の値と勾配を計算します。複素勾配を計算することも、勾配を実数のみに限定することもできます。

この例の最後にリストされている関数 complexFun を定義します。この関数は、以下の複素式を実装します。

f(x)=(2+3i)x

この例の最後にリストされている関数 gradFun を定義します。この関数は、complexFun を呼び出し、dlgradient を使用して入力に対する結果の勾配を計算します。自動微分の場合、微分する値 (入力に基づいて計算される関数の値) は実数のスカラーでなければなりません。そのため、この関数は、勾配を計算する前に結果の実数部の合計を取ります。この関数は、関数値の実数部と勾配を返します。勾配は複素数となる場合があります。

範囲が -2 ~ 2 および -2i ~ 2i である複素平面上のサンプル点を定義し、dlarray に変換します。

functionRes = linspace(-2,2,100);
x = functionRes + 1i*functionRes.';
x = dlarray(x);

各サンプル点について、関数値と勾配を計算します。

[y, grad] = dlfeval(@gradFun,x);
y = extractdata(y);

勾配を表示するサンプル点を定義します。

gradientRes = linspace(-2,2,11);
xGrad = gradientRes + 1i*gradientRes.';

これらのサンプル点の勾配値を抽出します。

[~,gradPlot] = dlfeval(@gradFun,dlarray(xGrad));
gradPlot = extractdata(gradPlot);

結果をプロットします。imagesc を使用して、複素平面上に関数の値を表示します。quiver を使用して、勾配の向きと大きさを表示します。

imagesc([-2,2],[-2,2],y);
axis xy
colorbar
hold on
quiver(real(xGrad),imag(xGrad),real(gradPlot),imag(gradPlot),"k");
xlabel("Real")
ylabel("Imaginary")
title("Real Value and Gradient","Re$(f(x)) = $ Re$((2+3i)x)$","interpreter","latex")

この関数の勾配は、複素平面全体で同じになっています。自動微分によって計算された勾配の値を抽出します。

grad(1,1)
ans = 
  1×1 dlarray

   2.0000 - 3.0000i

検証すると、この関数の複素微分は次の値となることがわかります。

df(x)dx=2+3i

ただし、関数 Re(f(x)) は解析的ではないため、複素微分は定義されません。MATLAB の自動微分の場合、微分する値は常に実数でなければならないため、複素解析関数を使用することはできません。代わりに、このプロットで示されているように、返された勾配が最急上昇方向を向くように微分が計算されます。これは、関数 Re(f(x)):C R を関数 Re(f(xR+ixI)):R × R R と解釈することで実現されます。

function y = complexFun(x)
    y = (2+3i)*x;    
end

function [y,grad] = gradFun(x)
    y = complexFun(x);
    y = real(y);

    grad = dlgradient(sum(y,"all"),x);
end

入力引数

すべて折りたたむ

評価対象の関数。関数ハンドルとして指定します。fundlgradient 呼び出しが含まれている場合、dlfeval は、自動微分を使用して勾配を評価します。この勾配の評価では、dlgradient 呼び出しの各引数は、dlarray であるか、dlarray を含む cell 配列、構造体、table でなければなりません。dlfeval の入力引数の数は、fun の入力引数の数と同じでなければなりません。

例: @rosenbrock

データ型: function_handle

関数の引数。任意の MATLAB データ型、または dlnetwork オブジェクトとして指定します。

dlgradient 呼び出しにおける微分変数である入力引数 xj は、トレースされた dlarray であるか、トレースされた dlarray を含む cell 配列、構造体、table でなければなりません。ハイパーパラメーターや定数データ配列などの追加の変数が dlarray である必要はありません。

深層学習の勾配を評価するため、関数の引数として dlnetwork オブジェクトを与え、fun 内にあるネットワークのフォワード パスを評価することができます。

例: dlarray([1 2;3 4])

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | table | cell | function_handle | categorical | datetime | duration | calendarDuration | fi
複素数のサポート: あり

出力引数

すべて折りたたむ

関数の出力。任意のデータ型として返されます。dlgradient 呼び出しによって出力が得られた場合、出力は dlarray になります。

ヒント

  • dlgradient は関数の内部で呼び出さなければなりません。勾配の数値を取得するには、dlfeval を使用して関数を評価しなければなりません。また、関数の引数は dlarray でなければなりません。Deep Learning Toolbox での自動微分の使用を参照してください。

  • 勾配を正しく評価するため、関数 fun には dlarray をサポートしている関数のみを使用しなければなりません。dlarray をサポートする関数の一覧を参照してください。

拡張機能

バージョン履歴

R2019b で導入