
この記事は、インテルの 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 ファイルの利用法については、「手書き数字認識アプリケーション」セクションで説明します。

