Main Content

機械学習モデルの予測を MATLAB Coder アプリを使用して行うコードの生成

この例では、分類および回帰モデル オブジェクトの予測を行うための C/C++ コードを MATLAB® Coder™ アプリを使用して生成する方法を示します。codegen (MATLAB Coder) を使用してコマンド ラインでコードを生成することもできます。詳細については、機械学習モデルの予測をコマンド ラインで行うコードの生成を参照してください。

一部の分類および回帰モデル オブジェクトには、コード生成をサポートする関数 predict または random があります。これらのオブジェクト関数を使用する予測には学習済みの分類または回帰モデル オブジェクトが必要ですが、コード生成用のエントリポイント関数の入力変数ではこれらのオブジェクトを使用できません。この例で説明されているように saveLearnerForCoderloadLearnerForCoder を使用して、この制限に対処します。

次のフロー チャートは、分類および回帰モデル オブジェクトのオブジェクト関数に対するコード生成ワークフローを示します。

この例では、k 最近傍弱学習器を使用してアンサンブル分類モデルに学習をさせ、saveLearnerForCoder を使用して学習済みモデルを保存します。次に、loadLearnerForCoder を使用して保存済みモデルを読み込んでオブジェクト関数を呼び出す、エントリポイント関数を定義します。エントリポイント関数をテストするスクリプトを作成します。最後に、MATLAB Coder アプリを使用してコードを生成し、生成されたコードを確認します。

分類モデルの学習

ionosphere データ セットを読み込みます。このデータ セットには、レーダー反射についての 34 個の予測子と、不良 ('b') または良好 ('g') という 351 個の二項反応が含まれています。

load ionosphere

ランダム部分空間法を使用して、k 最近傍弱学習器でアンサンブル分類モデルに学習をさせます。ランダム部分空間アンサンブルを使用する分類の詳細については、ランダム部分空間の分類を参照してください。

rng('default')  % For reproducibility
learner = templateKNN('NumNeighbors',2);
Mdl = fitcensemble(X,Y,'Method','Subspace','NPredToSample',5, ...
    'Learners',learner,'NumLearningCycles',13);

saveLearnerForCoder の使用によるモデルの保存

学習済みのアンサンブル モデルを現在のフォルダーの knnEnsemble.mat という名前のファイルに保存します。

saveLearnerForCoder(Mdl,'knnEnsemble')

saveLearnerForCoder は、完全な分類モデル Mdl をコンパクトにしてから、現在の作業フォルダー内の MATLAB バイナリ ファイル knnEnsemble.mat に構造体配列として保存します。

エントリポイント関数の定義

"エントリポイント" 関数は、コード生成用に定義する関数で、"最上位" 関数または "プライマリ" 関数とも呼ばれます。コード生成に対応する関数を呼び出すエントリポイント関数を定義し、エントリポイント関数から C/C++ コードを生成しなければなりません。エントリポイント関数内のすべての関数がコード生成をサポートしなければなりません。

現在のフォルダー内の新しいファイルで、以下を行う myknnEnsemblePredict という名前のエントリポイント関数を定義します。

  • 入力データ (X)、保存したモデルのファイル名 (fileName)、および関数 predict の有効な名前と値のペアの引数 (varargin) を受け入れる。

  • loadLearnerForCoder を使用して、学習済みアンサンブル モデルを読み込む。

  • 読み込んだモデルからラベルおよび対応するスコアを予測する。

入力引数として varargin を指定することにより、オプションの名前と値のペアの引数に対応できます。詳細については、可変長引数リストのコード生成 (MATLAB Coder)を参照してください。

type myknnEnsemblePredict.m % Display the contents of myknnEnsemblePredict.m file. 
function [label,score] = myknnEnsemblePredict(X,fileName,varargin) %#codegen
CompactMdl = loadLearnerForCoder(fileName);
[label,score] = predict(CompactMdl,X,varargin{:});
end

MATLAB のアルゴリズムについてのコードを生成しようとしていることを指示するため、コンパイラ命令 %#codegen (またはプラグマ) をエントリポイント関数のシグネチャの後に追加します。この命令を追加すると、MATLAB Code Analyzer はコード生成時にエラーになる違反の診断と修正を支援します。コード アナライザーによるコードのチェック (MATLAB Coder)を参照してください。

メモ: このページの右上にあるボタンをクリックしてこの例を MATLAB で開くと、MATLAB で例のフォルダーが開きます。このフォルダーには、エントリポイント関数ファイル (myknnEnsemblePredict.m) とテスト ファイル (test_myknnEnsemblePredict.m、後述) が含まれています。

コンパイラの設定

C/C++ コードを生成するには、適切に設定されている C/C++ コンパイラにアクセスできなければなりません。MATLAB Coder は、サポートされているインストール済みのコンパイラを探して使用します。mex -setup を使用すると、既定のコンパイラを表示および変更できます。詳細は、既定のコンパイラの変更を参照してください。

テスト ファイルの作成

関数 myknnEnsemblePredict を呼び出すテスト スクリプトを作成します。テスト スクリプトでは、生成したコードで使用する入力引数および名前と値のペアの引数を指定します。MATLAB Coder アプリを使用してコードを生成するときに、このテスト スクリプトを使用して入力の型を自動的に定義します。

この例では、次のように test_myknnEnsemblePredict.m というファイルを現在のフォルダーに作成します。

type test_myknnEnsemblePredict.m % Display the contents of test_myknnEnsemblePredict.m file. 
%% Load Sample data
load ionosphere

%% Test myknnEnsemblePredict
[label,score] = myknnEnsemblePredict(X,'knnEnsemble','Learners',1:13);

詳細については、アプリを使用した入力の型の自動定義 (MATLAB Coder)を参照してください。

MATLAB Coder アプリの使用によるコードの生成

MATLAB Coder アプリは、MATLAB コードから C または C++ コードを生成します。ワークフローに基づくユーザー インターフェイスにより、コード生成プロセスを進めることができます。以下の手順では、MATLAB Coder アプリのワークフローについて簡単に説明します。詳細については、MATLAB Coder (MATLAB Coder)およびMATLAB Coder アプリを使用した C コードの生成 (MATLAB Coder)を参照してください。

1.MATLAB Coder アプリを開いてエントリポイント関数ファイルを選択します。

[アプリ] タブの [アプリ] セクションで [さらに表示] 矢印をクリックして、アプリ ギャラリーを開きます。[コード生成][MATLAB Coder] をクリックします。[ソース ファイルの選択] ページが開きます。エントリポイント関数 myknnEnsemblePredict の名前を入力または選択します。

[次へ] をクリックして [入力の型を定義] ページに進みます。

2.入力の型を定義する

C では静的なデータ型が使用されるので、MATLAB Coder は MATLAB ファイル内のすべての変数のプロパティをコンパイル時に決定しなければなりません。このため、エントリポイント関数の入力のプロパティを指定する必要があります。

テスト スクリプト test_myknnEnsemblePredict を入力または選択し、[入力の型の自動定義] をクリックします。

MATLAB Coder アプリは、テスト スクリプトに基づいて関数 myknnEnsemblePredict の入力の型を認識します。

入力の型を変更します。

  • X — アプリは入力 Xdouble(351x34) であると推定します。学習済みモデルの予測子の個数と同じになるように予測子の個数を修正しなければなりません。ただし、予測用の観測値は異なる個数にすることができます。観測値の個数が不明である場合は、double(351x34)double(:351x34) または double(:infx34) に変更します。double(:351x34) に設定すると 351 個までの観測値が可能になり、double(:infx34) に設定すると観測値の個数に制限がなくなります。この例では、351 をクリックして :inf を選択することにより、double(:infx34) を指定します。

  • fileNamechar をクリックし、[定数の定義] を選択して、一重引用符を付けたファイル名 'knnEnsemble' を入力します。

  • varargin{1} — 名前と値のペアの引数に含まれる名前はコンパイル時の定数でなければなりません。char をクリックし、[定数の定義] を選択して、'Learners' を入力します。

  • varargin{2} — 生成されたコードで 13 個の弱学習器に対応するユーザー定義インデックスを指定できるようにするため、double(1x13)double(1x:13) に変更します。

[次へ] をクリックして [実行時の問題の確認] ページに進みます。このオプションの手順では、MEX ファイルが生成され、MEX 関数が実行され、問題が報告されます。[次へ] をクリックして [コード生成] ページに進みます。

3.C コードを生成する

[ビルド タイプ] を MEX に設定して [生成] をクリックします。MEX 関数 myknnEnsemblePredict_mex が生成されます。MEX 関数は、MATLAB から実行できる C/C++ プログラムです。MEX 関数を使用すると、MATLAB のアルゴリズムを高速化し、生成されたコードの機能と実行時の問題をテストすることができます。詳細は、MATLAB アルゴリズムの高速化 (MATLAB Coder)MATLAB で MEX 関数をテストする理由 (MATLAB Coder) を参照してください。

MATLAB Coder は、指定されたビルド タイプに基づいて、コンパイルするとスタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能ファイルになる MEX 関数またはスタンドアロン C/C++ コードを生成します。ビルド タイプの設定の詳細については、ビルド設定の構成 (MATLAB Coder)を参照してください。

[次へ] をクリックして [ワークフローの完了] ページに進みます。

4.[ワークフローの完了] ページを確認する

[ワークフローの完了] ページに、コード生成が成功したことが示されます。このページは、プロジェクトの概要と生成された出力へのリンクも提供します。

スクリプトの使用によるコードの生成

入力の型を定義した後で、MATLAB Coder プロジェクトを等価な MATLAB コマンドのスクリプトに変換できます。その後、スクリプトを実行してコードを生成します。詳細については、MATLAB スクリプトへの MATLAB Coder プロジェクトの変換 (MATLAB Coder)を参照してください。

MATLAB Coder アプリのツール バーで、[アクション メニューを開きます] ボタン をクリックします。

[スクリプトに変換] を選択してから [保存] をクリックします。myknnEnsemblePredict_script.m というファイルが作成されます。このファイルは、構成オブジェクト内のプロジェクトを再現し、関数 codegen (MATLAB Coder) を実行します。

myknnEnsemblePredict_script.m ファイルの内容を表示します。

type myknnEnsemblePredict_script.m
% MYKNNENSEMBLEPREDICT_SCRIPT   Generate MEX-function myknnEnsemblePredict_mex
%  from myknnEnsemblePredict.
% 
% Script generated from project 'myknnEnsemblePredict.prj' on 17-Nov-2017.
% 
% See also CODER, CODER.CONFIG, CODER.TYPEOF, CODEGEN.

%% Create configuration object of class 'coder.MexCodeConfig'.
cfg = coder.config('mex');
cfg.GenerateReport = true;
cfg.ReportPotentialDifferences = false;

%% Define argument types for entry-point 'myknnEnsemblePredict'.
ARGS = cell(1,1);
ARGS{1} = cell(4,1);
ARGS{1}{1} = coder.typeof(0,[Inf  34],[1 0]);
ARGS{1}{2} = coder.Constant('knnEnsemble');
ARGS{1}{3} = coder.Constant('Learners');
ARGS{1}{4} = coder.typeof(0,[1 13],[0 1]);

%% Invoke MATLAB Coder.
codegen -config cfg myknnEnsemblePredict -args ARGS{1} -nargout 2

スクリプトを実行します。

myknnEnsemblePredict_script
Code generation successful: To view the report, open('codegen/mex/myknnEnsemblePredict/html/report.mldatx')

生成されたコードの確認

MEX 関数をテストして、生成されたコードが元の MATLAB コードと同じ機能を提供するかどうかを確認します。このテストを実行するため、元の MATLAB コードの実行に使用したものと同じ入力を使用して MEX 関数を実行してから、結果を比較します。スタンドアロン コードを生成する前に MATLAB で MEX 関数を実行すると、実行時エラーを検出して修正することもできます。生成されたスタンドアロン コードでは、このようなエラーの診断がはるかに困難になります。詳細は、MATLAB で MEX 関数をテストする理由 (MATLAB Coder)を参照してください。

予測子データを渡して、myknnEnsemblePredict と MEX 関数が同じ結果を返すかどうかを確認します。

[label1,score1] = predict(Mdl,X,'Learners',1:10);
[label2,score2] = myknnEnsemblePredict(X,'knnEnsemble','Learners',1:10);
[label3,score3] = myknnEnsemblePredict_mex(X,'knnEnsemble','Learners',1:10);

isequal を使用して、label1label2 および label3 を比較します。

isequal(label1,label2,label3)
ans = logical
   1

isequal は、すべての入力が等しいことを意味する logical 1 (true) を返します。

関数 predict からの出力と比較すると、MEX 関数からの出力 score3 には丸めによる差が含まれている場合があります。このような場合は、小さい誤差を許容して score1score3 を比較します。

find(abs(score1-score3) > 1e-12)
ans =

  0x1 empty double column vector

score1score3 の要素ごとの差の絶対値が指定された許容誤差 1e-12 を超えない場合、find は空のベクトルを返します。この比較により、同じ結果を myknnEnsemblePredict と MEX 関数が返すことを確認します。

参考

(MATLAB Coder) | | |

関連するトピック