lynxeyedの電音鍵盤

MBDとFPGAと車載で使うデバイスの備忘録

高度運転支援向け単眼カメラの実装(3.ニューラルネットワークの基本実装)

パーセプトロンの収束定理の壁

深度推定のフィルタを試作し様々な環境で調査して、ある程度どんな環境にも対応できそうなパラメータを決定しました。
が、すこし問題が出てきました。

  • すごく白い道路を道路と認識せず、壁と認識し、警告が止まらなくなる。(協業しているイスラエルの会社からの報告。こちらでも再現がある程度出来ている)
  • 昼間のフィルタパラメータでは薄暗い時に特徴点が減る。だが、深夜になると昼間と同等になったりする。薄暗い→夜の境目でのパラメータが全く不明。深度推定に問題が著しく出るわけではないが、運動視差などで補完できないレベルではある。

と、線形的にフィルタの閾値などを変更しても解決が難しい事象が出てきました。

この非線形な事象の解決にはニューラルネットワークが必要に思われます。ただしクラス分類は最小限にするなどして実時間での処理を目指します。
もちろん、高性能GPUで解決する方法はなくはありませんが、搭載するターゲット(軽車両、超小型車、既存車両への後付け)から考え、初期開発にお金をかけ、量産では費用をかけないものを目指します。


分類問題と回帰問題

行いたいのは深度推定とセマンティックセグメンテーションです。
この二者はディープラーニングでは少し異なる設計を必要とされます。

  • 深度推定は回帰問題
  • 車、人、二輪車、などは分類問題

これで出力層の設計が変わります。具体的には活性化関数が変わります。最終的にはあまり大した問題にはならないでしょう。

MATLABでNNの基本を設計する

実装にはMATLABを使います。Deep Lerning ToolboxやTensorFlowは使わず、バニラMATLABを使用します。それらのパッケージを使用しリソースリッチに実験するのも素敵ですが、その環境をFPGAや組み込みプロセッサへネイティブに動作させるとなると、移植に必要なエネルギーが膨大なのと、ハードリアルタイムに動作できなくなる可能性が高くなります。また、提供されている機能の大半は使用しないと思われます。今回利用するNNの機能は限定的であり、使用するニューロンの層数は2ないし3層と決定しています。FPGAに期待するのはTFが提供する機能が動くことではなく、行列積の演算を素早く終えること、ただそれだけです。逆にいうと、MATLABはその限られた環境に無理矢理押しこめるか見積もるための飛び道具です。

NN実装の素振り

CNNではなくNNから行います。非線形の分類=NNを試してみて、畳み込みNN(=CNN)のカーネルがどの程度必要とされているか見積もりたいからです。

スタンフォード大のニューラルネットワークの授業が公開されています。とても理解しやすく書かれています。実装例としてPythonを使っていますが、あまりPythonコードの解説にならないように努力が払われているように感じられます。NNはもとをただせば行列式の積和なので数式で説明された方が、証明もできますし、エンジニアとしては嬉しいです。ライセンスもアカデミックらしくMITです。

勉強がてらこのスタンフォード大の授業を和訳しています。(まだ途中)
github.com

Module.1の最終章「Putting it together: Minimal Neural Network Case Study」までやってみて、例題の線形分類と非線形分類をMATLABで実装しました。

線形分類

「Putting it together: Minimal Neural Network Case Study」の実践です。 線形分類スコアをS、分類付けをする重み行列をW、入力データをX(サンプル数i個、j番目まである行列)、バイアスをb、教師信号yと置くと、


S = WX+b
と記述できます。どれだけ教師信号yとかけ離れていたかを示す、損失関数はソフトマックス関数を用いて、下記の様に表せます。

L_i = -\log\left(\frac{e^{f_{y_i}}}{\sum_j e^{f_j}}\right)
ここから勾配を求め、重みを改良します。これを反復することによってどのくらい分類に成功しているかを求めます。詳細はこちらか英語の原文に当たってください。
MATLABで記述しました。コード全文は以下。
github.com
MATLAB homeをお使いの方でも基本パッケージだけで動くはずです。試したバージョンはMATLAB/Simulink R2021aです。

色分けしたスパイラル散布図を線形分類しました。黒丸の青、緑、赤を分類します。


f:id:Lynx-EyED:20210319192840p:plain
認識率は52%でした。大体48~53%くらいになります。視覚的にもわかる様に、ランダムな座標を生成し、分類がどの様にされているかをみてみました。「線形」分類なのでこんなもんですね。

ニューラルネットワーク

隠れ層を導入し、2層ニューラルネットワークを構築し活性化関数にReLUを導入したものです。


f:id:Lynx-EyED:20210319194200p:plain
98%~99%の分類精度を誇ります。やった。視覚的にも明らかですね。

MATLABコード全文は
github.com

これから

今回のトライアルは、入力データXは座標で、n番目データの前後(n-1),(n+1)などは独立していました。
ですが、入力するのは画像です。つまりあるピクセルの上下左右(もう少しマクロな視点で言うならば周囲数十ピクセル)、はかなり関連性の高い情報になるはずです。畳み込みが有効になってくる分野です。ここからCNNを実践していきます。