Unityでディープラーニング学習用の教師データを大量に生成する方法
AIは教師データの収集とアノテーションが大変
こんにちは、AIやってますか!?(唐突な問いかけ)
AIの中でも、ディープラーニングの画像認識といえば、大変なのは教師データを集めることとアノテーションですね。
数千枚の画像に対して、例えばルールを変えてアノテーションのやり直しとか、セマンティックセグメンテーションのアノテーションとか地獄ですよね(想像です)。
なんとかこの教師データの収集とアノテーションを自動化するのが人類の夢なのではないかと思います。ただ、これは卵が先か鶏が先かの話なのでとても難しいです。今回は、Unityを使って、この教師データ生成をなんとか自動化できないかというトライアルになります。
既に先行事例に加えて、Unityさんが丁寧なチュートリアルを出していますので、今回はそれに沿って実践していく形になります。
ブログにも記事を書いていますので、よろしければこちらも合わせて参照ください。教師データの生成に関しては、この記事で完結しているので、時間が無い方はこの記事だけ読んでもらえば大丈夫です。
Unityの教師データ生成のためのチュートリアル
perceptionというモジュールを使います。
セットアップ方法及びチュートリアルは、以下の公式サイトがとても参考になります。
英語ですが、丁寧ですしスクリーンショットもあるので、勘と気合で頑張れば最後までたどり着けると思います。操作だけでなく、操作する理由も説明があるので親切です。操作する箇所は、わかりやすくActionと記載あるので、一度説明読みながら実践して流れを理解すれば、2回目以降はActionだけ追っていけば設定できるようになると思います。
チュートリアルは、Step1とStep2の2つに別れています。Step1がセットアップとRandomizationの設定方法です。Randomizationは、教師データの水増し(Data Augmentatin)に相当する作業と理解すれば良いと思います。Data Augmentationに関しては、本記事の最後に過去に書いた参考記事のリンクを貼っておきます。
Step2は、Randomizationをコードを使ってカスタムする方法に関して実施する内容になっています。
この記事では、試したことと、その結果、わずかなハマりどころをステップごとに順に説明していきます。基本的には個人的なメモレベルです(丁寧な日本語訳などはなくすみません、自動翻訳活用ください)。
Step1
Unity Hubを起動して、新しいプロジェクトを作成します。「Universal Render Pipeline」を選ぶ必要があるので注意してください。
Unityのバージョンは、Macの2020.2.7f1とLinuxの2020.3.19f1で試しました。
プロジェクトが起動したら、Perceptionモジュールをインストールします。「Window」 → 「Package Manager」 左上の「+」をクリックして「Add Package from git URL…」を選択。出てくるアドレスバーにcom.unity.perception
を入力して、インストールされたらOKです。
インポートした後、Perceptionモジュールを使ってタグ付けしたオブジェクトを表示します。
カメラでみると、いい感じにBounding Boxとピクセルレベルでの色塗りされた様子が表示されます。
ランダムな背景を配置した図です。
背景を更にリアルにします。
設定して実行すると、上記のような大量の画像と合わせて、アノテーション情報を格納したjsonファイルも一緒に保存されます。
アノテーション情報が問題ないか、確認と分析をJupyter Notebookで行います。
環境としてDockerイメージが提供されています。Apple Silicon Macでもちゃんと動きました。
Docker起動時、データのファイルパスを指定する必要がありますが、絶対パスを指定する必要があるので注意しましょう。エスケープ文字にも注意です(少しはまりました)。
Step2
はまったとろは、途中のAction: Add MyLightRandomizer to the list of Randomizers in SimulationScenario.
のところで、自分はここでリストに出てこず選択できませんでした。
なので、手順を変えて先に Action: Open MyLightRandomizerTag.cs and replace its contents with the code below:
のところを実施して MyLightRandomizerTag.cs
を作成して、エラーを解消したところ、選択できるようになりました。
これで、例えば光の強さのパラメータを振って画像データを取得することができます。
少しわかりにくいですが、以下2つの画像で明るさが異なるのが分かると思います。
その他、色々なパラメータを同じ要領で振って画像を取得することができます。これでStep2は完了です。
Step3は、Unityのクラウドサービスの話なので省略します。これで、ローカルのPCを使った教師データの取得方法を一通り理解できました。
取得したデータを、実際に学習に使うには、jsonファイルを使ってまたひと手間加工が必要になりますが、この処理は学習に使うソフトによって変わるので、省略します。
jsonファイルの加工に関しては、Step1の最後で分析に使ったJupyter Notebookを参考にすれば良いのではないかと思います。
サイコロのデータ生成と分類と学習
チュートリアルを終えたので少し違うことを試してみます。以下のようなサイコロの教師データを取得できるようなパッケージがあるので、これを使ってサイコロの出た目の画像の教師データ生成から学習までチャレンジしてみます。
ただ、上記のパッケージは、バージョンの違いなのか色々エラーがあってそのままでは動かなかったので修正したものを以下のリポジトリにアップしました。今回はこちらを使います。
サイコロのデータ生成
パッケージはDiceExperiment.unitypackageを右クリックしてダウンロードします。
Unity Hubを起動して、新しいプロジェクトを作成します。チュートリアルと同様「Universal Render Pipeline」を選ぶ必要があるので注意してください。
Unityが起動したら、本記事のStep1と同様に「Perception」モジュールをインストールしておきます。
続いて、Projectのタブを、右クリックして出てくるメニューで「Import Package」 → 「Custom Package…」をクリックして「DiceExperiment.unitypackage」を選択して、インポートします。
インポート後は、ScenesでDiceExperiment.unity
を選択します。
この状態でUnityを実行すると、以下のようなたくさんのサイコロ画像が生成されます。
サイコロの色を替えたいときは、Assets > MaterialsのDice, Dipsの色を変えましょう(ランダムに変更するのは、スクリプトのエラーが出てうまく出来ていません。誰か助けてください)。
サイコロを回転させたいときは、Rotationの値を調整します。0〜360度と思います。実際のサイコロを考えるとY軸方向は0〜360度設定したほうが良いでしょう。X,Yはカメラの取り付け角度次第ですが、少し値に幅あると取り付け位置に対してロバストになるかもしれません。
新しいパターンのデータを生成したい場合は、Hierarchy
のSimulationSceinario
のInspectorのDice Placement Randomizer
のRandom Seedの値とTotal Iterationsの値を変えれば、いくらでも画像を生成できます。
サイコロのデータ分類
学習するために、ラベル(サイコロの目)に応じてフォルダに分類しましょう。画像の目を確認して、自力でフォルダごとに分類するなどしてもよいですが、jsonファイルにラベルとファイル情報があるので、スクリプトを使ってサイコロの目ごとにフォルダを分類すると楽です。
スクリプトはdata_categorize.pyという名前で作成してリポジトリにアップしてあります。
スクリプトを使うためには、画像フォルダの保存場所に移動します。Hierarchy
> Main Camera
を選択してInspectorのPerception Camera
のLatest Output FolderのShow Folderをクリックすれば移動できます。
生成した画像と画像の情報を格納したファイルは、それぞれRGBxxxxxx
, Datasetxxxxxx
というフォルダに格納されています(xxxxx
はランダムに生成された文字列になります)。
data_categorize.py
というファイルを以下の構成で配置して、実行すればtarget
というフォルダの中に、画像が分類されて保存されます。
.
├── Datasetaxxxxx
├── Logs
├── RGBxxxxx
├── data_categorize.py
コマンドとしては、上記のフォルダのトップフォルダで以下コマンド実行すれば、スクリプトをダウンロードして実行できます。
$ curl -O https://raw.githubusercontent.com/karaage0703/DiceExperiment/main/data_categorize.py
$ python3 data_categorize.py
データ学習
分類した画像を教師データとして学習させれば、実際のサイコロ画像の判別できそうですね。学習は、以下のGoogle Colabのノートブックを使って実践しました。
ノートブックの詳細は、本記事の主題ではないので省略します。詳しく知りたい人は、宣伝になりますが「からあげ先生のとにかく楽しいAI自作教室」というAIの初心者向けの書籍をおすすめいたします。Google Colaboratoryを使って、実際に動かしながらAIを学べる本になっています。よろしければご購入検討ください。以下、書籍の紹介記事へのリンクです。
変更した点
以下はChristianWiele/DiceExperimentから修正した点のメモです。
「Assets」の「Settings」から「ForwardRenderer.asset」を選択して、Inspectorメニューの「Renderer Features」で「New Ground Truth Renderer Feature」を選択します。
インポートしたScripts/Perception
のコードが、そのままだとエラーになるので。冒頭のusing UnityEngine.Experimental.Perception.xxx
となっている箇所をusing UnityEngine.Perception.xxx
とExperimental.
を削除することでエラーを解消しました。
ラベル設定はデフォルトで問題ありませんでした。
Main Camera
は、Camera Labelers
をすべて削除してBoundingBox2DLabeler
を追加してId Label Config
にDiceIdLabelConfig
を設定します。
SimulationScenario
は自分の環境だと、インポートしたとき壊れてしまっていたので削除して作り直しました。
SimulationSceinario
の設定は、チュートリアルと同じ要領で設定します。
Fixed Length Scenario
を追加します。設定はデフォルトでOKです。
Background Randomizers
の設定は飛ばします(設定しません)。
Foreground Randomizers
の設定は、Foreground Randomizers
の代わりに、 Dice Placement Randomizer
を選択します。そのままではサイコロが小さくなり過ぎるので、Dice ScaleのRangeのMinを 0 > 0.5に変更しました。
背景をランダマイズするためにColorRandomizer
を追加しています。設定はデフォルトのままです。
まとめ
Unityで教師データを生成する方法を紹介しました。最初、サイコロのデータ生成するリポジトリを見つけたときは「これで楽勝じゃん!」と狂喜乱舞したのですが、エラーの連続で全く動かすことができませんでした。
結局Unityとperceptionモジュールの使い方を、ほぼ1から理解して、ようやく動かすことができました。なかなか大変でした…おかげでUnityとPerceptionモジュールと少し仲良くなれたような気がします(多分)。
作った教師データの活用例に関しては、今後紹介していきたいと思います。
宣伝「からあげ先生のとにかく楽しいAI自作教室」
AIの初心者向け本「からあげ先生のとにかく楽しいAI自作教室」を執筆しました。Google Colaboratoryを使って、実際に動かしながらAIを学べる本になっています。
この記事で生成した教師データの学習や、学習したモデルを使った画像認識に関してこの本で学ぶことができます。よろしければ是非。以下、本の紹介記事へのリンクです。
関連記事
Data Augmentation
ディープラーニング関係
参考リンク
Unity公式
サイコロのデータセット
変更履歴
- 2021/05/02 画像分類のスクリプトに関して追記
- 2021/05/01 微修正
Discussion