リッチな開発環境NVIDIA TAO ToolkitではじめるAI開発！YOLOv4-tinyとclassification(tf2)の転移学習・最適化・デプロイのチュートリアルスクリプトから読み解くAI開発の手順とは

# Step-by-StepでAIを開発することのできるNVIDIA TAO Toolkitを利用して、AIモデルの入手から、学習、適応、最適化、デプロイまでの手順を理解する

MediaTekのSoCについて調べていたところ「NVIDIA TAO Toolkit」という開発ツールに出会いました。NVIDIA TAO Toolkit は **転移学習(Transfer Learning)** によりAI開発の **T(Train)、A(Adapt)、O(Optimize)** を加速し、少ない手順で実運用に耐えるAIモデルを生成できる開発プラットフォームです。少ない手順で開発できるということは<font color="blue">**「NVIDIA TAO Toolkitによる開発手順さえ理解してしまえば、AI開発の基礎を習得できるのでは...」**</font> と思い立ち、手元のワークステーションにNVIDIA TAO Toolkitをインストールし、AIモデルを開発してみました。

### NVIDIA TAOによるAIモデルの開発が簡単な理由

NVIDIA TAO ToolkitによりAIモデルの開発手順を簡単に習得できる最大の理由は **チュートリアルのソースコードに「Jupyter Notebook」を活用していることにあります。** Jupyter Notebookは、Pythonスクリプトに追加の説明文を追記できる形式の開発環境であり、 **開発の説明文を読みながら、Pythonスクリプトによる開発を推進することができます。** つまり、NVIDIA TAO Toolkitの提供するJupyter Notebook用のファイル **「*.ipynb」** を上から順に辿り、それぞれのコードブロックの意味を理解し、実行していけば、Step-by-StepでAIモデルの開発方法を習得できてしまうのです。

https://docs.nvidia.com/tao/tao-toolkit/text/overview.html

![スクリーンショット 2025-02-11 171106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/e7a58ccb-be21-7a1d-c614-51e890d4fd00.png)

# NVIDIA TAO Toolkitのインストール手順

まず、NVIDIA TAO Toolkitをインストールしましょう。インストール手順は下記の記事をご参照ください。 **NVIDIA TAO Toolkitは複数の開発フレームワーク上で動作しますので、依存するフレームワークをすべてインストールした後に、NVIDIA TAO Toolkitをインストールします。** やや煩雑な手順となりますが、一度セットアップしてしまえば、利用する方法はとても単純なので、インストールに一度だけお付き合いください。

https://qiita.com/xtrizeShino/private/2de2c6b139fa8d7cfcaf

1. **CUDA** ... GPUへアクセスするためにインストール
2. **cuDNN** ... Neural NetworkからCUDAへアクセスするためにインストール
3. **Docker** ... NVIDIA TAOを実行するための仮想環境として追加
4. **NVIDIA Container Toolkit** ... Docker上からGPUを利用するために必要
5. **NGC CLI** ... NGC (NVIDIA GPU Cloud) を連携するためのCLIツール
6. **Anaconda3** ... NVIDIA TAOと連携するための仮想環境も作成する

# インストールしたNVIDIA TAOでYOLOv4を開発する

それでは、早速インストールしたNVIDIA TAO Toolkitを使って、 **物体検出を行うAIモデル「YOLOv4-tiny」** を開発してみましょう。本記事の手順を辿ることにより、以下のように **自動車と人物を検出できるAIモデル** を開発することが可能です。

https://docs.nvidia.com/tao/tao-toolkit/text/cv_finetuning/tensorflow_1/object_detection/yolo_v4_tiny.html

![000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/f3c9a4d9-8cf5-9286-5913-d9c2eb637d8a.png)

## 実行環境

今回は、以下の環境にて、NVIDIA TAO Toolkitを利用しました。GPUのメモリサイズがSystem Requirenmentsに足りていませんが、 **GPUのモデルサイズとして16GBが求められているのは、1回の推論で処理するデータの個数（batch_size）が16GB向けにチューニングされているため** ですので、Memory Allocation Error等が発生してしまい、動作しない場合はbatch_sizeを調整すれば問題ないでしょう。

- Core i5-14500 (14cores, 20threads)
- RAM 64GB
- NVIDIA GeForce RTX3060Ti 8GB x2
  - 注意）System Requirenments(=16GB)に満たないメモリサイズ

NVIDIA TAOのSystem Requirementsは以下の通りです。

- System Requirements
  - 16 GB system RAM
  - 16 GB of GPU RAM
  - 8 core CPU
  - 1 NVIDIA GPU
  - 100 GB of SSD space

## 開発手順

NVIDIA TAO ToolkitによるAIモデルの開発は、
下記に挙げる11個の手順から構成されています。

1. **Install the TAO launcher** ... 環境設定
2. **Prepare dataset and pre-trained model** ... 学習済みAIモデルの取得
3. **Provide training specification** ... ハイパーパラメータの設定
4. **Run TAO training** ... 最初の転移学習
5. **Evaluate trained models** ... 学習結果の評価 
6. **Prune trained models** ... 最適化（プルーニング）
7. **Retrain pruned models** ... プルーニングしたモデルでの学習
8. **Evaluate retrained model** ... 学習結果の評価
9. **Visualize inferences** ... 実画像に対する推論
10. **Model Export** ... AIモデルの書き出し
11. **Verify the deployed model** ... 書き出したモデルの評価

#### NVIDIA TAO Toolkitによる転移学習とは！

https://resources.nvidia.com/ja-jp-tao/watch-126

https://aws.amazon.com/jp/what-is/transfer-learning/

https://event.dbsj.org/deim2022/post/tutorial/deim2022_tutorial_T7_slides.pdf


## NVIDIA TAO ToolkitでYOLOv4のAIモデルを開発する

それでは、NVIDIA TAO Toolkitを使ってYOLOv4のAIモデルを開発してみましょう。

### 作業用ディレクトリを作成する

まず、NVIDIA TAO Toolkit用の作業用ディレクトリを作成します。

```bash
mkdir -p ~/sandbox_tao_tutorial/
```

### Pythonの仮想環境を有効化する

次に、NVIDIA TAO Toolkitを実行するために必要なPythonの仮想環境「launcher」をactivateします。その後、 tao_tutorials ディレクトリにて jupyter notebook を実行し、ブラウザからNVIDIA TAOへアクセスできるようにします。 **launcherのセットアップ方法については下記の記事をご参照ください。**

https://qiita.com/xtrizeShino/items/2de2c6b139fa8d7cfcaf

```bash
(base) $ conda activate launcher
(launcher) $ cd ~
(launcher) $ cd tao_tutorials/
(launcher) $ jupyter notebook --ip 0.0.0.0 --port 8888 --allow-root

# [I 2025-02-08 12:28:29.403 ServerApp] http://shino-Ubu22-devel:8888/tree?token=d0943ab5b36f7e39133dfef8c902bd8afe07c560c883a0c4
# [I 2025-02-08 12:28:29.403 ServerApp]     http://127.0.0.1:8888/tree?token=d0943ab5b36f7e39133dfef8c902bd8afe07c560c883a0c4
# [I 2025-02-08 12:28:29.403 ServerApp] Use Control-C to stop this server and shut down all kernels 
```

### NVIDIA TAO Toolkit内のYOLOv4-tiny開発スクリプトを開く

インストールしたNVIDIA TAO Toolkitに含まれる「YOLOv4-tiny」の開発スクリプトは **「notebooks」「tao_launcher_starter_kit」「yolov4-tiny」** に含まれています。

![スクリーンショット 2025-02-09 181118.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/6d999562-b478-bac0-fb2f-cb0e085854eb.png)

![スクリーンショット 2025-02-09 181204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/7bf12a21-df73-0403-566a-c865a9086f44.png)

![スクリーンショット 2025-02-09 181323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/ce75684d-46d2-6187-debf-878ba58cb72e.png)

Jupyter Noptebook形式のYOLOv4-tinyの開発スクリプトを開くと、下記のように、説明文とソースコードの混在した開発画面が表示されます。この説明文を読みながら、 **都度、作業ディレクトリなどの必要な情報を記入** し、Jupyter Notebookを実行していくことにより、YOLOv4-tinyのAIモデルを入手することができます。

![47f547a5-edba-e347-d406-a01b9d46bf9c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/63223b4e-78db-ce2e-7a40-e30fb151eed7.png)

### 作業用ディレクトリを作成し、指定する

続いて、 **YOLOv4-tinyモデルの開発に利用するディレクトリを作成** します。そして、作成したディレクトリのパスをJupyter Notebookで開かれているYOLOv4-tinyの開発スクリプト中に記入します。 **パスを指定する場合は、相対パスでなく、絶対パスを指定してください。**

```bash
(base) $ mkdir -p ~/sandbox_tao_tutorial/yolov4_tiny
(base) $ cd ~/sandbox_tao_tutorial/yolov4_tiny/
(base) $ pwd
/home/shino/sandbox_tao_tutorial/yolov4_tiny
```

# ![スクリーンショット 2025-02-09 181835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/9b2083d3-3690-645b-3c0d-e48079968491.png)

### 学習用データセットを入手し、展開する

NVIDIA TAO Toolkitは学習済みのAIモデルに対して、転移学習を行うことのできるツールキットです。ここでは転移学習に利用するデータセットをダウンロードします。

YOLOv4-tinyで利用する追加のデータセットは、 **Notebookに記載されているリンクをクリックし、メールアドレスを入力することにより、メールアドレス宛にダウンロードURLが送られてきますので、そちらのURLをスクリプト中に記入** することにより、入手できます。

![スクリーンショット 2025-02-09 182243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/54dd383e-5b1a-f683-1559-9368659f5cd6.png)

![スクリーンショット 2025-02-09 215002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/149a79d9-2cf7-94fb-6440-9e05bb92898a.png)

データセットをダウンロードした後、TAOのコマンド `tao model yolo_v4_tiny dataset_convert` を利用して学習用データセットと検証用データセットを定義します。

![スクリーンショット 2025-02-09 215451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/92c6bf16-60a6-c105-db04-3cbd6ade0e58.png)

### 学習済みモデルを入手する

次のステップを実行することにより、学習済みのAIモデルを入手できます。スクリプトの実行後 **「*.hdf5」のTensorFlow 形式のAIモデルがダウンロードされた** ことを確認できます。

![スクリーンショット 2025-02-09 215743.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/0b91a45e-15a0-1c86-1e15-78a3861029bc.png)

### 転移学習を実行する

学習用データセットと、学習済みAIモデルを利用し、**転移学習（transfer learning）** により、目指すべきAIモデルを手早く入手します。 **転移学習は `tao model yolo_v4_tiny train` コマンドにより実行し、ハイパーパラメータは `*.kitti.txt` にて指定** します。また、今回の開発環境には **GPUが2基搭載されていますので `--gpus 2 --gpu_index 0 1` を指定し両方のGPUを使う旨** を設定します。

https://docs.nvidia.com/tao/tao-toolkit/text/cv_finetuning/tensorflow_1/object_detection/yolo_v4_tiny.html

![スクリーンショット 2025-02-09 220319.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/3f5d9528-5013-3272-c9c7-04fb1ddca5a2.png)

学習が始まると `nvidia-smi` の出力にて、以下のように2基のGPUのメモリが消費されていることを確認できます（ **並列に学習が進んでいることを確認することができます** ）。学習は80epochs行われます。

![スクリーンショット 2025-02-09 220604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/61d9b881-fbb4-52b8-0e6f-b24a69300556.png)

### 学習が完了したAIモデルを評価する

AIの転移学習が完了したならば、次に、AIモデルの評価を行います。 **評価には `tao model yolo_v4_tiny evaluate` コマンドを利用します。** この評価により、どのくらいの精度のモデルが生成できたかを確認することが可能です。もし、十分に学習できていないようであれば **「学習のepochs」** や **「データセットの量や質」** を見直す必要があるでしょう。

![スクリーンショット 2025-02-10 083339.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/20590865-52ec-4413-4411-1706d88af468.png)

### 影響の少ない重み値(weight)に対してプルーニング（枝刈り）を実施し、プルーニング後のモデルに再度学習を適用する

YOLOv4-tinyは非常に深いニューラルネットワークの構造を持ったAIモデルです。そのため、前手順により学習をした結果、 **接続しなくてもよい（重み値：weightを"0"として扱ってもよい）ニューロン間の結合が存在し、こうしたネットワークを切断することにより、AIモデルのレイテンシを改善することができます。** このように、ニューラルネットワークの枝を刈る処理のことを **「プルーニング」** と呼びます。

https://www.tensorflow.org/model_optimization/guide/pruning?hl=ja

プルーニングによる最適化では、まず、前述した通常の転移学習した結果に基づいて、不要と思われる枝を選定し、これを切断。新しくなったニューラルネットワークがよりよいパラメータを保持できるよう、再度学習を行います。

![スクリーンショット 2025-02-10 083728.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/fbefab25-2c72-ba93-d974-6103a6726b8e.png)

以下のコマンドにより **プルーニングしたAIモデルに対して学習を再度実施します。**

![スクリーンショット 2025-02-10 111755.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/8afee39f-5b89-097f-a52e-b19b36942887.png)

最後に、得られたAIモデルを評価しましょう。

![スクリーンショット 2025-02-10 150458.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/c05a8121-ef9b-ff08-f213-aa93c5db77cb.png)

### 学習した結果として得られたAIモデルで推論する

ここまでで得られたAIモデルを利用して、実際の画像データに対して推論を実施し、推論ができることを確認してみましょう。 **推論には `tao model yolo_v4_tiny inference` コマンドを利用します。ここでは9枚の画像に対して推論を実施しています。** 推論後、実際に画像を開くと、期待するオブジェクトがバウンディングボックスで囲まれている様子を見ることができます。

![スクリーンショット 2025-02-10 150747.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/712bc3a0-5f5d-620b-eab9-bbd874e22d30.png)

![000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/f3c9a4d9-8cf5-9286-5913-d9c2eb637d8a.png)

### 生成されたモデルから、FP32/FP16/INT8それぞれの重み値に量子化されたモデルを生成し、ONNX形式とTensorRT形式でエクスポートする

ここまでの手順で **構築したAIモデルを、実際のエッジAIでも実行できるようにデプロイ** します。デプロイ工程では、量子化のデータ幅を決めるパラメータ `fp32` `fp16` `int8` を `tao model yolo_v4_tiny export` や `tao model yolo_v4_tiny gen_trt_engine` に指定し、 **エッジでも処理しやすいデータ幅(FP32/FP16/INT8)のAIモデルをエクスポートします。**

https://docs.nvidia.com/tao/tao-toolkit/text/tao_deploy/yolo_v4_tiny.html

![スクリーンショット 2025-02-10 151351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/099c6cff-3750-8fd6-934a-b98861ea4144.png)

![スクリーンショット 2025-02-10 151402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/87f5c604-da64-4534-b946-96c05aafd832.png)

![スクリーンショット 2025-02-10 151424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/9b8cbc33-54f1-742e-dba6-42813a0abe37.png)

![スクリーンショット 2025-02-10 151438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/6a8953f9-8417-77a4-376e-1bd8a50161a6.png)

エクスポートの結果、 **FP32/FP16/INT8のAIモデルを得ることに成功** しました。

```bash
### 作業用ディレクトリへ移動する
(base) $ cd ~/sandbox_tao_tutorial/yolov4_tiny/yolo_v4_tiny
(base) $ pwd
# /home/shino/sandbox_tao_tutorial/yolov4_tiny/yolo_v4_tiny

### モデルがエクスポートされたディレクトリの内容を確認する
(base) $ ls -al ./export
# drwxrwxr-x  2 shino shino      4096  2月 10 15:32 .
# drwxrwxr-x 10 shino shino      4096  2月 10 15:12 ..
# -rw-r--r--  1 root  root       4746  2月 10 15:21 cal.bin
# -rw-r--r--  1 root  root  311869608  2月 10 15:20 cal.tensorfile
# -rw-r--r--  1 root  root         23  2月 10 15:12 labels.txt
# -rw-r--r--  1 root  root        193  2月 10 15:12 nvinfer_config.txt
# -rw-r--r--  1 root  root        795  2月 10 15:32 status.json
# -rw-r--r--  1 root  root   31962692  2月 10 15:14 trt.engine
# -rw-r--r--  1 root  root   13713724  2月 10 15:20 trt.engine.fp16
# -rw-r--r--  1 root  root    8707356  2月 10 15:32 trt.engine.int8
# -rw-r--r--  1 root  root   23706382  2月 10 15:12 yolov4_cspdarknet_tiny_epoch_080.onnx
```

#### ONNX形式のAIモデルの内容をNetronで確認する

生成されたONNX形式のネットワークは、Netronで開くことができます。YOLOv4-tinyは単純な深いネットワークですが、実際に開いてみると、 **プルーニングによりかなり複雑なネットワーク構造となっていることを確認できます。複雑なネットワーク構成となっているのは、枝刈りの影響でネットワークの分流が発生しているためです。**

https://netron.app/

![スクリーンショット 2025-02-11 141137.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/d1ac9c28-e53a-ba70-1ece-f140c6ee14af.png)

![スクリーンショット 2025-02-11 141203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/e8c9c937-8cb7-55d7-b675-e3eb5e3ccbc0.png)

### エクスポートしたTensorRT形式のAIモデルで推論を評価する

最後に、エクスポートしたTensorRT形式のAIモデルを利用し、推論できることを確認してみましょう。 **`trt.engine` を引数に指定した `tao deploy yolo_v4_tiny inference` を実行** することにより、デプロイ後のAIモデルを使って推論することができます。

![スクリーンショット 2025-02-10 161621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/23b04015-ae54-3095-371d-bb2eecc71b6f.png)

以下のように、 **自動車と人物を検出できるAIモデルを得ることができました！**

![000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/f3c9a4d9-8cf5-9286-5913-d9c2eb637d8a.png)

----

以上のように、NVIDIA TAO Toolkitを使うことにより、AIモデルを開発するフローをひとつずつ理解し、体系立ててAIモデルの開発手順を学ぶことができます。 **AIモデルの取得から、学習、最適化、プルーニング、量子化までをひとつのスクリプトで扱っている例はネットを探してもほとんど見つけられない** ため、是非一度NVIDIA TAO Toolkitをお試しください！ 

https://www.tensorflow.org/tutorials/images/transfer_learning?hl=ja

https://www.tensorflow.org/model_optimization/guide/pruning?hl=ja

https://www.tensorflow.org/lite/performance/post_training_quantization?hl=ja

https://www.isus.jp/wp-content/uploads/openvino/2024/docs/openvino-workflow/model-optimization-guide/compressing-models-during-training/quantization-aware-training-tensorflow.html

----

**ここまで読んでNVIDIA TAO Toolkitをセットアップしてみたくなった方は以下の記事をご参照ください。ある程度のメモリとGPUを搭載したLinuxマシンがあれば、ローカルPCを使って無料で試すことができます。**

https://qiita.com/xtrizeShino/private/2de2c6b139fa8d7cfcaf



----

## NVIDIA TAO Toolkitでclassification(tf2)を開発する

次に **`yolo_v4_tiny`** の対比として、
NVIDIA TAO Toolkitで **`classfication(tf2)`** を開発する手順を掲載します。

----

### 開発の前準備を行う

まず、NVIDIA TAO Toolkit全体向けの作業用ディレクトリを作成します。

```bash
mkdir -p ~/sandbox_tao_tutorial/
```

次に、NVIDIA TAO Toolkit起動用のPythonの仮想環境をActivateします。

```bash
(base) $ conda activate launcher
(launcher) $ cd ~
(launcher) $ cd tao_tutorials/
(launcher) $ jupyter notebook --ip 0.0.0.0 --port 8888 --allow-root
```

### 開発に利用するスクリプトを開く

今回開発するclassification(tf2)の開発用スクリプトは **`notebooks` `tao_launcher_starter_kit` `classification_tf2` `tao_voc` `classification.ipynb`** に格納されています。

![スクリーンショット 2025-02-11 124250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/1a51bba6-aaaa-d6d1-57af-2e0abae1a565.png)

![スクリーンショット 2025-02-11 124300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/02021ae0-e5ea-6ac8-c233-268a433e5b20.png)

![スクリーンショット 2025-02-11 124314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/8d8695e1-4c35-09da-e9e8-052bdf44cde3.png)

![スクリーンショット 2025-02-11 124326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/93f86cba-9b9b-93f0-5f0c-e01f2e95f58d.png)

![スクリーンショット 2025-02-11 124338.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/8c51eacb-c907-b693-4afb-afe53c0108e8.png)

### NVIDIA TAO x classfication(tf2) の notebook

**`classification(tf2)`** のnotebookは下記のようになっています。

![スクリーンショット 2025-02-11 124412.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/5d1e44d2-b677-d5ca-a37f-2c350f19cc6d.png)

開発時に利用するコマンドや引数は、下記のサイトにまとめられています。

https://docs.nvidia.com/tao/tao-toolkit/text/cv_finetuning/tensorflow_2/image_classification_tf2.html

### 開発環境の設定を行う

開発用のディレクトリを作成し、その絶対パスを、スクリプトへ記入します。

```bash
(base) $ cd sandbox_tao_tutorial/
(base) $ ls
# tao_ssd  yolov4_tiny

(base) $ mkdir classification_tf2
(base) $ cd classification_tf2
(base) $ pwd
# /home/shino/sandbox_tao_tutorial/classification_tf2
```

**`LOCAL_PROJECT_DIR` がローカルPC上の開発用ディレクトリへのパスです。** その他の **`/workspace`** から始まるパスは、開発用のDockerコンテナの内部のディレクトリ構成を決めるパスです。これらのディレクトリは実行時に自動的に生成されますので、特に設定する必要はありません。

![スクリーンショット 2025-02-11 125238.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/cf359226-ad9f-ffdd-7940-0376fd6b2020.png)

mountスクリプトを開き、開発用のディレクトリが指定されていることを確認します。

![スクリーンショット 2025-02-11 125527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/d283923b-8853-d1c3-0e12-90b4cf1e2725.png)

NVIDIA TAO Toolkitのパッケージを、ビルド環境にインストールします。

![スクリーンショット 2025-02-11 125738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/add73598-64d4-6ea8-2577-fd352fac75d7.png)

### 転移学習に利用するデータセットをダウンロードする

転移学習に利用するデータセットのURLをコピーし、`LOCAL_PROJECT_DIR` 内に `data` ディレクトリを作成し、`wget` コマンドを使ってデータセットをダウンロードします。

![スクリーンショット 2025-02-11 125809.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/7b1a46c6-d9c8-f9bf-7c80-087ce2ce37ed.png)

```bash
# 作業ディレクトリ内にdataディレクトリを作成する
(base) $ pwd
# /home/shino/sandbox_tao_tutorial/classification_tf2
(base) $ mkdir data

# dataディレクトリ内に学習用データセットをダウンロードする
(base) $ cd data
(base) $ wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
```

ダウンロード後、スクリプトを実行し、展開すると下記のディレクトリが作られます。

![スクリーンショット 2025-02-11 133432.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/30d1125d-745d-f5d4-8feb-ca5b04ba10d7.png)

### 学習済みAIモデルを取得する

続いて、学習済みAIモデルを取得します。 **が、提供されている「classification(tf2)」の開発用スクリプトは、何故か `ngc registry model list` と `ngc registry model download-version` がコメントアウトされており、AIモデルが自動的にダウンロードされるようになっていません。** ここではAIモデルをダウンロードして利用したいため、 <font color="red">**これらのコメントアウトを解除し、コードを有効化した後に、コードブロックを実行し、モデルをダウンロードしてください。**</font>

![スクリーンショット 2025-02-11 133740.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/a14bdd73-527b-d4f8-ea77-f2a8fed3dc1e.png)

![スクリーンショット 2025-02-11 133754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/28bc20bd-c4bf-e2fd-e227-b092bc869654.png)

### 学習用のハイパーパラメータを設定する

<font color="blue">**提供されている「classification(tf2)」の開発用スクリプトが保持する学習用のハイパーパラメータでは、16GB RAMを持つGPU向けに、 `batch_size` と `batch_size_per_gpu` が大きな値となっています。**</font> 今回は、RTX3060Ti 8GBモデルでAIの学習を実行するため、設定されている `batch_size` と `batch_size_per_gpu` を変更し、 **1回に処理するデータ量を絞り、GPUのメモリが溢れないように調整しました。**

https://docs.nvidia.com/tao/tao-toolkit/text/cv_finetuning/tensorflow_2/image_classification_tf2.html

![スクリーンショット 2025-02-11 134321.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/8dddc172-7fee-577f-2502-7008459180fb.png)

```python
!mkdir -p $LOCAL_EXPERIMENT_DIR/output
!sed -i "s|RESULTSDIR|$USER_EXPERIMENT_DIR/output|g" $LOCAL_SPECS_DIR/spec.yaml
### 以下を追加
# GPU毎のバッチサイズと、合計バッチサイズを調整する
!sed -i "s|batch_size_per_gpu: 64|batch_size_per_gpu: 16|g" $LOCAL_SPECS_DIR/spec.yaml
!sed -i "s|batch_size: 256|batch_size: 64|g" $LOCAL_SPECS_DIR/spec.yaml
# 更新された設定スクリプトを表示する
!cat $LOCAL_SPECS_DIR/spec.yaml
```

ハイパーパラメータが変更されていることを確認してください。

![スクリーンショット 2025-02-11 134456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/20b6aae0-d304-0640-aefd-1a67eafbfcea.png)

### TAOによるAIモデルの転移学習を実行する

また、今回のAI学習環境は、RTX3060Tiを2基搭載していますので **`num_gpus=2` を指定し、学習に複数のGPUが利用されるよう設定しました。指定した後にスクリプトを実行し、学習を開始します。**

![スクリーンショット 2025-02-11 140038.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/4ae9a75d-e357-14b8-0497-81e2ce51b023.png)

学習を開始した後、Jupyter Notebookを実行しているプロンプトとは別のプロンプトを開き **`nvidia-smi` を実行し、GPUのメモリが十分に利用されており、GPUのメモリが溢れそうになっていないかを確認しておきましょう。**

![スクリーンショット 2025-02-11 140303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/1fd32545-bf99-e974-0816-b2278a4b6cc4.png)

80epochsの学習が完了すると、結果が表示されます。

![スクリーンショット 2025-02-11 152727.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/45ccc4fb-c731-fcfd-3455-7343f2432ee3.png)

### 学習結果を確認する

評価用のスクリプトを生成します。

![スクリーンショット 2025-02-11 152959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/e9d93f87-4db4-3c5a-0cf7-5d5f8e6f23b9.png)

**`tao model * evaluate`** コマンドにより評価を実行すると、精度が出力されます。

![スクリーンショット 2025-02-11 153345.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/eccc9095-6144-5039-4249-250c0ad1abde.png)

### プルーニングによる最適化を行い、その後再度学習を実行する

続いて、プルーニング（枝刈り）を行います。

![スクリーンショット 2025-02-11 153907.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/565e5cce-10a2-6155-ac62-c71e0fd0642b.png)

プルーニング後に実行する再学習で利用するハイパーパラメータも、上記の学習時と同様、RTX3060Ti 8GB向けのサイズに調整します。

```python
!mkdir -p $LOCAL_EXPERIMENT_DIR/output_retrain
!sed -i "s|RESULTSDIR|$USER_EXPERIMENT_DIR/output_retrain|g" $LOCAL_SPECS_DIR/spec_retrain.yaml
!sed -i "s|PRUNEDMODEL|$USER_EXPERIMENT_DIR/output/prune/model_th=0.68_eq=union.tlt|g" $LOCAL_SPECS_DIR/spec_retrain.yaml
### 以下を追加
# GPU毎のバッチサイズと、合計バッチサイズを調整する
!sed -i "s|batch_size_per_gpu: 64|batch_size_per_gpu: 16|g" $LOCAL_SPECS_DIR/spec.yaml
!sed -i "s|batch_size: 256|batch_size: 64|g" $LOCAL_SPECS_DIR/spec.yaml
# 更新した設定スクリプトを表示する
!cat $LOCAL_SPECS_DIR/spec_retrain.yaml
```

**`tao model * train`** を再度実行し、プルーニング後の再学習を行います。

![スクリーンショット 2025-02-11 154324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/0bcc204a-2823-fc00-eda9-dcdf523faf59.png)

#### Quantization Aware Training（QAT）向けのコードブロック

TensorFlowは、Model Optimization Toolkitとして **「Quantization Aware Training（QAT）API」** を提供しています。 **QATは、ニューラルネットワークの学習中に低精度のハードウェアをシミュレートし、全体的なネットワーク損失メトリックに量子化誤差を最小化する機能** です。NVIDIA TAO ToolkitからQATを利用するにはQATに関するコードブロックを実行してください（ <font color="blue">**今回の手順では、QATの実行を省略します**</font> ）。

https://www.infoq.com/jp/news/2020/11/google-tensorflow-optimization/

https://www.isus.jp/wp-content/uploads/openvino/2024/docs/openvino-workflow/model-optimization-guide/compressing-models-during-training/quantization-aware-training-tensorflow.html

![スクリーンショット 2025-02-11 170318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/c65826a7-7e6c-4632-c1b1-5672e4e2a489.png)

### モデルを評価する

学習によって得られたモデルを **`tao model * evaluate`** により評価します。

![スクリーンショット 2025-02-11 171943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/359f08c3-d774-7267-addb-3064927d3c6d.png)

### 生成できたAIモデルをエクスポートする

最後に生成したAIモデルをエクスポートしましょう。 **`tao model * export` コマンドにより、ONNX形式としてAIモデルをエクスポートすることができます。** エクスポート時に指定できるパラメータについては下記のサイトをご参照ください。

https://docs.nvidia.com/tao/tao-toolkit/text/tao_deploy/classification_tf2.html

![スクリーンショット 2025-02-11 172428.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/b908fe33-46d6-c4a2-84d4-00924798d818.png)

エクスポートされたONNX形式のAIモデルは、Netronにより可視化できます。

https://netron.app/

![スクリーンショット 2025-02-11 172744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/12598669-f979-5f80-c47c-6583fd482a28.png)

### エクスポートしたAIモデルにより推論できることを確認する

最後に、エクスポートしたAIモデルを指定した **`tao deploy * inference`** コマンドにより推論できることを確認しましょう。

![スクリーンショット 2025-02-11 173437.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919880/bc5724c1-678e-cb3a-8dda-acd84212d599.png)

----

以上が **`classfication(tf2)`** の開発の流れです。
**`yolo_v4_tiny`** とほぼ同じ手順で開発できることがわかります。

このようにNVIDIA TAO Toolkitを使うことで、様々なネットワークを体系立てて、転移学習、プルーニング、量子化といった流れをスムーズに実行することができます。

**是非ご活用ください！**

----