Jetson Nanoで学習済みモデルを使って、いろいろやってみる(3)ファインチューニング(MaskR-CNN)


NVIDIAのNGCにはセマンティック・セグメンテーションのよさげなチュートリアルがなかったので、Pytorchのチュートリアルを使ってみます。

TORCHVISION OBJECT DETECTION FINETUNING TUTORIAL
TorchVision オブジェクト検出 ファインチューニング チュートリアル

このチュートリアルでは、FasterR-CNNをベースにしたMaskR-CNNを使用します。 Faster R-CNNは、画像内の潜在的なオブジェクトのバウンディングボックスとクラススコアの両方を予測するモデルです。

こんな感じのことをやってみます。

New(追加しました)

チュートリアルの学習は少々重いです。

いつものように、学習はGoogle Colabを使い、推論の実行はColab Jetson Nano の2つでやってみます。

ここでは、学習したモデルを保存して再利用したかったのでチュートリアルとちょっと異なる点があります。ご了承ください

目次

1.学習用の環境をJetson Nanoで作成してGoogle Drive にアップロード

2.Google Colab で学習をして、モデルデータを保存

3.Colabで新規Notebookを作成し、モデルをロードして推論実行

4.Jetson Nano に推論実行環境を作成し、モデルをロードしてNoteBookで推論実行

以下の記述で、/home/jetson というユーザー名は適宜、ご自分の環境で置き換えてください。

 


1/4. 学習用の環境をJetson Nanoで作成してGoogle Drive にアップロード

使用するJetson Nano は4GBモデルで、OS image はJetpack(4.4.1)です。

Jetsonのセットアップなどはこちらのページをご参照ください。

work-maskrcnn という名前で新規にディレクトリを作成

データセットをダウンロードして、解凍しておきます。

モジュールを追加しておきます。

終了後、不要ファイル削除

 

ブラウザーでGoogle Driveにアクセスして、work-maskrcnnをアップロード

work-maskrcnnフォルダーはColabの学習で使います。

 

 


2/4. Google Colab で学習をして、モデルデータを保存

ブラウザーでGoogle Colabを開きます。

最初にNotebookを作成する際にGPUも使えるようにします。

ファイルー>ノートブックを新規作成

ランタイムをクリックー>ランタイムのタイプを変更

GPUを選んで保存します。

ファイルのアイコンをクリック

事前にGoogleドライブにアップしておいた環境(work-maskrcnn)が使えるようにドライブをマウントします。

マウントするとドライブが表示されるので、カレントディレクトリを変更します。

ライブラリやモジュールが使えるかチェックしておきます。

データセットのtorch.utils.data.Datasetクラスを作成しましょう。

There are two common situations where one might want to modify one of the available models in torchvision modelzoo. The first is when we want to start from a pre-trained model, and just finetune the last layer. The other is when we want to replace the backbone of the model with a different one (for faster predictions, for example).
torchvision modelzoo で利用可能なモデルを修正したい場合、2つの一般的なシチュエーションがあります。1つ目は、事前に訓練されたモデルから始めて、最後のレイヤーを微調整(finetune)する場合です。もう一つは、(例えば、より高速な予測のために)モデルのバックボーンを別のものに置き換えたい場合です 。

Let’s go see how we would do one or another in the following sections.
どのように行うかを見てみましょう。
1.Finetuning from a pretrained model

事前トレーニング済みモデルからのファインチューニング

COCOで事前にトレーニングされたモデルから始めて、特定のクラスに合わせてファインチューニングします。

注:今回はこのモデルを使います。

 

2.Modifying the model to add a different backbone

モデルを変更して別のバックボーンを追加する

別の一般的なシチュエーションとしては、ユーザーが検出モデルのバックボーンを別のバックボーンに置き換えたい場合に発生します。 たとえば、現在のデフォルトのバックボーン(ResNet-50)は、一部のアプリケーションには大きすぎる可能性があり、より小さなモデルが必要になる場合があります。

これが、トーチビジョンによって提供される機能を活用してバックボーンを変更する方法です。

注:下記の理由によりこのモデルは使いません。

 

An Instance segmentation model for PennFudan Dataset 
PennFudanデータセットのインスタンスセグメンテーションモデル

In our case, we want to fine-tune from a pre-trained model, given that our dataset is very small, so we will be following approach number 1.

Here we want to also compute the instance segmentation masks, so we will be using Mask R-CNN:

PennFudan Datasetの例では、データセットが非常に小さいため、事前にトレーニングされたモデルから微調整(fine-tune)する必要があるため、1のFinetuning from a pretrained modelに従います

ここでは、インスタンスのセグメンテーションマスクも計算するため、MaskR-CNNを使用します。

 

Putting everything together
すべてをまとめる

In references/detection/, we have a number of helper functions to simplify training and evaluating detection models. Here, we will use references/detection/engine.py, references/detection/utils.py and references/detection/transforms.py. Just copy them to your folder and use them here.
references/detectionフォルダーには、検出モデルのトレーニングと評価を簡素化するための多数のヘルパー関数があります。 ここでは、references / detection / engine.py、references / detection / utils.py、references / detection /transforms.pyを使用します。 それらをフォルダにコピーして、ここで使用するだけです。

注:1/4でこれら3つのPythonコードはGoogle Driveにセットされ、このセクションの最初にモジュールとして読み込まれています。

 

Testing forward() method (Optional)
forward()メソッドのテスト(オプション)

Before iterating over the dataset, it’s good to see what the model expects during training and inference time on sample data.
データセットを反復処理する前に、サンプルデータのトレーニングおよび推論時間中にモデルが何を期待するかを確認することをお勧めします。

トレーニングと検証を実行します。

注:チュートリアルでは以下はmain関数として記述されていますが、ここではべた書きしています。

10エポックのモデルをトレーニングしましょう。

トレーニングが終了したらモデルをpickle化して保存しておきます。

注:pickleを使った方法は簡単ですが推奨されていません。推奨された方法としてはstate_dictを使います。

Appendixをご参照ください。

 

 

 


3/4. Colabで新規Notebookを作成し、モデルをロードして推論実行

2でやったようにColabに推論用のGPU対応の新規Notebookを作成して、Google Driveにマウントしておきます。

で、以下を実行

ライブラリを読み込み

データセットのtorch.utils.data.Datasetクラスを作成しましょう。

テスト用画像を準備

学習で作成したモデルを読み込みます。

テスト用画像の数

img_countより小さい番号を指定して予測用画像を準備

推論実行

予測(prediction)の結果は、辞書のリストになっていてboxes、labels、masks、score が含まれています。

 

使用した画像を確認

画像の中のセグメーテーションの数をmasksかboxesの配列数で調べます。

Nより小さい番号を指定してセグメンテーション表示

 

 


4/4. Jetson Nano に推論実行環境を作成し、モデルをロードしてNoteBookで推論実行

使用するJetson Nano は4GBモデルで、OS image はJetpack(4.4.1)です。

SWAP領域も2GB以上確保しておく必要があります。

JetsonのセットアップやSwap設定などはこちらのページをご参照ください。

Google Driveにアクセスして保存しておいた学習モデルをダウンロードしておきます。

ダウンロードしたファイル(tutorial_model.pkl)は/home/jetson/work-maskrcnnに移動しておきます。

 

NVIDIAのイメージを使ってコンテナを作成します。

以下のセットアップが面倒な方向けにイメージを用意しました。
これでコンテナを作成すれば、後はJupyterNotebookを起動するだけです。
よろしければお使いください。
Appendix2

 

my_maskrcnnという名前でコンテナを作成

sudo docker create -it --name my_maskrcnn --gpus all --network host -v /home/jetson/work-maskrcnn:/work nvcr.io/nvidia/l4t-pytorch:r32.4.4-pth1.6-py3

コンテナ起動

アップデート&アップグレード

ライブラリを追加インストール

 

torchとtorchvisionのデフォルトでインストールされているバージョン(1.6.0と0.7.0)だとpickle化されたモデルの読み込みで失敗します。コンテナのPytorchとTorchvisionのバージョンを上げておきます(1.7.0と0.8.1)。

注:モデルの保存・読み込みにstate_dictを使った場合はこのバージョンアップは不要です。Appendix参照

まずは、削除

再インストール

Pytorch

Torchvision(だいたい30分くらいかかります、コーヒータイムです)

jupyterlabをインストールしておきます。

 

マウントしておいたworkフォルダーへ移動して、Jupyter Notebook を起動

token付きでURLが表示されますので、コピーして外部ブラウザーからNotebookを開きます。

 

 

推論実行は3/4で行ったライブラリ読み込み以降と手順は同じです。

Jetson Nanoの場合、モデルの読み込みと推論モードでの実行に少々時間がかかります。

TensorRTを使うことも検討する必要あり?

また、メモリも不足気味になっています。このページでやったようにデスクトップではなくCUI環境を使い、NotebookではなくPythonコンソールで実行することを考慮してもいいかもしれません。

 

 


 

追加

こんな感じで、セグメンテーションマスクをまとめて表示してみます。

OpenCVを使ってみます。ただ、今回使ったDockerイメージにはOpenCVは実装されていません。

OpenCVの実装などはこのページをご参照ください。

以下のコード参照

Image.fromarray(img.mul(255).permute(1, 2, 0).byte().numpy())

CV用に元画像イメージ作成

image_org = img.mul(255).permute(1, 2, 0).byte().numpy()

opencvをインポートして、CV用にRGB変換。

maskの輪郭を、太さ1の青線でアンチエイリアス(AA)で元画像に描き込みます。

保存

 

 


Appendix

state_dictを使ったモデルの保存と読み込み

1.学習済みモデルを保存する

保存コードは簡単です。

 

2.モデルを読み込んで推論実行

読み込む前にmodel を定義しておく必要があります。

コード全体はこんな感じです。pickle版と比較してみてください。

今回は「Save on GPU, Load on GPU」なので以下のようになっています。

画像として保存する場合

保存

 


Appendix2

Docker Hub に wisteriahill/my-nvidia:latest というイメージをpush しています。

このイメージはNVIDIAのnvcr.io/nvidia/l4t-pytorch:r32.4.4-pth1.6-py3をベースにして
Pytorch(1.7.0)とTorchvision(0.8.1)、Jupyterlab(3.0.8)、pandas(1.1.5)がセットアップされたものです。

これをpullしておきます。

 

これを使ってmy_maskrcnnという名前でコンテナを作成します。

sudo docker create -it --name my_maskrcnn --gpus all --network host -v /home/jetson/work-maskrcnn:/work wisteriahill/my-nvidia:latest

コンテナ起動

 

以降はworkに移動してJupyterを起動するだけです。

戻る


 

Be the first to comment

Leave a Reply

Your email address will not be published.


*