このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
メトリクス関数を使用した深層学習実験の評価
この例では、メトリクス関数を使用して実験の結果を評価する方法を説明します。既定では、組み込みの学習実験を実行すると、実験マネージャーによって、実験における各試行の損失、精度 (分類実験の場合)、および平方根平均二乗誤差 (回帰実験の場合) が計算されます。その他の尺度を計算するには、独自のメトリクス関数を作成します。たとえば、メトリクス関数を定義して次を行うことができます。
学習済みネットワークの予測性能をテスト。
最終エポックにおける検証損失の勾配を計算することによって学習の進行状況を評価。
試行ごとに異なるネットワーク アーキテクチャを使用する実験で使用されるネットワークのサイズを表示。
各試行の学習が完了すると、実験マネージャーによってメトリクス関数が評価され、その値が結果テーブルに表示されます。
この例では、手書きの数字のイメージを分類するようネットワークに学習させます。2 つのメトリクス関数により、学習済みネットワークが 1 と 7 の数字のイメージをどの程度適切に識別するかを判定します。実験マネージャーを使用してイメージ分類用ネットワークに学習させる詳細については、ハイパーパラメーターのスイープによるイメージ分類を参照してください。
メトリクス関数の定義
メトリクス関数を組み込みの学習実験に追加します。
[実験] ペインの [メトリクス] で、[追加] をクリックします。
[メトリクスの追加] ダイアログ ボックスで、メトリクス関数の名前を入力して [OK] をクリックします。既にプロジェクトに存在する関数の名前を入力した場合、実験マネージャーによってその関数が実験に追加されます。そうでない場合は、既定のテンプレートによって定義された関数が実験マネージャーによって作成されます。
メトリクス関数の名前を選択して [編集] をクリックします。MATLAB® エディターでメトリクス関数が開きます。
メトリクス関数への入力は、以下の 3 つのフィールドをもつ構造体です。
trainedNetwork
は、関数trainNetwork
によって返されるSeriesNetwork
オブジェクトまたはDAGNetwork
オブジェクトです。詳細については、netを参照してください。trainingInfo
は、関数trainNetwork
によって返される学習情報を含む構造体です。詳細については、infoを参照してください。parameters
は、ハイパーパラメーター テーブルのフィールドをもつ構造体です。
カスタム メトリクス関数の出力は、スカラー数、logical 値、または string でなければなりません。
実験を開く
まず、例を開きます。実験マネージャーによって、検証と実行が可能な事前構成済みの実験を含むプロジェクトが読み込まれます。実験を開くには、[実験ブラウザー] ペインで、実験の名前 (ClassificationExperiment
) をダブルクリックします。
組み込みの学習実験は、説明、ハイパーパラメーターのテーブル、セットアップ関数、および実験の結果を評価するためのメトリクス関数の集合で構成されます。詳細については、組み込み学習実験の構成を参照してください。
[説明] フィールドには、実験を説明するテキストが表示されます。この例の説明は次のようになります。
Classification of digits, evaluating results by using metric functions: * OnesAsSevens returns the percentage of 1s misclassified as 7s. * SevensAsOnes returns the percentage of 7s misclassified as 1s.
[ハイパーパラメーター] セクションでは、実験で使用する手法 (Exhaustive Sweep
) とハイパーパラメーター値を指定します。実験を実行すると、実験マネージャーは、ハイパーパラメーター テーブルで指定されたハイパーパラメーター値のすべての組み合わせを使用してネットワークに学習させます。この例は、ハイパーパラメーター InitialLearnRate
および Momentum
を使用します。
[セットアップ関数] は、実験用の学習データ、ネットワーク アーキテクチャ、および学習オプションを構成します。セットアップ関数への入力は、ハイパーパラメーター テーブルのフィールドをもつ構造体です。このセットアップ関数は、イメージ分類問題用のネットワークに学習させるために使用する 3 つの出力を返します。この例では、セットアップ関数には 3 つのセクションがあります。
学習データの読み込みでは、学習データと検証データを含むイメージ データストアを定義します。この例では、数字データセットからイメージを読み込みます。このデータセットの詳細については、イメージ データセットを参照してください。
digitDatasetPath = fullfile(toolboxdir("nnet"), ... "nndemos","nndatasets","DigitDataset"); imdsTrain = imageDatastore(digitDatasetPath, ... IncludeSubfolders=true, ... LabelSource="foldernames");
numTrainingFiles = 750; [imdsTrain,imdsValidation] = splitEachLabel(imdsTrain,numTrainingFiles);
ネットワーク アーキテクチャの定義では、深層学習による分類用の畳み込みニューラル ネットワークのアーキテクチャを定義します。この例では、セットアップ関数テンプレートによって指定された既定の分類用ネットワークを使用します。
inputSize = [28 28 1]; numClasses = 10; layers = [ imageInputLayer(inputSize) convolution2dLayer(5,20) batchNormalizationLayer reluLayer fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
"学習オプションの指定" では、実験用の
trainingOptions
オブジェクトを定義します。この例では、ハイパーパラメーター テーブルから学習オプションInitialLearnRate
とMomentum
の値を読み込みます。
options = trainingOptions("sgdm", ... MaxEpochs=5, ... ValidationData=imdsValidation, ... ValidationFrequency=30, ... InitialLearnRate=params.InitialLearnRate, ... Momentum=params.Momentum, ... Verbose=false);
セットアップ関数を検査するには、[セットアップ関数] で [編集] をクリックします。MATLAB® エディターでセットアップ関数が開きます。また、セットアップ関数のコードは、この例の最後の付録 1 にあります。
[メトリクス] セクションは、実験結果を評価するオプションの関数を指定します。ネットワークの学習が完了するたびに、実験マネージャーによってこれらの関数が評価されます。メトリクス関数を検査するには、メトリクス関数の名前を選択して [編集] をクリックします。MATLAB エディターでメトリクス関数が開きます。
この例には 2 つのメトリクス関数が含まれています。
OnesAsSevens
は、学習済みネットワークが数字 1 のイメージを 7 に誤分類した割合を返します。SevensAsOnes
は、学習済みネットワークが数字 7 のイメージを 1 に誤分類した割合を返します。
これらの関数はそれぞれ、学習済みネットワークを使用して数字データセット全体を分類します。その後、これらの関数は、実際のラベルと予測されたラベルが一致しないイメージの数を判定します。たとえば、関数 OnesAsSevens
は、実際のラベルが "1"
で、予測されたラベルが "7"
であるイメージの数を計算します。同様に、関数 SevensAsOnes
は、実際のラベルが "7"
で、予測されたラベルが "1"
であるイメージの数を計算します。これらのメトリクス関数のコードは、この例の最後の付録 2 と付録 3 にあります。
実験の実行
実験を実行すると、実験マネージャーはセットアップ関数で定義されたネットワークに 6 回学習させます。試行ごとに、ハイパーパラメーター値の異なる組み合わせが使用されます。既定では、実験マネージャーは一度に 1 つの試行を実行します。Parallel Computing Toolbox™ を使用している場合は、複数の試行を同時に実行したり、クラスター内のバッチ ジョブとして実験をオフロードしたりできます。
一度に 1 つの実験を実行するには、"実験マネージャー" ツールストリップの [モード] で
[Sequential]
を選択し、[実行] をクリックします。複数の試行を同時に実行するには、[モード] で
[Simultaneous]
を選択し、[実行] をクリックします。現在の並列プールがない場合、実験マネージャーは既定のクラスター プロファイルを使用して並列プールを起動します。その後、実験マネージャーは、並列プールにあるワーカーと同じ数の同時試行を実行します。最良の結果を得るには、実験を実行する前に、GPU と同じ数のワーカーで並列プールを起動します。詳細については、実験マネージャーを使用したネットワークの並列学習とGPU 計算の要件 (Parallel Computing Toolbox)を参照してください。実験をバッチ ジョブとしてオフロードするには、[モード] で
[Batch Sequential]
または[Batch Simultaneous]
を選択し、[クラスター] と [Pool Size] を指定して、[実行] をクリックします。詳細については、Offload Experiments as Batch Jobs to Clusterを参照してください。
結果テーブルに、各試行のメトリクス関数の値が表示されます。
結果の評価
実験で得られた最良の結果を見つけるには、結果テーブルを並べ替えます。たとえば、1 の誤分類の回数が最も小さい試行を見つけるには次のようにします。
[OnesAsSevens] 列をポイントします。
三角形のアイコンをクリックします。
[昇順に並べ替え] を選択します。
同様に、7 の誤分類の回数が最も小さい試行を見つけるには、[SevensAsOnes] 列のドロップダウン メニューを開いて [昇順に並べ替え] を選択します。
両方の値が最小となる試行が 1 つもない場合は、両方のメトリクスに対する順位が良い試行を選択してください。たとえば、結果テーブルをtable
配列として MATLAB ワークスペースにエクスポートし、試行ごとに 2 つのメトリクス値の平均を計算します。
[実験マネージャー] ツールストリップで、[エクスポート]、[結果テーブル] をクリックします。
ダイアログ ウィンドウで、エクスポートしたテーブルのワークスペース変数の名前を入力します。既定の名前は
resultsTable
です。エクスポートしたネットワークを関数
averageMetrics
(この例の最後の付録 4 に掲載) への入力として使用します。たとえば、MATLAB コマンド ウィンドウで次のように入力します。
averageMetrics(resultsTable);
この関数は、メトリクスの平均値が最も低かった試行に関するメトリクス情報の概要を表示します。
******************************************
Best trial: 4 Ones misclassified as sevens: 1.3000% (Ranking: 3) Sevens misclassified as ones: 1.2000% (Ranking: 1) Average of metric values: 1.2500%
******************************************
実験結果に関する観測結果を記録するには、注釈を追加します。
結果テーブルで、最適な結果が得られた試行の [OnesAsSevens] セルを右クリックします。
[注釈の追加] を選択します。
[注釈] ペインで、テキスト ボックスに観測結果を入力します。
[SevensAsOnes] セルについても上記の手順を繰り返します。
詳細については、実験結果の並べ替え、フィルター処理、および注釈追加を参照してください。
実験を閉じる
[実験ブラウザー] ペインでプロジェクトの名前を右クリックし、[プロジェクトを閉じる] を選択します。実験マネージャーによって、プロジェクトに含まれるすべての実験と結果が閉じられます。
付録 1: セットアップ関数
この関数は、実験用の学習データ、ネットワーク アーキテクチャ、および学習オプションを構成します。
入力
params
は、実験マネージャーのハイパーパラメーター テーブルのフィールドをもつ構造体です。
出力
imdsTrain
は、学習データ用のイメージ データストアです。layers
は、ニューラル ネットワーク アーキテクチャを定義する層グラフです。options
はtrainingOptions
オブジェクトです。
function [imdsTrain,layers,options] = ClassificationExperiment_setup1(params) digitDatasetPath = fullfile(toolboxdir("nnet"), ... "nndemos","nndatasets","DigitDataset"); imdsTrain = imageDatastore(digitDatasetPath, ... IncludeSubfolders=true, ... LabelSource="foldernames"); numTrainingFiles = 750; [imdsTrain,imdsValidation] = splitEachLabel(imdsTrain,numTrainingFiles); inputSize = [28 28 1]; numClasses = 10; layers = [ imageInputLayer(inputSize) convolution2dLayer(5,20) batchNormalizationLayer reluLayer fullyConnectedLayer(numClasses) softmaxLayer classificationLayer]; options = trainingOptions("sgdm", ... MaxEpochs=5, ... ValidationData=imdsValidation, ... ValidationFrequency=30, ... InitialLearnRate=params.InitialLearnRate, ... Momentum=params.Momentum, ... Verbose=false); end
付録 2: 7 として誤分類された 1 の検索
この関数は、7 として誤分類された 1 の個数を判別します。
function metricOutput = OnesAsSevens(trialInfo) actualValue = "1"; predValue = "7"; net = trialInfo.trainedNetwork; digitDatasetPath = fullfile(toolboxdir("nnet"), ... "nndemos","nndatasets","DigitDataset"); imds = imageDatastore(digitDatasetPath, ... IncludeSubfolders=true, ... LabelSource="foldernames"); YActual = imds.Labels; YPred = classify(net,imds); K = sum(YActual == actualValue & YPred == predValue); N = sum(YActual == actualValue); metricOutput = 100*K/N; end
付録 3: 1 として誤分類された 7 の検索
この関数は、1 として誤分類された 7 の個数を判別します。
function metricOutput = SevensAsOnes(trialInfo) actualValue = "7"; predValue = "1"; net = trialInfo.trainedNetwork; digitDatasetPath = fullfile(toolboxdir("nnet"), ... "nndemos","nndatasets","DigitDataset"); imds = imageDatastore(digitDatasetPath, ... IncludeSubfolders=true, ... LabelSource="foldernames"); YActual = imds.Labels; YPred = classify(net,imds); K = sum(YActual == actualValue & YPred == predValue); N = sum(YActual == actualValue); metricOutput = 100*K/N; end
付録 4: メトリクス平均値の計算
この関数は、結果テーブルからメトリクス値を抽出します。その後、この関数は、メトリクス平均値および各メトリクスの順位を結果テーブルに追加し、最適な結果が得られた試行に関するメトリクス情報の概要を表示します。
function results = averageMetrics(results) Metric1 = results.Metrics.OnesAsSevens; Metric2 = results.Metrics.SevensAsOnes; MetricAverage = (Metric1+Metric2)/2; results = [results table(MetricAverage,Metric1,Metric2)]; N = height(results); results = sortrows(results,"Metric1"); OnesAsSevensRanking = (1:N)'; results = [results table(OnesAsSevensRanking)]; results = sortrows(results,"Metric2"); SevensAsOnesRanking = (1:N)'; results = [results table(SevensAsOnesRanking)]; results = sortrows(results,"MetricAverage"); results = removevars(results,["Metric1","Metric2"]); fprintf("\n******************************************\n\n"); fprintf("Best trial: %d\n",results.Trial(1)); fprintf("Ones misclassified as sevens: %.4f%% (Ranking: %d)\n", ... results.Metrics.OnesAsSevens(1),results.OnesAsSevensRanking(1)); fprintf("Sevens misclassified as ones: %.4f%% (Ranking: %d)\n", ... results.Metrics.SevensAsOnes(1),results.SevensAsOnesRanking(1)); fprintf("Average of metric values: %.4f%%\n", ... results.MetricAverage(1)); fprintf("\n******************************************\n\n"); end