2020年1月1日水曜日

C#で画像認識(Accord.Net) 2.最小構成のプログラム作成

前回からの続きです。
Accord.Netを使用して、画像認識させる最低限の構成について記載します。
私自身が初心者で機械学習はサッパリなので、誤認識あったらゴメンナサイ

Accord.Netについては、以下の記事も参考にしてください。
C#で画像認識(Accord.Net) 

1.機械学習に必要なもの

私の認識では画像認識処理の登場人物は以下です
  • BagOfWords
  • VectorMachine
  • 画像のリスト
  • 入力値のリスト
  • 分類結果のリスト
  • 判定したい画像

BagOfWords
画像のリストを読み込んで解析可能なデータに変換します。
BagOfWordsによる変換結果の一覧が入力値のリストです。

分類結果のリスト
画像のリストの分類の一覧です。
分類とはユーザが決めるもので、

  • 赤い画像(0)、青い画像(1)、黄色い画像(2)
  • 人物(0)、風景(1)

などのように分類して、括弧のように数値を割り振ったリストです。

VectorMachine
機械学習のコアになるクラスです。
入力値のリストと分類結果のリストを読み込んで学習を行います。
その後、判定したい画像を読み込むことで、どの分類に属しているか判定します。
学習にはTeacherを定義します

2.処理の流れ

実際に処理をまとめると以下のようになります。
サンプルでは

  • リンゴ、伊勢海老バナナ青空」の画像を読み込み
  • 赤色黄色青色」に分類
  • イチゴ」の画像を読み込み「」グループと判別させる

イメージです。


private void Study()
{
 // データ変換の配列の長さ
 const int CodeWordCount = 60;

 //データ解析のアルゴリズム
 BinarySplit binarySplit = new BinarySplit(CodeWordCount); 
 BagOfVisualWords bagofVW = new BagOfVisualWords(binarySplit);

 List<bitmap> bmps = new List<bitmap>();
 List<double> inputs = new List<double>();
 List<int> outputs = new List<int>();

 // 学習用画像の読み込み
 bmps.Add(new Bitmap("リンゴの画像のパス")); // 赤色の画像
 bmps.Add(new Bitmap("伊勢海老の画像のパス")); // 赤色の画像
 bmps.Add(new Bitmap("バナナの画像のパス")); // 黄色の画像
 bmps.Add(new Bitmap("青空の画像のパス")); // 青色の画像

 // BagOfWordsでデータ変換
 bagofVW.Learn(bmps.ToArray());
 foreach (var bmp in bmps)
 {
  var wordCount = bagofVW.Transform(bmp);
  inputs.Add(wordCount);
 }

 // 読み込んだ画像の分類
 outputs.Add(0); // 赤色の画像
 outputs.Add(0); // 赤色の画像
 outputs.Add(1); // 黄色の画像
 outputs.Add(2); // 青色の画像

 // 赤、青、黄の3分割
 var classes = 3;

 // 機械学習の実施
 var msvm = new MulticlassSupportVectorMachine<chisquare>(0, new ChiSquare(), classes);

 var teacher = new MulticlassSupportVectorLearning<chisquare>(msvm)
 {
  Learner = (param) => new SequentialMinimalOptimization<chisquare>()
  {
   UseComplexityHeuristic = true,
   UseKernelEstimation = true
  }
 };
 msvm = teacher.Learn(inputs.ToArray(), outputs.ToArray());


 // 画像の判定
 Bitmap targetBmp = new Bitmap("イチゴの画像のパス");

 var codeword = bagofVW.Transform(targetBmp);

 // イチゴは赤いので「0」が返却されるはず
 var ret = msvm.Decide(codeword);

}