AIもこなせるようになってきた IoTデバイス

#2021年も残りわずか！
早いもので12月、というわけで「画像認識できるデバイス」をテーマに
近年のIoTデバイスの状況をまとめます。
###AIタスクはディープラーニングに注目
ここ10年ほどはニューラルネットワークの汎用性と高い精度が着目され、さまざまな分野への応用が進んできました。
![ディープラーニング応用分野](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/fc071734-4f23-e607-5324-8ab61a8a3aa6.jpeg)
(画像引用元 [計測・試験機器総合Web展(計測展)](https://www.keisokuten.jp/static/sp_deeplearning.html))

10年前は顔認識なんか個人で扱える術もなく、一部企業の固有技術でした。
下のデジカメの例も、顔を「認識」しているわけでなく「検出」止まり。
![顔検出によるオートフォーカス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/da0790e2-531a-7ebe-a133-c23691998cd9.jpeg "ニコン COOLPIX7900")

(画像引用元 [デジカメWatch](https://dc.watch.impress.co.jp/cda/compact/2005/02/16/978.html))
で10年ほど前から突然ディープラーニングのブームに火が点き、オープンに研究されていることもあり、
今ではiPhoneなどのスマートフォンに顔認証が搭載され、画像認識はすっかり浸透した状況です。
###使いやすくなったディープラーニング
ディープラーニング自体もユーザが利用しやすいように、進化してきました。
使いやすさについて何点か述べたいと思います。
####1. 学習済モデルをダウンロードして使える
ディープラーニングの一般的な流れは次の通り、
学習フェーズにてモデルを鍛え、鍛えた学習済モデルを推論フェーズにて利用する流れです。
![学習と推論フェーズ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/84954ca7-5fb4-91bc-5ff9-afbc6ba3031b.jpeg "学習は大変、推論は楽")
(画像引用元 [キャド研](https://cad-kenkyujo.com/teruemon_ai/))

学習フェーズが面倒で大変です。
学習前にモデルの形を設計しますが、専門知識や経験がないと認識精度を確保できません。
加えてモデルの内部パラメータを鍛えるために、大量の学習用データを必要とします。
そして満足できる精度のモデルができるまで、モデルやデータを修正しながら何度も学習しなおす必要があります。
学習を短時間化するためには、高性能なシステムが必要です。

それに比べて、推論フェーズは楽です。
学習済モデルに入力データを突っ込んで、認識結果を受け取るだけ。

今は、画像認識など特定AIを利用するだけなら、精度の良い学習済モデルをダウンロードして利用でき、学習フェーズが不要です。

```python:test.py
import sys
import numpy as np
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions

model = ResNet50(weights='imagenet')

img = image.load_img(sys.argv[1], target_size=(224, 224))
imgin = preprocess_input(np.expand_dims(image.img_to_array(img), axis=0))
preds = model.predict(imgin)
print(decode_predictions(preds)[0])
```
上記 Pythonのサンプルコードで使われているのは、
ResNet-50 という1000種類の物体を識別できる学習済モデルです。
Kerasのライブラリでは、モデルを自動ダウンロードしてくれます。

上記プログラムのテストのため、次の画像を認識させてみます。
![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/48c42170-19ae-c7f2-ff8e-f6a15a9e7491.jpeg "グランツーリスモ")

```Bash
$ python3 test.py test.jpg
(省略)
[('n03895866', 'passenger_car', 0.19717215), ('n04285008', 'sports_car', 0.18797779), ('n02974003', 'car_wheel', 0.16151562), ('n03459775', 'grille', 0.12596677), ('n04037443', 'racer', 0.11913665)]
$
```
車とは認識しているようです。

####2. 開発環境の充実
Python言語がAIのライブラリも充実しており良く利用されています。
GPU(グラフィックボード) の並列処理機能を利用して、ディープラーニングを高速化できるようになってます。
上記環境をクラウド提供してくれる [Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja "Colaboratory") サービスがあります。
![Colab](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/15fa5770-e63d-4318-60b9-53962320f3eb.png "Colab")
(画像引用元 [python_textbook](https://python-textbook.readthedocs.io/en/latest/src/google_colab.html))

お試しレベルの利用なら無料で、Pythonや機械学習の勉強にも十分です。
環境構築する手間がなく、ブラウザからすぐ開発に着手できます。

####3. IoTデバイスからも利用可能に
IoTデバイスは、一般的に低スペックでデータ処理は難しいとされてきましたが、最近は事情が変わってきています。

Raspberry Pi が代表的な例で、手のひらサイズのマイコンボードに OSが載るほど高性能化しています。
![Raspberry Pi 4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/8aac8a1c-8e3d-cbd5-f4ff-608ced589f84.png "Raspberry Pi 4")

非力なマイコンボードに 「AIチップ」を載せる製品も出てきました。
次の写真の真ん中にある小さいチップは、ST製の 「SensorTile Kit」です。
![AIチップの例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/781e62ec-daed-e5b1-dea0-bd6e99e19173.jpeg "ST SensorTile Kit")
(画像引用元 [ロボスタ](https://robotstart.info/2019/05/29/sensor-tile-kit01.html "ロボスタ"))

FPGAによるハードウェア合成でAIチップを自作する試みもあります。

ソフトウェアライブラリも選択肢が増えています。
TensorflowLite などの TinyML と呼ばれる類のライブラリが注目をあびつつあり、メモリの少ないマイコン上でAI処理できるようになっています。

#2020年に製作した顔認識デバイス
ここからは実際に触ったIoTデバイスの紹介です。
講習会で顔認識のデモ用に、Raspberry Piで顔認識システムを作りました。
![顔認識システム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/ebfd179a-ae50-9816-ee58-f932b650560d.jpeg "Raspberry Pi 4")
Raspberry Pi 4 とタッチパネルをフレームケースに組み込んだもので、
CCDカメラやスピーカーも備えています。
![システム概要](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/fd66021c-1ce3-cc46-6d8d-8cffaf5a419c.png "システム概要")
![製作工程1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/216f9d8e-e522-80da-dd6b-f4db2fb1fceb.png "製作工程1")
![製作工程2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/9841990e-91a1-4b7f-406a-6b78e41896c8.png "製作工程2")
![製作工程3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/fcc7461c-4028-f282-a157-2684eeae12e3.png "製作工程3")
顔認識のアプリケーションも自作しました。 Pythonから Dlibと呼ばれるライブラリを利用しています。
Dlib自体は汎用のデータ分析ライブラリですが、最近はディープラーニングモデルが利用できるなど流行を取り入れた拡張がなされています。

認識された顔の特徴量データと名前をセットで、Elasticsearchへデータベース登録できるようにしました。
アプリケーションの実行イメージは次のような感じです。
![ひろゆきとほりえもんの顔認識](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/0204f063-56a9-52a8-d24b-1742cef06130.jpeg "顔認識")

#2021年に購入したAIカメラデバイス
今年はAI処理ができるマイコン製品をいくつか試しました。

###Maixduino
まず、Sipeed社製のマイコンボードである「[Maixduino](https://akizukidenshi.com/catalog/g/gM-15550/)」です。
K210と呼ばれるRISC-VアーキテクチャのSoCがメインで、
KPUと呼ばれるニューラルネットワークアクセラレータを搭載しています。
![Maixduino](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/38f063d8-c863-ff8c-fbc0-37c3e9d6ea3a.jpeg "Maixduino")
K210用に [MaixPy](https://github.com/sipeed/MaixPy)と呼ばれる MicroPythonが動作するファームウェアが提供されています。
MaixPyでは MicroPythonにより、つまり Pythonでプログラミングが可能です。
これで、1000クラス(1000種類)判別の画像認識を試しました。

```python
import sensor, lcd
import KPU as kpu
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
sensor.set_vflip(1)
sensor.run(1)
lcd.clear()
lcd.draw_string(100,96,"MobileNet Demo")
lcd.draw_string(100,112,"Loading labels...")
task = kpu.load(0x300000)
kpu.set_outputs(task, 0, 1, 1, 1000)
f=open('labels.txt','r')
labels=f.readlines()
f.close()
clock = time.clock()
while(True):
    img = sensor.snapshot()
    clock.tick()
    fmap = kpu.forward(task, img)
    fps=clock.fps()
    plist=fmap[:]
    pmax=max(plist) 
    max_index=plist.index(pmax) 
    a = lcd.display(img, oft=(0,0))
    lcd.draw_string(0, 224, "%.2f:%s                            "%(pmax, labels[max_index].strip()))
    print(fps)
a = kpu.deinit(task)
```
肝となる部分は、
MobileNetモデルとして学習済のデータを ファームウェアの0x300000番地に書き込んで利用しているところ。
「task = kpu.load(0x300000)」 の部分です。
K210はメモリ 8MB制限があるため、最小サイズのファームウェアを選ぶなど切り詰めないと動作しません。
![iPhone認識](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/2633ab85-15e5-9d55-58d6-84c2b2dca640.jpeg "Maixduinoの1000クラス画像判別")
iPhoneをカメラで認識させたところ iPod と判定されてますが、概ね認識するようです。

MaixPyには、NES(ファミコン)エミュレータを搭載するファームウェアが存在します。

```python
import nes
nes.init(0)
nes.load("nes/Alter_Ego.nes")
while True:
  nes.loop()
```
![ALTER EGO](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/fb652c98-a7ed-3fbc-a295-69b9fa2b1290.jpeg "NESエミュレータ")
Maixduinoでは、RGBチャンネルが誤っているためか色が変ですが、とりあえず動きます。
AIといい、ファミコンといい、遊び心満載なのが中華製品の特長と呼べるでしょう。

###M5Stack UnitV2
次に買ったのは、M5Stack社製 M5Stack UnitV2です。
2021年6月に発売されたばかりの、AIカメラと呼ばれる製品です。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/b822caf1-9862-1bba-1267-dc194cf42ca2.jpeg "M5Stack UnitV2")
(画像引用元 [SWITCHSCIENCE社](https://www.switch-science.com/catalog/7160/))

UnitV1 は、Maixduinoと同じ K210を搭載していてメモリサイズに制限がありましたが、
UnitV2 は、128MBメモリを搭載し Linuxが動きます。 このサイズで Linuxマシンです。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/4955b424-0156-00c2-2e4b-4f50bc2d1845.jpeg "M5Stack UnitV2")
さらに標準ファームウェアで Webアプリが動作し、各種AIタスクがメニューから実行可能です。
プログラムとかインストールは不要、買って PCとつなげるだけです。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/107a5a76-3d29-8a7a-0496-f935d8db5cb2.png "UnitV2 Webアプリ")
PCと UnitV2を USBで繋いで、 http://unitv2.py へアクセスすれば、メニュー画面が開きます。
希望のメニューをクリックすると、該当のAIタスクがロードされ実行されます。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/9da82bfa-8f3d-b404-fe4a-7d964ade35e8.png "UnitV2 メニュー")
メニューはこんな感じ。
イメージで表示しきれてませんが、内蔵マイクを利用した音声波形分析も可能です。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/7f707ab2-a4df-ec03-757e-68deb1118569.png "UnitV2 Camera Stream")
「Camera Stream」は、AIとかなく、カメラの映像をそのまま表示します。
カメラの画質は、昔のスマートフォンレベルです。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/5f4f709c-495b-b0e1-0e0a-274db71711b8.png "UnitV2 Object Recognition")
「Object Recognition」です、そこそこ認識してくれます。
![M5Stack UnitV2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347113/4f3b4fb5-74f4-ff20-ade2-4797605a7548.png "UnitV2 Code Detector")
「Code Detector」はこんな感じです。 QRコードは読み取ってくれるようです。

これ以外も、Jupyter Notebookに切り替えて Pythonプログラムが実行できたり、
Linuxなので、環境やツールのカスタマイズ性が高いというのも魅力です。

この手のものは中国製品が先行している状況で、AIをバンドルした売り方といい、開発力が高いと感じさせられます。

# 以上
来年も、良いお年を。