Transformers Object detection - detr の転移学習とONNX変換と実行。
---- 雑草の独自データの転移学習とONNXでの変換、実行を試す ----
Transformers Object detection
1. 最初に、オリジナルの転移学習を試す。
次に、雑草画像の独自データを用意して、YOLO アノテーションを作成して、それを、COCO 形式に変換して、
雑草画像の転移学習を、試してみた。
開発環境
Ubuntu Mate 22.04
GPU: GeForce GTX 1070
Python 3.10
virtualenv
checkpoint = "facebook/detr-resnet-50"
が、転移学習のベースモデルみたい。
huggingface.co/facebook/detr-resnet-50
num_train_epochs=30
位必要みたい。
一応、オリジナル版の転移学習は、OK でした。
2. DETR to ONNX
学習が終わったら、ONNX に変換できるみたい。
Export to ONNX
これは、後で、書きます。
3. 雑草 YOLO データセットを、COCO に変換したら、転移学習をできるか、試してみた。
Convert YOLO annotations to COCO/Pascal VOC
独自データセットを用意するには。
Create a dataset
image_dataset#loading-script
object_detection
folder/train/zasou/0001.jpg
folder/test/zasou/0001.jpg
形式で、画像データを保存する。
Object detection は、
Object detection datasets have bounding boxes and categories identifying objects in an image. An example metadata.jsonl may look like:
metadata.jsonl ファイルを用意するみたい。
zasou_train.ipynb で転移学習させる。
zasou_Inference.ipynb で、結果を検証する。
一連の作業は、
tosa-no-onchan/transform_object_detection に書いています。
4. 感想?
オリジナルの学習データだと、30 エポックほどの学習でOK だが、自分で用意した、
雑草のデータだと、160 エポックほど学習させても、inference で検出できない。
最終的に、400 エポック 学習させて良くなった。
Training Loss: 0.2118
transformer のライブラリー関連を、少し使ってみたが、どうも、これは使いづらい。
すべてが、ライブラリーの中で、公開はされているが、多重継承でラッパーされていて、見通しが悪い。
もう少し手作業で組み込む形が解りやすい。
Keras のサンプルのほうが、よっぽど良い。と、おんちゃんは思う。
今公開されている学習済モデルを、そのまま使うには便利だ。
facebook/detr-resnet-50 の中に、入力データの変換形式や、ラベル情報がすべて入っているので、
ダウンロードさえすれば、すぐ使える。
これが、良いのかどうかは、使う側の考えか。
5. 注意点。
独自学習データのクラスName の変更。
オリジナルデータから、雑草データに変えたので、その場合の、 class name の指定に苦労したので、メモしておきます。
datsets.Features を、別途指定しないといかん。
先に、オリジナルの情報を確認します。
'category': ClassLabel(names=['Coverall', 'Face_Shield', 'Gloves', 'Goggles', 'Mask'], id=None) を、
'category': ClassLabel(names=['zasou'], id=None) にする。
ds = load_dataset("imagefolder", data_dir="datasets", features=my_features)
で、独自データ・セットのロード時に、features=my_features を適用する。
注) ただし、学習には、別に必要がないのだが。
6. 学習済モデルを公開したので、zasou_Inference.ipynb で、検証できる。
zasou_Inference.ipynb
zasou_Inference_cam.py
一応、雑草が検出できるようになった。すごい!!
注) pipeline() を使うと、遅い。8[fps] 位ぞね。
./datasets/train/zasou の下に、雑草画像を、google からダウンロードしておいてください。
雑草画像ダウンロード
7. pipeline() , image_processor() を使わない検出スクリプト。
Facebook による検出トランスフォーマー (DETR) を使用したオブジェクト検出 を参考に、
pipeline() , image_processor() を使うと遅いので、これを使わない script も作成しました。
torch + cuda だと、26[fps] 位のスピードでした。
zasou_Inference3_cam.py
check_point="tosa-no-onchan/detr-resnet-50_finetuned_zasou"
で試してください。
github に公開しました。
tosa-no-onchan/transform_object_detection
しかし、Transformers DETR は、 SBC 上で実行できるのだろうか?
これが、今の心配事じゃ。
おんちゃんの目的は、草刈りロボットに組み込んで、雑草を刈り取ることじゃが。
8.
Export to ONNX
Transformers DETR を、ONNX への変換ができそうだが?
$ python -m pip install optimum[exporters]
$ optimum-cli export onnx --model tosa-no-onchan/detr-resnet-50_finetuned_zasou onnx/
ローカルの ./onnx に作成された。
onnxruntime で、 ./onnx/model.onnx をロードして、雑草の検出を試してみた。
一応、検出はできるみたい。しかし、
pred_logits,pred_boxes = sess.run([output_name, output_name_1], {input_name: x})
で、戻ってくる、pred_logits が、なんとなく変。
1 batch 100 個エントリーが帰ってきて、各行の、その中に、1 of K で、一番大きいカラムが、class_id+1 に該当するがようだが、
1.0 / pred_logits[0][0..99][class_id] が、score になるみたいだ?
どうして、そうなるのか?
参考になるコードがありました。
/home/nishi/torch_env/lib/python3.10/site-packages/transformers/models/detr/image_processing_detr.py
post_process()
prob = torch.functional.softmax(out_logits, -1)
scores, labels = prob[..., :-1].max(-1)
torch では、上の、2行を使えば、OKだが、onnx の場合は?
onnx 版は、下記で代用しました。
scores, labels =prob[..., :-1].max(-1), prob[..., :-1].argmax(-1)
と、
scores, labels =prob.max(-1), prob.argmax(-1)
とで、結果が違うみたい。
下記で、違いを検証してみた。
結果は、
scores, labels =prob[..., :-1].max(-1), prob[..., :-1].argmax(-1)
では、各 logitsの最後は、つかわないみたい。
各 logitsの最終columnは、unknown クラスの accuracy なので、対象から外す必要があるみたい。
max(-1)、 argmax(-1) は、max(axis=-1)、 argmax(axis=-1)の事で、各行の最終軸に対して、オペレーションを実行して、
結果を1つ上の軸に、リストで返すみたいじゃ。
検証してみた。
後、model に渡す入力画像は、0 - 255 を 0 - 1.0 にノーマライズしないと行けないみたい。
torch だと、torchvision.transforms.ToTensor() を通すだけで、OKみたい。
onnx版では、下記で代用しました。
上記、2件の対応で、なんとか、onnx 版も実行できるようになりました。
onnx_inference_cam.py
onnxruntime + cpu USB-Cam 640x480 サイズで、4 [fps] 位のスピードでした。
モニターに表示した、雑草画像を、USB Camera で映して、検出はできるようです。
実際の雑草で試してみないといかんぞね。
9. Export to TFLite
TensorFlow Lite へ変換できそう。-- 結果は、NG!!
今回は、virtualenv で、別の環境下で、行います。
$ cd
$ python3 -m virtualenv optimum_env
$ source ./optimum_env/bin/activate
(optimum_env)$ python -m pip install optimum
(optimum_env)$ python -m pip install optimum[exporters-tf]
tensorflow-2.12.1 が入るみたい。
注) Supported architectures には、DETR が入っていないから、NG かも!!
10. 参照。
1) docs/transformers/model_doc/detr
2) transformers.AutoModelForObjectDetection
3) transformers.DetrForObjectDetection
4) train-rt-detr-custom-dataset-transformers
こちらにも、独自データの転移学習例があった。
しかしこちらは、warmup_steps=300 を指定している。
おんちゃんも、warmup_steps=500 で、一度試したが、これは、NG の気がする。
warmup_steps は、使わない方が良いと思う。
load_best_model_at_end=True
これは、使えそうだ。
5) facebookresearch/detr
Facebook による検出トランスフォーマー (DETR) を使用したオブジェクト検出
この検出プログラムは、学習後の、実行プログラムの作成の参考になります。