
こんにちは,先日からハカルスにインターンで来ている, エッジエンジニアの岸本です.昨年夏にソニーから発売されたArduino互換の高性能ボードコンピュータ,SPRESENSEを触ってみました.SPRESENSEはArduino互換のEdgeデバイスで高性能なCPUを積んでいます.そこで今回は性能面で困難とされるエッジでの学習を行ってみました.
ここ数年でEdgeでの推論デバイス・アクセラレータが流行ってきています.しかし,Edgeでの学習はあまり見かけません.そこで今回は,SPRESENSE上でハカルスの得意とするスパースモデリングの学習を行いました.
1. SPRESENSEとその開発環境
SPRESENSEはソニーの開発した高性能なArduino互換ボードでソニーの開発したセンシングプロセッサーCXD5602を搭載しており,
- 低消費電力
- 高い計算能力
- GPSによる測位機能
- ハイレゾ音声の入出力
などの強みがあります.Xperia Ear Duoにも搭載されており,首振りのジェスチャー操作の認識には機械学習が使われているそうです.今回は以下の2つのポイントについて調査してみます.
- Arduino互換のためArduinoIDEで開発でき, 学習コスト・導入の敷居が低い.
- 高性能な演算能力があり,Edge側での学習が行える.
Arduinoはオープンソースで開発されているハードウェアでライセンスさえ守れば自由に互換製品を出すことが出来ます.またArduinoの統合開発環境であるArduinoIDEもオープンソースで公開されており,自由に使うことが出来ます.
1.1 開発環境/環境構築について
- SPRESENSE
- Windows 10
- ArduinoIDE 1.8.21.0
ArduinoIDEの設定,ブートローダーの書き込みなどはこちらを参照しました.
2. ADMMの実装
Lasso のアルゴリズム実装の一つにADMMというものがあり,今回はこのアルゴリズムを使用します.L1ノルムを最適化することで,結果として得られる線形回帰モデルの重みがスパースになります.今回実装したコードはすべてハカルスの GitHub で公開しています.ADMMによる最適化をlasso_train.hという名前のファイルにadmmクラスを作りましたので参照してください.
また、行列計算を簡単にするため,行列計算用クラスをndarrayという名前で作りました.行列の生成,四則演算,行列積,逆行列の計算などを実装しました.以下のような簡単な行列演算が出来ます.
3. ADMMの実行
3.1 学習に用いたデータセット
ボストンの住宅価格のデータセットを用いました.以下のデータを1~13のデータを入力し14・MEDVの予測をするモデルを学習させます.
- CRIM – per capita crime rate by town
- ZN – proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS – proportion of non-retail business acres per town.
- CHAS – Charles River dummy variable (1 if tract bounds river; 0 otherwise)
- NOX – nitric oxides concentration (parts per 10 million)
- RM – average number of rooms per dwelling
- AGE – proportion of owner-occupied units built prior to 1940
- DIS – weighted distances to five Boston employment centres
- RAD – index of accessibility to radial highways
- TAX – full-value property-tax rate per $10,000
- PTRATIO – pupil-teacher ratio by town
- B – 1000(Bk – 0.63)^2 where Bk is the proportion of blacks by town
- LSTAT – % lower status of the population
- MEDV – Median value of owner-occupied homes in $1000’s
3.2 データセットの読み込み
Arduinoエディタのツール>シリアルモニタでシリアルモニタを開きます.シリアルモニタよりデータのサイズとデータセットを入力し,シリアル通信でSPRESENSEに送ります.
3.3 学習の結果
学習器にデータを入れ学習を実行したらシリアル通信で学習したスパースベクトルをPCをに送り返して表示します.実行した結果が下の画像になります.表示されているベクトルより,学習したベクトルがスパースになっていることが分かります.
14:MEDV(住宅価格の中央値)は6:RM(1戸当りの部屋の数)に正の重み,13:LSTAT(地位の低い人の人口)と11:PTRATIO(1教師当たりの生徒数)に負の重み,という結果になりました .また,学習にかかった時間も0.16秒と,とても高速で有ることが分かります.
4. Fused Lassoの実装
Fused Lasso は隣り合う要素同士の差を用いた罰則項を設定することで、隣り合う要素間の変化を抑制することができます.実装のコードは fused_lasso クラスを見てもらえればわかるのですが、元になる admm を少し拡張することで実装できます.一般化 Lasso の拡張法についてはハカルスがメンテナンスしているオープンソースのライブラリ spm-image に例がありますし,ハカルスのスパースモデリング のエバンジェリスト増井さんによる発表資料もありますので、ご興味ありましたらそちらもご覧ください.
4.1. 学習させるデータ
ここでは簡単な矩形波にノイズを乗せ,そこからノイズ除去するというタスクを用意しました.
4.2. 学習の結果
学習結果をmatplotlibで表示したものが下図になります.100次元の階段状の矩形波ベクトル(青)にノイズを乗せ(橙)それをFused Lassoでデノイズ(緑)しました.
5. 結論
今回はSPRESENSEを用いてLassoとその派生系であるFused Lassoを実装しました.SPRESENSEは低消費電力にもかかわらず高速で動作し,組み込み機器でも線形回帰モデルの実行は十分に可能なことがわかりました。
またArduino互換であるため学習コストが低く,手軽にプログラムを書けました.今回は使いませんでしたがGPSやDACを内蔵していたり拡張ボードとしてカメラやWi-fiも使えるためとても夢が広がりますね.