Translate

2019年9月10日火曜日

Donkeycar3.1.0上の機械学習モデルを調べてみた


Donkeycar がVersion3になり、実装されているモデルのタイプ(DEFAULT_MODEL_TYPE)が増えた。

しかし、どのモデルが何者なのか、ドキュメントには一切書かれていない。

デフォルトで動作するlinear以外はどうなっているのか、
そもそも既存のTubデータで動作するのかといった情報がないのだ。

結局 donkeycar パッケージリポジトリを自分で読むしか無いのだ。

<2019/09/11追記>
Facebook側にコメントが有り、公式ドキュメントにも
記載があるそうです。よく読めって話ですよね..
http://docs.donkeycar.com/parts/keras/
まずこちら(Google Chromeの翻訳かけても十分読めます)を
参照していただいたほうがいいでしょう。

と、いうことでざっと読んで概要をまとめてみた。

ちなみにdonkeycarのモデルの呼び出しはFactoryパターンで実装されていて、
myconfig.py上にDEFAULT_MODEL_TYPEを指定すると、
(デフォルトはconfig.py上のDEFAULT_MODEL_TYPE="linear"が有効になる)
Abstract Factory関数はutil.pyのget_model_by_typeの引数にわたり
該当するモデルパーツクラスがインスタンス化される仕組みだ。

Donkeycar3.1.0には以下のモデルタイプ(引数model_type)が存在する。


model_typeクラス概要
lineardonkeycar.parts.keras.KerasLineardonkeycarデフォルトのモデル。中間層は、Conv2D×5層。出力層でステアリング値、スロットル値を直接出力。
tflite_lineardonkeycar.parts.tflite.TFLitePilotTensorFlow Lite モデルファイルをロードして実行するためのパーツクラス。トレーニングを実行するための`compile`メソッドが実装されていないのでモデル作成およびトレーニングはdonkeycarアプリケーション外で各自で作成・実行しなくてはならない。linearで作成したモデルファイルをコンバートするなどして使用する(h5ファイルのコンバート処理はkeras_model_to_tfliteメソッドが提供されている)。使用可能なモデルは、入力はイメージ(120x160x3)、出力はアングル値・ステアリング値(ともにfloat値)が前提となる。
localizerdonkeycar.parts.KerasLocalizerほぼcategoricalのモデルと同じだが、出力層がスロットル、アングルにロケーション分類値が加わっている。ロケーション分類値は、LED表示に使用されるのみなので、自動運転動作には全く影響しない。LEDを搭載していない標準DonkeyCarの場合はcategoricalを指定した場合と何ら変わらない。 しかしTubデータにロケーション分類値を格納する処理が実装されていないので、学習処理が動かないかもしれない。
behaviordonkeycar.parts.keras.KerasBehavioral入力層がイメージと車線状態を取り込むモデル。車線状態(左車線・右車線のどちらか)をL1キーでトグル入力させそれをone hotな動作ベクトルに変換し、イメージと一緒に入力層に与えている。入力層以外はイメージ側は`categorical`と同様、状態ベクトル側は全結合層×3、最後に両方の結果を連結している。ソースコードコメントを読むと昔はlinearベースだったようだ。ジョイスティックがない場合、あってもL1というラベルが使用しているJoystickクラスに定義されていない場合はこのモデルを選択しても意味がない。しかも手動運転時の運転者が走行操作と並行してただしく状態を入力しなければならない。
imudonkeycar.parts.keras.KerasIMUMPU6050(I2C)から角速度3軸、加速度3軸がTubデータに書かれていることが前提。入力層はイメージとIMU値、中間層はイメージがConv×5層・IMUが全結×3層を結合したもの、出力層でステアリング値、スロットル値を直接出力。
tensorrt_lineardonkeycar.parts.tensorrt.TensorRTLinearTensorRTを使ったクラス、このためTelsa/Jetson/Nvidia Driveがない場合は使用できない(GeForceも実行できない)。`compile`メソッドは存在するが処理が実装されていないため、学習済みモデルをロードし推論するのみの機能提供となるコンバート方法は公式ドキュメントを参照のこと。なお、コードのコメントにtesnorflow-gpuでのトレーニングは非推奨との記述がある(なぜかは不明)。
coral_tflite_lineardonkeycar.parts.coral.CoralLinearPilotEdgeTPU搭載した環境を前提としたクラス。Tensorflow Liteモデルファイルを読み込み、推論を実行するのみ。モデルファイルは別途作成する必要がある。コンバート方法は..知っている人はコメント欄にお願いします..
3ddonkeycar.parts.keras.Keras3D_CNN畳み込み層を時系列データを扱うためConv2DではなくConv3Dを使ったモデル。直近一定数(デフォルトは20)のイメージを入力し、Conv3D×4層の中間層にかけ、アングル値・スロットル値を出力する(分類ではなくfloat値で返却)。
rnndonkeycar.parts.keras.KerasRNN_LSTM時系列データが扱えるRNN/LSTMをベースとしたモデル。直近一定件数(デフォルトは3)のイメージを入力し、各イメージにConvolution2D×5層にかけ各々をベクトル化したものを作成しLSTM(RNN実装の一つ)にかけ、出力層はアングル値、スロットル値を出力する(分類ではなくfloat値で返却)。
categoricaldonkeycar.parts.keras.KerasCategorical画像分類を使ったモデル。入力層はイメージ、中間層はイメージサイズによりConv2D×4or5層、出力層はスロットル15分割、アングル20分割の各1値を選定する。CNNの画像分類精度の高さを使っているためlinearより精度が高いという人もいる。細やかな動作を行いたい場合は出力層の分割数を増やせば良い。
latentdonkeycar.parts.keras.KerasLatentConv2D×8層を中間層に持つモデル。入力はイメージ、出力はアングル値・スロットル値(ともにfloat値を直接出力)以外にCNNを掛けた直後Deconvolution(Transposed Convolution/up-convolutionともいうDC-GANによく使用される)層を6層かけてイメージも生成している。しかし出力ではアングル値・スロットル値のみを使っているだけで生成したイメージは`KerasLatent`クラス内で捨てているため、そのまま使用する場合は、単にCNN8層のモデルでしかない。
fastaidonkeycar.parts.fastai.FastAiPilotfastaiパッケージのモデルファイルを読み込み実行するための推論のみのパーツクラス。クラス上にcompileメソッドがなくpython manage.py trainを実行できない(donkeycarアプリケーションを使ったトレーニングができない)。よってモデルはdonkeycarアプリケーション外部で定義されていることが前提となる。fastaiパッケージがtoachパッケージベースで記述されているためtensorflowベースではない。なおfastaiパッケージはディープラーニングのeラーニングコースである course.fast.ai 内で使用されている。

標準Donkeycarで有効に動作しそうなモデルタイプは
  • linear
  • categorical
  • rnn
  • 3d
の4種類。
ただ..rnnと3dは複数のイメージデータ(rnnはデフォルト3件、3dはデフォルト10件)
を入力にしないといけないが、
manage.py上のVehicle上のメモリ領域に最近N件のイメージデータを
確保するような処理がない..
なのでまともに動作するのは
  • linear
  • categorical
の2つだけだ。

<2019/09/11修正>
rnn、3dのrun関数内で最近N件をインスタンス変数にためて
いる実装がありました。推論も実行できそうです。
コメントご指摘、ありがとうございました。

linearでうまく行かない人はcategoricalでうまくいくことが多い。
これはCNNが画像分類で世に出たわけでもともと得意なケース
ということなのだとおもう。



  • behavior
は、ゲームパッドでの手動運転(学習データ収集)が必須となっており、
かつゲームパッド上に(joystick具現クラス上に)ラベル"L1"が定義されていること
が前提となり、
手動運転中Donkeycarが車線を変更するたびにL1ボタンを押さなくてはならない。
behaviorモードで手動運転したTubデータは項目が増えるが、
そのまま先の4つのモードでもトレーニングさせることができる(拡張項目は無視されるが、ファイルロードに時間がかかる)。
ゲームパッドとしてPS3/PS4をつかっているならこのまま動作すると思うが
F710とかだとmanage.pyの1行を書き換える(L1をLTなどに書き換える)必要がある
(厄介なことにmyconfig.pyではなくmanage.py上に直書きされているのだ)。


また
  • imu
は、MPU6050をI2C経由で接続しておかなくてはならず、
Tubデータも増える。
MPU6050は日本のAmazonでも購入可能だ。
IMUデータはCNNではなく全結合層の結果をCNNの結果と
コンカチしているだけなので
素人目にも精度が悪そうだ。
角速度と加速度なので、
機械学習の入力として使用するのではなく、
ルールベースの剰余項補正などに使用したほうが良いとおもう。


  • localizer 
はよくわからない実装だ。
3色LEDを搭載しているDonkeycarでないと意味がないし、
そもそもどう点灯してほしいかの学習データ入力方法がないので
学習は無法地帯になっている。
コードを読む上でなにか見落としがあるのかもしれない。
3色LEDの想定はKY-009という基板実装モジュールで
日本のAmazonにもあるにはあるが品切れ状態で
国内で入手するのは難しそうである。
3色LED自体は販売されているので、
ブレッドボード上でカソード側の抵抗を見繕えば
自前基板実装の難易度は高くない。
(..Donkeycarを菅原文太が乗っていたデコトラみたいにしたかったのかもしれない..)

よくわからない実装といえば
  • latent
もそうだ。
DC-GANで使用されているDeconvolution層を使って画像データを生成
させているが、3.1.0ではつくりっぱなしで、
Tubやメモリ上に格納していない、使用していないのだ。
想像するに、学習データを増やそうとしているのだろうが、
もしかしたら後続バージョンでなにかかわるのかもしれない。
入力・出力ともデフォルトのTubデータで操作しそうだから
このモデルも動くとは思うが、deconv結果を使用しない以上
単なるCNN8層モデルでしかないため、
トレーニングや自動運転処理が重いだけでおわるかもしれない。


以下の4つのモデル
  • tflite_linear
  • coral_tflite_linear
  • tensorrt_linear
  • fastai
は、クラス上にモデルファイルのロードと自動運転実行機能しか
実装されていない。
fastai以外はlinearとついているのでlinearモデルのTF Lite/TF Lite TPU版/TensorRT
実装(モデル定義、トレーニング処理)があってもいいとおもうのだけど
みあたらない..

ただ
  • tflite_linear
  • coral_tflite_linear
は、デフォルトのlinearで学習したモデルファイルをコンバートするだけ
で使用できそうだ。coralはUSB接続するGoogle Coralアクセラレータ
(旧Mobidius)かEdge TPU実装ボード(Google Coral Dev Board JP Version)が
ないと動作しない。
  • tensorrt_linear
は、Tesla(Google ColabでもOK)、Jetson、NVIDIA Driveシリーズでのみ
動作する。
TeslaをDonkeycarに乗せるのはコストが見合わないし、
NVIDIA Driveはトヨタとかホンダとか本気で自律走行を載せようとしている
メーカ向けらしいので無理。
ほぼJetson Nano向けということになる。
持っていないので詳しくないが、Jetson Nano上のTensorflow は
バックエンドでTensorRTを使うようになっているのだと思う
(モデルファイルはどう作るのかは不明)

<2019/09/11追記>
tensorrt_linearのモデルファイルの作り方は公式ドキュメント
http://docs.donkeycar.com/guide/robot_sbc/tensorrt_jetson_nano/
に記載されています。
コメントご指摘、ありがとうございました。



p.s.

ちなみにdonkey makemovie --tub <tubデータディレクトリパス> --type < model_type値 > --out < 出力mp4ファイルパス >--salient --start 1 --end <画像にしたいtubデータ通し番号(最後)>を実行することで、
モデルがexciteした箇所を可視化してくれる。
さらにモデルが推論した値も可視化してくれるので
ぜひためしてほしい。

..のだけど、処理はとても重い。
linear で start=1 end=2400を指定して
仮想マシン2コア8GBRAM(FloydHub cpu)で動かしたら
8時間たったころにメモリが足りなくて落ちた..
しかも生成したmp4は途中で切れている状態で
再生できなかった..

以下、FloydHub実行例。
#Tubデータはデータセットとして先に格納済みで
#モデルファイルmodels/20190910/mypilot_linear.h5も作成済みが前提。
#Tawn氏のkeras-visだと動かなかったので1行だけ修正した版を独自リポジトリ
#に格納している

floyd run --cpu --env tensorflow-1.13 --data user_id/datasets/dataset_name/1:data 'git clone https://github.com/autorope/donkeycar.git&&cd donkeycar&&git checkout master&&cd ..&&pip install -e donkeycar[pc]&&pip install keras-vis&&git clone https://github.com/coolerking/keras-vis&&pip install -e keras-vis&&donkey createcar --path mycar&&cd mycar&&donkey makemovie --tub /floyd/input/data --out linear.mp4 --type linear --model ../models/20190910/mypilot_linear.h5 --start 1 --end 2400 --salient'



Google Colaboratory (Python3/GPU)で
linear で start=1 end=2400を指定して実行すると
5時間23分かかって1分の動画を生成した..
ただ..実はGoogle Colabratoryの90分問題・120分問題というのがあり、
(モデルファイル作成のトレーニング処理は長くても20分なので問題ない)
手動で対処していたためほとんど他の作業ができなかった..
この記事に書いてあるChromeプラグインを入れたのだが、
#ダイアログが出て自動更新されなかった

タダだから、文句言えないけど..

p.s.2

ちなみにrnnや3dモデルでdonkey makemovieすると大量のエラーがでた。
generatorやrunの入力が複数件対応していないためだ。

<2019/09/11追記>
エラーの原因はrnnと3dで異なっているので、もう少し掘り起こしてみます..

p.s.3

tensorflow liteはRaspberry Pi Zero上では
トレーニングだけでなく推論実行できない。
armv6ベースのwheelファイルがPyPIにないので
自分でwheelファイルがつくれないと、
すなわちソースコードからwheelファイルを
Raspberry Pi Zero上もしくはDockerコンテナなどのクロスコンパイル環境上で
ビルドできないと、
使用できない。

あるいはTawn氏が作ったtflite_serverというOSSで
クラサバ形態をとるかだが、
これだと"自律"走行とは言えないかもしれない..

2 件のコメント:

inachi さんのコメント...

「tflite_linear, coral_tflite_linear は、デフォルトのlinearで学習したモデルファイルをコンバートするだけで使用できそうだ」とありますが、そのとおりで、donkeycar/templates/train.py にコンバートのコードが入っています。つまり python manage.py train で学習可能です。tensorrt_linear について linear で学習したモデルファイルのコンバートは自動で行われませんが http://docs.donkeycar.com/guide/robot_sbc/tensorrt_jetson_nano/ に手順が載っています。

実際に動かして確認していませんが、rnnと3dについて「manage.py上のVehicle上のメモリ領域に最近N件のイメージデータを確保するような処理がない.」とありますが、それぞれのモデルパーツクラスに実装されているように見えます。

ton さんのコメント...

コメントありがとうございます。

http://docs.donkeycar.com/guide/robot_sbc/tensorrt_jetson_nano/
確認しました。TensorRT用ファイルのコンバートは公式ドキュメントにも書かれていたのですね。失礼いたしました。

Tensorflow Liteの変換はtflite.py内にkeras_model_to_tfliteとkeras_session_to_tflite
という関数が用意されているのでこれを呼び出すプログラムをかけばコンバートできそうです。

またご指摘の最近N件のイメージデータを確保する処理keras.pyの各パーツクラス内にありました。
パーツをVehicleへaddする際のinputsにかかれていないと..と思い込んでおりました。
最新N件をパーツクラスのself.img_seqに格納していたのですね。

みおとしておりました。訂正させていただきます。

既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ

既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。   1. The Twelve Factors (日本語訳からの転記) コードベース   バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 ...