この記事は、インテルの The Parallel Universe Magazine 26 号に収録されている、インテル® DAAL による手書き数字認識向け C++ コードの作成例に関する章を抜粋翻訳したものです。
インテル® Data Analytics Acceleration Library (インテル® DAAL) は、インテル® プラットフォーム上でのデータ解析とマシンラーニング向けに最適化されたビルディング・ブロックを提供する、データ解析用のパフォーマンス・ライブラリーです。インテル® DAAL に含まれる関数は、マシンラーニングのすべてのデータ処理段階 (前処理、変換、解析、モデリングから意思決定まで) をカバーします。各処理段階向けに、インテル® Atom™ プロセッサー、インテル® Core™ プロセッサー、インテル® Xeon® プロセッサー、インテル® Xeon Phi™ プロセッサーを含むインテル® アーキテクチャー向けに最適化された関数とユーティリティーが用意されています。インテル® DAAL は、3 つの処理モード (バッチ、オンライン、分散) と 3 つのプログラミング API (C++、Java*、Python*) をサポートします。
ここでは、インテル® DAAL の手書き数字認識アプリケーションの C++ コード例について見ていきます。手書き数字認識は、典型的なマシンラーニングの問題の 1 つで、いくつかのアプリケーション・アルゴリズムに関連があります。サポート・ベクトル・マシン (SVM)、主成分分析 (PCA)、ナイーブベイズ、ニューラル・ネットワークはすべて、この問題への対応に使用されますが、予測の精度が異なります。インテル® DAAL には、これらのアルゴリズムのほとんどが含まれています。ここでは、SVM を使用して、手書き数字認識にインテル® DAAL のアルゴリズムを導入する方法を示します。
インテル® DAAL でのデータのロード
手書き数字認識において、認識は基本的にマシンラーニング・パイプラインの予測/推論段階に当たります。提供された手書き数字から、システムが数字を認識または推論できなければなりません。システムが入力から出力を予測/推論できるように、トレーニング・データセットから学習したトレーニング済みモデルが必要になります。トレーニング・モデルを作成する前のステップとして、最初にトレーニング・データを収集します。
サンプル・アプリケーションでは、UCI Machine Learning Repository (英語) で公開されている 3,823 件の前処理済みトレーニング・データと 1,797 件の前処理済みテストデータを使用します。インテル® DAAL は、いくつかのデータ形式 (CSV、SQL、HDFS、KDB+) とユーザー定義のデータ形式をサポートしています。ここでは、CSV 形式を使用します。トレーニング・データは digits_tra.csv
ファイルに、テストデータは digits_tes.csv
に保存されると仮定します。
インテル® DAAL には、データソースからメモリーへデータをロードするためのいくつかのユーティリティーがあります。ここでは、最初に trainDataSource
オブジェクトを定義します。これは、CSV ファイルからメモリーへデータをロードすることができる CSVFeatureManager
です。インテル® DAAL の内部では、メモリーにあるデータは数値テーブルとして保持されます。CSVFeatureManager
を利用すると、自動的に数値テーブルが作成されます。CSV ファイルからデータをロードするには、メンバー関数 loadDataBlock()
を呼び出します。これで、データが数値テーブルとしてメモリーにロードされ、後続の処理を行うことができます。CSV ファイルからトレーニング・データをロードする C++ コードの重要な部分を図 1 に示します。
/* 入力データセットのパラメーター */ string trainDatasetFileName = "digits_tra.csv"; string testDatasetFileName = "digits_tes.csv"; /* FileDataSource<CSVFeatureManager> を初期化して .csv ファイルから入力データを取得 */ FileDataSource<CSVFeatureManager> trainDataSource(trainDatasetFileName, DataSource::doAllocateNumericTable, DataSource::doDictionaryFromContext); /* データファイルからデータをロード */ trainDataSource.loadDataBlock(nTrainObservations);
1. トレーニング・データをロードする C++ コード
SVM ベースの手書き数字認識モデルのトレーニング
トレーニング・データがメモリーにロードされたら、そのデータを学習して、トレーニング・モデルを作成します。ここでは、トレーニング・データセットが小さく、データを一度にメモリーに収めることができるため、トレーニング用のアルゴリズムとして、SVM を使用します。処理には、バッチ処理モードを使用します。アルゴリズムを定義後、クラスの数 (この例では 10) などのアルゴリズムに必要な関連パラメーターを設定します。そして、トレーニング・データの数値テーブル trainDataSource.getNumericTable()
をアルゴリズムに渡します。
algorithm.compute()
を呼び出すと、SVM の計算が開始され、しばらくするとトレーニングが完了します。トレーニング済みモデルは、trainingResult
オブジェクトに格納され、algorithm.getResult()
を呼び出して取得できます。図 2 にトレーニング・プロセスのサンプルコードを示します。
services::SharedPtr<svm::training::Batch<> > training(new svm::training::Batch<>()); /* 多クラス SVM トレーニング用のアルゴリズム・オブジェクトを作成 */ multi_class_classifier::training::Batch<> algorithm; algorithm.parameter.nClasses = nClasses; algorithm.parameter.training = training; /* トレーニング・データセットと関連する値をアルゴリズムに渡す */ algorithm.input.set(classifier::training::data, trainDataSource.getNumericTable()); /* 多クラス SVM モデルを作成 */ algorithm.compute(); /* アルゴリズムの結果を取得 */ trainingResult = algorithm.getResult(); /* 学習したモデルをディスクファイルへシリアル化 */ ModelFileWriter writer("./model"); writer.serializeToFile(trainingResult->get(classifier::training::model));
2. トレーニング・プロセスのサンプルコード
インテル® DAAL は、トレーニング済みモデルをメモリーからファイルへ出力するシリアル化関数と、トレーニング済みモデルファイルをメモリーにロードする逆シリアル化関数を提供します。図 2 の最後の 2 行のように、model
という名前のファイルに書き込む ModelFileWriter
を定義します。writer.serializeToFile()
を呼び出して、trainingResult
に格納されているトレーニング済みモデルを model
ファイルに書き込みます。このシリアル化/逆シリアル化ユーティリティーは、トレーニング後、サーバーがトレーニング済みモデルをクライアントへ移植し、クライアントがトレーニングを行わずにそれを使用して予測/推論を行う場合に役立ちます。model
ファイルの利用法については、「手書き数字認識アプリケーション」セクションで説明します。