見出し画像

自動運転するなら最適な前処理をしよう!

久しぶりの投稿でーーーーーーす!(前回更新は去年の秋・・・)

前回から、いろいろ進捗が出ているのにも関わらず、記事を更新していないことは一旦無かったことにしておきます。汗

↓こんな感じで、しっかり自動走行しています!


さて、AIによる自動走行は様々な手法が提案されていますが、ここではカメラ画像から最適な操作を推論するオープンソース、「DonkeyCar」を使って自動走行を実現しています。

今回は、「DonkeyCar」によって自動運転する場合の画像の前処理について記していこうと思います。

(とりあえず結果だけ知りたいという方は、一番下までスクロールしてください。)



なんで前処理するの?

今回、画像の前処理をする目的は、「抽象性の高い自動走行AIを作る」これに限ります。

「抽象性の高い」とはどういうこと? かと言いますと、
以前に学習させたコースとは別のコースでも、学習なしで走行可能だということです。

例えば、
・コースの形が違う
・環境光が違う
・会場が違う

これらは、DonkeyCarの推論には大きな影響を与えます。
基本的には上の条件のどれかが当てはまっていれば、学習は初めからやり直さなければならないことが多いです。

今回は画像の前処理を行うことで、どんなコースでもいきなり自動走行できるAIを作ることを目標にしています。



DonkeyCarでは、どのように学習してるの?

上の動画で紹介した通り、ピンクのテープに沿うようにラジコンを走らせ、学習のためのデータを集めました。
しかし、DonkeyCarは必ずしもこのテープを認識して学習しているわけではありません。

下はDonkeyCarが集めたデータのひとつです。

画像1

{
    ...
    "user/angle": 0.5825864276568502,        # ステアリング:左へ約60%
    "user/throttle": 0.19591836734693877     # スロットル:前へ約20%
    ...
}

画像の瞬間、私はステアリングを左へ約60%、スロットルを約20%開けていたようです。


では、DonkeyCarはこのデータを集めてどのように学習するのでしょう?
DonkeyCarでは「ニューラルネットワーク」と呼ばれる方法で学習しています。

下の図はDonkeyCarのAIパートを簡略化したものです。

スクリーンショット 2020-07-26 0.02.04

「ニューラルネットワーク」の役割は、学習機能付きの計算器です。
DonkeyCarのニューラルネットワークは人間のラジコン操作を真似をするように計算式を調節します。


例えば、画像中のある4点の画素値がそれぞれ、4, 5, 1, 2だったとします。
ニューラルネットワークはこれらの値を使ってステアリングやスロットルの値を再現する計算式を考えます。

60 = [4] × 20 - [5] × 3 + [1] × 5 - [2] × 5
↑のように考えるかもしれませんし、

60 = - [4] × 5 + [5] × 6 + [1] × 30 + [2] × 10
↑のように計算するかもしれません。

考え方はAI次第です。


このように、1つの画像と操作データの組だけでは、
どの画素値を選んで、どのように計算するか、という考え方はほぼ無限にあります。

しかし、多くの画像と操作データの組を一つの計算式で再現するという場合には、その再現方法は限られてきます。

DonkeyCarでは、集めたあらゆる画像に対して、その画素値(正確には画素値に前処理を施したデータ)を使って、人間の操作データを再現できるような計算式を見つけ出します。

この十分に調整された計算式を使って、DonkeyCarは画像から操作データを計算し、自動運転が可能になるというわけです。


ただ、ニューラルネットワークの学習には、重要な性質があります。
ニューラルネットワークはできる限り楽をして計算式を見つける癖があります。
まるで人間のようです。

下の画像は、ステアリングを右に切っている瞬間です。

画像5

先ほどのステアリングを左に切っている画像はこちら。

画像1

両者を見比べた時に、ニューラルネットワークにとっては、
画像の下半分からピンク色を探し、その形と操作データの関係性から計算ルールを見つけるよりも、
上半分を見て「全体的に黄色っぽい場合は右、黒が多い場合は左」と単純な計算ルールの方が見つけやすいはずです。

こういう場合、先に風景で計算ルールを見つけたならば、その後もうちょっと頑張って、ピンクのテープで計算ルールを見つけ直すということはほとんどありません。

そのため、DonkeyCarはコースよりも風景部分の色の配置を見て学習しやすく、
・コースの形が違う
・環境光が違う
・会場が違う
という要因で自動走行できなくなる可能性が高いと言えます。



どのように画像を前処理するの?

では、どのようにすれば、コースを見てくれるようになるでしょうか?

今回試した手法は2つです。

・風景となる上半分をトリミングする
・前処理でレーンを直接検出する


1つめの方法は単純です。
学習に利用して欲しくない上半分を隠してしまうという作戦です。
(下の画像は上半分を黒く塗りつぶしているだけですが、実際には切り取って学習させます)

画像5

こうすることで、床の情報だけでニューラルネットワークに最適化させることができます。(地面の照り返しの影響などは残る)
また、総画素数が半分程度になり、ニューラルネットワークが考慮すべき計算量が減るため、高速な学習と高速な推論もできるようになります。


2つめの方法は画像処理によって直接レーンを検出する方法です。
余計な情報は完全に取り去ることで、ニューラルネットワークの学習を
「レーンの形」だけに集中させます。

画像6

検出方法は、ガンマ補正やコントラスト調整などを使って、レーンを強調したあと、色彩によって抽出を行いました。



前処理の結果はどうなった? & 考察

下の動画が、前処理の結果です。

左から、「前処理なし」「トリミング」「レーン検出」となっていて、
それぞれの上側が学習に利用したデータセット、下側が自動走行のシミュレーション結果で、各列で上下が対応しています。

また、それぞれの上下間(学習に利用したコースと自動走行のシミュレーションをさせたコース)では、コースの形が少し異なっています。

赤がステアリング、青がスロットルの推論結果を表しています。

まず結論として、「トリミング」では「前処理なし」と比べても遜色ない推論性能を見せているように見えます。
それどころか、コースの形の違いに対しても柔軟な適応力を見せているようです。
ニューラルネットワークの学習は、スパルタ教育の方が良いということですね(にっこり)

次に、「レーン検出」に至っては、ノイズの影響が大きい結果となりました。
これは、前処理の検出精度がさほど高くないという点が原因となっていると思います。


まだ過去のデータを使ったシミュレーションしかできていないので、実際に全然違うコースを走らせた結果が出たら、記事を更新します。

ひとまずの結果としては、「トリミング」は良好、「レーン検出」はまだまだという結果になりました。

とはいえ、レーン検出の最大の強みは、ガンマ補正やコントラスト調整のパラメータ最適化さえ行えば、「環境光、コースの形、レーンの色や種類」など様々な環境で汎用的に学習・推論できることであり、過去のあらゆるデータを複合した学習ができる可能性があるということです。

レーン検出のためのパラメータ自動最適化ツールを作成したので、それはまたの機会に紹介できればと思います。


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