オブジェクトの広場は株式会社オージス総研グループのエンジニアによる技術発表サイトです

AI

JetBotを動かしてみよう

第3回 JetBotを走らせる(衝突回避編)
オージス総研
堂 亮平, 山岸 優
2019年6月5日

本連載では「Jetson Nano」を使ったAI自律走行車「JetBot」(公式Wiki)について紹介しています。第3回となる今回は第1回で紹介した、JetBotが衝突や落下を回避しながら走行できるようになるまでをもう少し詳しく紹介していきます。

衝突を回避しながら走るまで

JetBotが衝突や落下を回避しつつ走行するためには、このまま走行できるのかそれとも何かに衝突したり落下してしまうのか、JetBotが判断できなければなりません。そこで、JetBotのカメラから取得した画像を元に状況を判断するモデルを作成し、動かします。工程は以下の通りです。

  1. ソフトウェアのセットアップ
  2. 教師データの収集
  3. 衝突回避走行モデルの学習
  4. 学習モデルによる衝突回避走行

なお本記事の参照元は、公式WikiのExamples内にある「Example 3 - Collision avoidance」となります。

1. ソフトウェアのセットアップ

まずJetBot上のJetsonNanoを起動させるために、公式WikiのSoftware Setupに従ってセットアップしてください。

セットアップの注意点

JetBotのOSイメージは通常版が64GBを超えているため128GB以上のmicroSDカードが必要になります。(64GBのmicroSDカードでも収まる63GBの縮小版イメージもありますが、後述の教師データの収集等を考えると、大きなサイズのmicroSDカードを準備することをお勧めします)

2. 教師データの収集

衝突回避走行モデルは、JetBotのカメラから取得した画像を下記のように2クラスに分類します。その判定結果から走行スクリプトが車体を制御します。そこで予め2クラスのどちらに属するかラベルを付与した画像データを集め、これをお手本(教師データ)としてモデルの学習を行います。

  • 衝突回避走行モデルの分類クラス
    衝突しない場合はまっすぐ進み、衝突または落下する場合は左折して回避します。(右折はしません)
クラス名 車体の制御
free 直進
blocked 左折

2-1. 教師データ収集方法の変更

教師データの収集はJetBot上で行います。公式Wikiのdata_collection.ipynbでは手動で1枚ずつ画像を保存していますが、今回は時間短縮のためJetBotを走らせながら連続で画像を保存するようにスクリプトを改変しました。JetBotを前進と左折の2種類の操作で走らせながら画像を保存し、それぞれの操作に対応したラベルを付けます。

操作コマンド 保存する画像 概要
forward クラス「free」の画像 画像を1枚保存し、少し前進する。コマンド「stop」を実行するまで前進を繰り返す。
left クラス「blocked」の画像 画像を1枚保存し、少し左折する。1回のみ実行する。
stop なし コマンド「forward」で前進中のJetBotを停止する。

2-2. 教師データ収集スクリプトの実行

スクリプトを実行して、JetBotを操作するためのUIを表示します。

カメラの映像を見ながら、3種類のコマンドでJetbotを動かして画像を収集します。公式Wikiでは、各クラスそれぞれ100枚以上の画像が必要となっています。

  • 教師データの収集風景

3. 衝突回避走行モデルの学習

3-1. 学習環境のセットアップ

モデルの学習はJetBot上でも行えますが、学習時間を短縮するために別のGPU搭載PC(学習用PC)で実行します。そこで下記に示す学習環境に必要なものをインストールします。また、JetBotのリポジトリからスクリプト一式をクローン、またはダウンロードしておきます。

  • CUDA
  • cuDNN
  • Python
  • Jupyter Lab
  • Pytorch

3-1. 教師データの移動

教師データをJetBotから学習用PCに移します。教師データはサンプルと同じくスクリプトと同じ階層(jetbot/notebooks/collision_avoidance/)の「dataset」フォルダに格納していますので、フォルダごと学習用PC側の同じ階層に移動します。

  • 教師データのラベルについて 「dataset」フォルダ以下には「free」フォルダと「blocked」フォルダが格納されており、それぞれに該当する画像が振り分けられ、これがラベル付けとなっています。

3-2. モデルの学習

学習用PCでJupyter Labのサーバを立ち上げ、train_model.ipynbを実行します。

学習はAlexNetの転移学習となります。エポック数はデフォルトで30回です。第一回記事で書いたとおり当初はエポック数を50回に増やして実行しましたが、かなり早い段階で精度(Accuracy)が1で張り付き上限に達する為、それほどエポック数は必要ありません。

4. 学習モデルによる衝突回避走行

4-1. 衝突回避走行スクリプトの実行

live_demo.ipynbを実行します。2つ目のコードセルで学習済みモデルを読み込むので、保存したファイル名に変更しておきます。

8つ目のコードセルにてcamera.observe()でカメラを有効にし、衝突回避走行を開始します。9つ目のコードセルは停止命令になります。camera.unobserve()はカメラで無効にし、robot.stop()でJetBotを停止します。

4-2. 衝突回避走行モデルの性能

「3-2. モデルの学習」で述べた通り、モデルの精度(Accuracy)は1で張り付き上限に達します。しかしこの精度は教えられたとおりに画像分類をできているかどうかなので、走行性能には直接寄与しません。走行性能はモデルに与える教師データの質に左右されます。

  • 慎重に走行するモデル
    こちらは安全運転で収集した教師データによるモデルです。衝突や落下を回避しているのは良いですが、左折タイミングが早く、旋回角度も大きくなっています。

  • 最低限の回避で走行するモデル
    こちらはなるべく回避動作が最小限になるよう走行し、教師データを収集したモデルです。障害物をギリギリで避け、旋回角度も1つ目のモデルより浅くなっています。ただ、たまに車体の後部が障害物に接触するため、まだ調整が必要です。

さいごに

今回はJetBotの衝突回避走行を実行するまでを紹介しました。モデルの学習自体はシンプルなDeep Learningによる画像分類で、収集する教師データも多くないので手軽だと思います。しかし衝突や落下をギリギリで避け、テーブル上をくまなく走るような性能の良いモデルを作るには、教師データの収集に試行錯誤が必要そうです。今回は性能の評価軸も決めていないため、モデルの評価方法を考えるのも面白いかもしれません。