post Image
Windows PCかつオフライン環境でお気軽に画像認識する

TL;DR

Windows, つよいGPUがない, インターネットに画像をアップできない, アドミン権限がないなどの環境でも動作する、転移学習を利用した画像認識アプリを .NET Framework (Windows Forms) で作成しました。

アプリケーションをダウンロードし、分類したい名前を付けたフォルダに数枚ずつ画像を用意するだけで短時間で簡単に学習ができます。Pythonなどをインストールする必要もありません。色々なものを分類して最近の画像認識の精度を体感してみてください。

アプリケーションは、Microsoft がオープンソースで開発を進めているML.NET (ML.NET単体では Linux, Macなどでも動きます) を利用しています。実装されている TensorFlow API を利用して、学習済みの Inception モデルを読み込み、画像特徴を抽出し、Stochastic Dual Coordinate Ascent(SDCA) を利用した多クラス分類器用いて転移学習をします。

アプリケーションの利用方法

  1. アプリをダウンロードして展開し、ImageClassificationApp0.9.0\ImageClassificationApp.exe を起動します。
  2. 画像を学習するには、[学習する] のボタンをクリックし、開いたダイアログから画像を分類済みのフォルダ(下図の場合は SampleImages フォルダ)を選択してOKをクリックします。
    image
  3. 30秒から1分程度で学習が完了します。image下図のように表示されたら画像を Drag & Drop すると認識結果と確信度(0~1, 1が最も高い)が表示されます。 image
  4. あらかじめ学習したモデルを利用することも可能です。先ほど画像を学習したフォルダにimageClassifier.zipというファイルが生成されていますので、それを読み込んでみてください。学習済みモデルのファイル名は適宜変更可能です。また学習に利用した画像も不要です。image

.NET 開発者向けの解説

ML.NET とは

ML.NET は Microsoft がオープンソースで進めている .NET 開発者向け機械学習フレームワークです。クロスプラットフォームで開発されており、Windows, Linux, macOS で動作します。Windows Hello, Bing Ads PowerPoint デザインアイディアなどでも使われています。
類似のものとして、Windows Machine Learning がありますが、こちらは Windows 10 以降の OS に特化したものとなります。API等に互換性はありません。

ML.NET を Windows Forms から利用する

ML.NET はクロスプラットフォームを実現するため .NET Core で作成されています。.NET Core で作成した DLL は、.NET Framework で作成しているアプリケーションからは直接参照することはできませんが、.NET Standard ライブラリにすることで .NET Framework から参照できるようになります。なお、今回は .NET Core 2.0 を利用しているため、.NET Standard 2.0 / .NET Framework 4.6.1 以降が必要です。

  1. .NET Standard 2.0 のクラスライブラリのプロジェクトを作成し、nuget を利用して、必要なライブラリ(今回は、Microsoft.ML, Microsoft.ML.ImageAnalytics, Microsoft.ML.TensorFlow のいずれも 0.7.0)を追加する
    image
    image
  2. 1.のプロジェクトを .NET Framework のプロジェクトから参照する
  3. .NET Framework のプロジェクトの .csproj を開き、<RestoreProjectStyle>PackageReference</RestoreProjectStyle> を最初の <PropertyGroup> 内の先頭に追加する
    image
  4. x64でビルドする

下記のようなメッセージが出てデバッグ実行に失敗する場合は、10秒くらい待ってもう一度実行してください。

The OutputPath property is not set for project ‘CoreReferenceForm.csproj’. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration=’Debug’ Platform=’x64′. This error may also appear if some other project is trying to follow a project-to-project reference to this project, this project has been unloaded or is not included in the solution, and the referencing project does not build using the same or an equivalent Configuration or Platform. CoreReferenceForm

参考

実装について

ML.NETのサンプルにある Image Classification をベースにしています。以下は説明のため部分的に抜粋しています。詳しくは ソースコードを参照してください。

学習

ML.NET では下記のようにパイプラインを構成していきます。

var pipeline = mlContext.Transforms.Categorical.MapValueToKey("Label", "LabelTokey")
                .Append(new ImageLoadingEstimator(mlContext, imagesFolder, ("ImagePath", "ImageReal")))
                .Append(new ImageResizingEstimator(mlContext, "ImageReal", "ImageReal", ImageNetSettings.imageHeight, ImageNetSettings.imageWidth))
                .Append(new ImagePixelExtractingEstimator(mlContext, new[] { new ImagePixelExtractorTransform.ColumnInfo("ImageReal", "input", interleave: ImageNetSettings.channelsLast, offset: ImageNetSettings.mean) }))
                .Append(new TensorFlowEstimator(mlContext, featurizerModelLocation, new[] { "input" }, new[] { "softmax2_pre_activation" }))
                .Append(new SdcaMultiClassTrainer(mlContext, "softmax2_pre_activation", "LabelTokey"))
                .Append(new KeyToValueEstimator(mlContext, ("PredictedLabel", "PredictedLabelValu")));

上記のコードでは

  • 画像ファイルとその画像のラベル(クラス名; 日本語 (UTF-8) が利用可能)が記載された.tsvファイル読み込み
  • 画像のリサイズ
  • ディープラーニング向けの形式へのデータ変換
  • ディープラーニングを利用した画像特徴の抽出
  • Stochastic Dual Coordinate Ascent(SDCA) を利用した画像特徴の多クラス分類

といったような各処理をつないでいます。パイプラインの構成は、画像に限らず、自然言語処理や数値(CSVファイル)データの学習でも同様です。詳しくは、ML.NETのチュートリアルサンプルコードを参照してください。

パイプラインができたら、そこに学習データを渡して学習を行います。

var data = loader.Read(new MultiFileSource(dataLocation));
var model = pipeline.Fit(data);

つづいて、できたモデルを評価します。

var sdcaContext = new MulticlassClassificationContext(env);
ConsoleWriteHeader("Classification metrics");
var metrics = sdcaContext.Evaluate(trainData, label: "LabelTokey", predictedLabel: "PredictedLabel");
Console.WriteLine($"LogLoss is: {metrics.LogLoss}");
Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");

モデルの保存も簡単です。

 using (var f = new FileStream(outputModelLocation, FileMode.Create)){
    model.SaveTo(env, f);
 }

推論

推論はモデルを読み込んで、画像ファイルを渡すだけです。作成したモデルにはラベル(クラス名)も含まれています。

// モデル読み込み
using (var f = new FileStream(modelLocation, FileMode.Open))
{
    loadedModel = TransformerChain.LoadFrom(env, f);
}
var predictor = loadedModel.MakePredictionFunction<ImageNetData, ImageNetPrediction>(env);

// 画像読み込み
var testData = ImageNetData.ReadImage(filename,"---");
ImageNetPrediction data=  predictor.Predict(testData);

return data.PredictedLabelValue + " " + data.Score.Max();

『 機械学習 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。