見出し画像

ML.NETで機械学習②-画像で転移学習-

こんにちは。
「ML.NETで機械学習①」に引き続き、C#で機械学習を扱うライブラリ「ML.NET」を使ってAIの学習を進めていきたいと思います。

転移学習

今回は、画像の転移学習を行ってみたいと思います。
簡単に転移学習とは何かについて説明します。
画像分類でよく使われるCNNは畳込み層で画像の特徴を学習しますが、入力層に近い層は画像全体の抽象的な概念を学習するのに対して、出力層に近い層ではその画像を特徴づけるより具体的な概念について学習します(下記、参考:https://www.sbbit.jp/article/cont1/33345)。

画像1

したがって、入力層に近い層は予め多様な画像ですでに学習させたネットワーク(学習済みモデル)を利用して、出力層に近い層のみを学習させたいラベルに置きなおして学習させるといった手法を使うことがあり、この手法のことを転移学習といいます。

転移学習は一から学習させるよりも学習効率がよく、学習にかける時間を短縮できるといったメリットもあるので、画像分類においてよく使われる手法となっています。

転移学習の実装

ここでは、下記サンプルプログラムを参考に実装していきます。

自分のプロジェクトに「ML.NET」をインストールする場合は、NuGetパッケージから「Micorosoft.ML」というパッケージをインストールしてください。
また、合わせて「Microsoft.ML.Vision」、「SciSharp.TensorFlow.Redist」と「Microsoft.ML.ImageAnalytics」をインストールします。

学習を行うデータセットは下記になります。

このサイトにはひび割れあり/ひび割れなしのコンクリート構造物の画像データセットがあります。
その中から、橋床のデータセットを使用します。

基本的には、上記のサンプルプログラムをコピペすれば簡単に実行できますが、変更することが多い箇所のみ解説します。
トレーニングのパイプラインを定義するために、ImageClassificationTrainerを用いて学習時のオプションを定義します。

var classifierOptions = new ImageClassificationTrainer.Options()
{
   FeatureColumnName = "Image",
   LabelColumnName = "LabelAsKey",
   ValidationSet = validationSet,
   Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
   MetricsCallback = (metrics) => Console.WriteLine(metrics),
   TestOnTrainSet = false,
   ReuseTrainSetBottleneckCachedValues = true,
   ReuseValidationSetBottleneckCachedValues = true,
   WorkspacePath=workspaceRelativePath
};

サンプルでは、学習済みモデルのアーキテクチャとしてResnetV2の101レイヤーが使用されています。
他のアーキテクチャに変更したい場合は、ImageClassificationTrainer.Architectureの設定を変更します。
この記事を書いている現在で、使用することのできるアーキテクチャの種類は以下の通りです。

・ResnetV2 101レイヤー
・InceptionV3
・MobilenetV2
・ResnetV2 50レイヤー

また、ImageClassificationTrainerのオプションの中でバッチサイズやエポック数、学習率を設定することができます。

var classifierOptions = new ImageClassificationTrainer.Options()
{
   FeatureColumnName = "Image",
   LabelColumnName = "LabelAsKey",
   ValidationSet = validationSet,
   Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
   MetricsCallback = (metrics) => Console.WriteLine(metrics),
   TestOnTrainSet = false,
   ReuseTrainSetBottleneckCachedValues = true,
   ReuseValidationSetBottleneckCachedValues = true,
   WorkspacePath=workspaceRelativePath,

   // バッチサイズの設定
   BatchSize = 32,
   // エポック数の設定
   Epoch = 60,
  // 学習率の設定
   LearningRate = (float)0.001
};

実際に、学習してみるとコンソール画面に学習経過が出力されます。
僕のPCではCPUを使用して学習を開始してから1~2分くらいで学習が完了します。感覚的にもかなり早い印象でした。転移学習とはいえ、この早さで学習を行えるのであれば、簡単な初期評価としてもかなり使えそうな気がします。

コンソール画面

また、何度か学習を行っていると、エポック数を60回に設定しているのに、40回程度で学習が勝手に終了してしまうことがありました。
これは「Early Stopping」といって、学習精度が想定よりも早期に安定したときに、設定したエポック数分学習を行っていなくても、学習を自動的に終了してくれる機能です。
この機能も学習効率を上げてくれる便器な機能の一つです。

まとめ

「ML.NET」を使うことで、画像の転移学習を簡単に行うことができました。基本的にはトレーニングパイプラインのオプションを自分の解きたいタスクに合わせて設定してやるだけで、他はサンプルプログラムと同じプログラムで動かすことができます。
今度は、学習の設定や検証結果の確認をより簡単にするために自分なりのUIを開発していこうかと思います。

この記事が気に入ったらサポートをしてみませんか?