Jetson NanoでCustomVisionのモデルを動かしたかった

# はじめに
- https://medium.com/microsoftazure/running-a-gpu-enabled-azure-custom-vision-docker-container-on-a-nvidia-jetson-nano-db8747b00b4f

上記の参考サイトに従ってCustomVisionのモデルをJetsonNanoで動かしていきます。自分用の記録です。
~~現状動いていません。解決方法を教えていただけると幸いです。~~

**(2020/11/5)** Nvidiaが提供するコンテナのカタログを見ていたらTensorflowが入ってるDockerイメージがありましたのでそれを利用することでできました。その記事は[こちら](https://qiita.com/yosiiii/private/237991750a7e3c777e91)です。

本記事はJetsonNanoのセットアップの自分用メモとして残しておきます。

# 用意するもの
- Jetson Nano
- PC
- マイクロSDカード
- マイクロSD変換アダプター
- Micro-USB充電器
- CustomVisionのモデル
- USBキーボード
- マウス
- HDMIケーブル
- モニター

# Jetson Nanoのセットアップ

**OSのインストール**
まずOSをインストールします。OSのインストールは[公式](https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#intro)の通りにやっていきます。
はじめにSDカードをフォーマットします。以下のサイトからSD Card Formatterをダウンロードしてきて、PCにインストールします。
https://www.sdcard.org/jp/downloads/formatter/eula_windows/index.html
インストールしたら起動してマイクロSDカードをPCに接続、フォーマットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685335/3a336b0f-ade1-4103-873a-9c45aae5bb15.png)


次にOSイメージをマイクロSDカードに焼きます。以下のサイトからbalenaEtcherをダウンロードしてインストールします。
https://www.balena.io/etcher/

OSのイメージは以下からダウンロードしておきます。5.9GBもあるのでダウンロードに時間がかかりました。
https://developer.nvidia.com/jetson-nano-sd-card-image

Etcherを起動してOSのイメージを選択してマイクロSDカードに焼きます。これでOSのインストールは完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685335/7815d0b1-7168-5a4d-f1ac-7d5c55220612.png)

マイクロSDをJetson Nanoにさして電源をつけると、言語、キーボード配列、タイムゾーン、ユーザの作成などがあります。それらを完了したら次に進みます。

**CustomVision用にConfig編集**
Jetson NanoでConfigをいじる必要があるみたいです。sshで接続するか、直接コンソールをたたいて参考サイトにあるコマンドを実行していきます。

```
sudo systemctl set-default multi-user.target
sudo nvpmodel -m 0
```

↑　UIを使わないようにして、Nanoをスピードアップするためにハイパワーモードにするみたいです。次に、DockerのランタイムをデフォルトでNvidiaのランタイムにするためにviなどで```/etc/docker/daemon.json```を以下のように編集します。

```json:/etc/docker/daemon.json
{
  "default-runtime": "nvidia",
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
     }
   }
}
```

次にパッケージを最新のバージョンにアップデートします。

```
sudo apt-get update
sudo apt-get dist-upgrade
```

```sudo``` なしでDockerを使うためにDockerのグループにユーザを追加します。

```
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
```

再起動します。

```
sudo reboot
```

最後にGPUのテストをします。以下のコマンドを実行して最後の行に```Result = PASS```と表示されたらセットアップは完了です。それ以外の場合は、画面の指示に従ってDockerでGPUサポートを有効にしてみてとのことです。

```
docker run -it jitteam/devicequery ./deviceQuery
```

## CustomVisionのモデルのダウンロード

CustomVisionからJetson Nanoにモデルをダウンロードします。PerformanceタブでダウンロードするIterationを選択し、Exportします。プラットフォームはDockerfileを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685335/fd39718d-0374-0287-d5f1-54bbca41baec.png)
versionはLinuxを選択し、Exportします。Exportが終わったら、ダウンロードボタンを右クリックでリンクをコピーしてどこかに保存しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685335/3ef781f0-efc7-1f31-58c2-1a270845dca7.png)

## CustomVisionのコンテナを実行する

CustomVisionのモデルをダウンロードします。ダブルクオートを忘れないように。url部分を先ほど保存したリンクにすることで先ほどのモデルをダウンロードできます。

```
wget -O customvision.zip "https://github.com/hnky/blog/raw/master/downloads/HomerOrMarge.DockerFile.Linux.zip"
```

展開します。

```
unzip customvision.zip -d customvision
```

Dockerfileを編集する必要があるみたいです。以下のように編集します。sshで接続してviで編集、```:%d```で一括削除、コピーして右クリックペーストで行けます。

```
cd customvision
nano Dockerfile
```

```dockerfile:Dockerfile

FROM nvcr.io/nvidia/l4t-base:r32.2
RUN apt-get update -y
RUN apt-get install python3-pip -y
RUN pip3 install -U pip
RUN DEBIAN_FRONTEND=noninteractive apt-get install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev -y
RUN DEBIAN_FRONTEND=noninteractive apt-get install python3 python3-dev python-dev build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev zlib1g-dev -y
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3-opencv
RUN pip3 install --pre tensorflow-gpu==2.0.0 --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v42
RUN pip3 install flask pillow
COPY app /app
# Expose the port
EXPOSE 80
# Set the working directory
WORKDIR /app
# Run the flask server for the endpoints
CMD python3 -u app.py
```

編集したらビルドします。時間がかかります。

```
docker build . -t mycustomvision
```

ビルドが終わったらコンテナを起動します。

```
docker run -p 127.0.0.1:80:80 -d mycustomvision
```

なぜか推論できない...。app.pyがエラーで止まってるみたいです。以下でエラーの内容が確認できます。

```
docker logs <container name>
```

本来うまくいっていたなら画像をPOSTすることで推論してくれるみたいです。以下のようにテストができるはずです。

```
curl -X POST http://127.0.0.1/url -d '{ "url": "https://github.com/hnky/blog/raw/master/downloads/marge.jpg" }'
```

# 感想
TensorFlowやKeras、dockerのl4t-baseイメージを変更してやってみてもうまくいきません。どうして、、、


間違い等ありましたらご指摘いただけると助かります。