LoginSignup
1
1

More than 1 year has passed since last update.

Tensorflow.jsを使ってブラウザで任意の物体検出がしたい2022【Tensorflow2.9.1でSavedModel作成編】

Last updated at Posted at 2022-07-27

はじめに

Tensorflow.jsを使って、ブラウザで任意の物体検出がしたい!
見事大ハマリしたので、同じエラーで苦しんでいる人を解決方向に導けたら。
後の自分への備忘録も兼ねて。

概要

Tensorflow.jsを使って最終的に有名巨大像(牛久大仏、鎌倉大仏、奈良大仏、高崎観音、自由の女神)をブラウザでリアルタイム検出するモデルを作成した。開発環境はMacBookPro, Anaconda。
その過程を2回に分けて記事にする。
大きくTensorflowのObject Detection APIを使ってモデルを学習する部分と、そのモデルをTensorflow.jsで使えるように変換、ブラウザで読み取れるようにする2ステップだ。
今回は前編の 【Tensorflow2.9.1でSavedModel作成編】 である。
スクリーンショット 2022-07-12 17.17.34.png

準備

tfrecord形式のアノテーションデータ

まず、画像に物体の位置情報を付与した自作アノテーションデータを用意する。
アノテーションデータを作るにはVoTTが簡単でおすすめ。元画像のサイズはバラバラでも問題ない。
使い方は割愛するが、以下の記事が参考になる。書き出し形式が色々あるのでtfrecord形式を選ぶこと。
指定したフォルダに、大量のJSONと共にtfrecordが入ったフォルダが書き出される。

Google Colaboratoryが使える環境

今回WindowsでGPUを使おうとしたところ上手くいかなかったので、Google Colaboratory(以下Google Colab)でGPUを使って学習をすることにした。クラウドなのでGoogle Colab自体はWindows/Macどちらも対応。Google DriveにGoogle Colab用のフォルダを作っておく。
Google Colaboratoryの使い方はこちらがおすすめ。

手順

0. Google Colaboratoryのファイルをダウンロード

Google Colaboratoryのファイルを作ったのでこちらを元に進めていく。
(以下のGithubには手順を進めやすいようGoogle ColaboratoryのファイルであるTensorflow_ODA_2022.ipynbと、これから手順1で作成するTensorflow_ODA_DriveDirディレクトリのほぼ完成形を入れてある。)

1. Googleドライブ上フォルダを作成

Google Colaboratoryでは自分のGoogleドライブをマウントして中のファイルを読み込める。
そのためまずは、先程作ったアノテーションデータなどの読み取るデータと、後で出力するモデルデータを置くための基準となるフォルダをマイドライブ上に作成する。名前は任意だがTensorflow_ODA_DriveDirとしておく。
フォルダ構造は以下の通り。

Tensorflow_ODA_DriveDir
├── model
│   └── ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
├── tfrecord
│   ├── train
│   │   ├── 000000.tfrecord
│   │   └── …
│   └── val
│       ├── 000000.tfrecord
│       └── …
├── trained
├── tf_label_map.pbtxt
└── pipeline.config

Tensorflow_ODA_DriveDir内を解説する。

  • model
    転移学習に使うモデルを入れるフォルダ。
    転移学習とは既にあるモデルを流用することで学習の精度や速度を早める学習のさせ方。
    以下からダウンロードする。
    TensorFlow 2 Detection Model Zoo
    モデルは色々あるのだが、今回はSSD MobileNet V2 FPNLite 640x640を使う。
ここでの大ハマリ(クリックで展開)
  1. モデルがダウンロードできない
    そんなまさかと思うが、最初モデルが全くダウンロードできなかった。
    何度も、どんなやり方でダウンロードしても、tar.gzが壊れる。
    しかも、いくら調べても有力な手がかりが得られず。
    途方に暮れていたところ、会社のセキュリティにブロックされていたことが発覚。
    家のWi-Fiでするっとダウンロードできて涙ちょちょぎれ。。。

  2. EfficientDetを選択
    EfficientDetは優秀なモデルだがここでは選んではいけない。
    後編で使うTensorflow.jsはEfficientDetに対応しておらず、ブラウザで読み取る段階でエラーが出てしまう。
    これも原因がなかなか分からず苦労させられた。

  • tfrecord - train / val
    アノテーションデータ(tfrecord)を入れるフォルダ。
    trainに学習用、valに検証用のデータを入れる。
    大体 train : val = 7 : 3 くらいになるようtfrecordを分割して入れる。

  • trained
    学習後のチェックポイントデータを保存するフォルダ。今は空。(gitで管理するため.gitkeepは入れてある。)

  • tf_label_map.pbtxt
    アノテーションしたときのタグの名前やIDが書いてあるファイル。
    tfrecordを生成した場所に一緒に生成されているのでTensorflow_ODA_DriveDir直下にそのまま入れる。

  • pipeline.config
    学習に使う設定ファイル。
    ダウンロードしたssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8に入っているpipeline.configを書き直してTensorflow_ODA_DriveDir直下に保存する。
    以下書き直す箇所。

◎ 3行目
アノテーションのタグ種類数、この記事の場合は5。

pipeline.config
- num_classes: 90
+ num_classes: 認識させたい物体の種類数

◎ 135行目
余裕がありそうなら16くらいでも良いが、自分の場合メモリ足りないエラーが出たので8に減らした。

pipeline.config
- batch_size: 128
+ batch_size: 8

◎ 165行目
転移学習に使うモデルのチェックポイントのパス。

pipeline.config
- fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED"
+ fine_tune_checkpoint: "/content/drive/MyDrive/Tensorflow_ODA_DriveDir/model/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0"

◎ 171行目
画像認識から物体検出モードに。

pipeline.config
- fine_tune_checkpoint_type: "classification"
+ fine_tune_checkpoint_type: "detection"

◎ 175, 185行目
tf_label_map.pbtxtのパス。

pipeline.config
- label_map_path: "PATH_TO_BE_CONFIGURED"
+ label_map_path: "/content/drive/MyDrive/Tensorflow_ODA_DriveDir/tfrecord/tf_label_map.pbtxt"

◎ 177行目
学習用tfrecordの場所。?はワイルドカードで、??????.tfrecordとすることですべての数字6桁.tfrecordファイルを読み込める。

pipeline.config
- input_path: "PATH_TO_BE_CONFIGURED"
+ input_path: "/content/drive/MyDrive/Tensorflow_ODA_DriveDir/tfrecord/train/??????.tfrecord"

◎ 189行目
検証用tfrecordの場所。?は上と同じ。

pipeline.config
- input_path: "PATH_TO_BE_CONFIGURED"
+ input_path: "/content/drive/MyDrive/Tensorflow_ODA_DriveDir/tfrecord/val/??????.tfrecord"

長くなってしまったが、これで基準となるフォルダは完成した。

2. Google Colaboratory上で学習

学習の流れはColaboratory上に書いたため、上記のフォルダを作成した後手順0.でダウンロードしたipynbを順に実行していけば無事にSavedModelが作成できると思う。
そこで、ここでは私がつまづいたポイントをメインに解説していく。
気になる人はGoogle Colaboratoryと見比べながら読んでほしい。

Protobufのバージョン

TensorflowではProtocol Buffers(以下Protobuf)というフォーマットが使われている。そのため、Protobufライブラリをダウンロードしてコンパイルする必要がある。
チュートリアルでは最新バージョンをダウンロードするよう指南されているが、最新バージョンをダウンロードすると途中model_builder_tf2_test.pyでインストールが上手く行ったか確認する際以下のようなエラーが出る。

ImportError: cannot import name 'builder' from 'google.protobuf.internal' (/usr/local/lib/python3.7/dist-packages/google/protobuf/internal/__init__.py)

これはObject Detection APIに必要なパッケージのインストールをsetup.pyでする際にv3.19.4のProtobufがインストールされてしまうため「先にコンパイルした最新のProtobuf」と「setup.pyでダウンロードされたv3.19.4のProtobuf」のバージョンの齟齬でエラーが発生している。そのため、今回は最初からv3.19.4をインストール・コンパイルすることで対処することにした。

Tensorflow2.9に合ったCuda, cuDNNのバージョン

恐らくここが1番のハマりポイントである。
Protobufと同じく、setup.pyを動かすとTensorflowの最新バージョン(2022年7月現在:2.9.1)が上書きインストールされてしまう。 そのまま学習に進むと、DNN library is not found.のエラーが発生する。
これはGPUを使うためのCuda、cuDNNのバージョンがTensorflow2.9と噛み合ってないため起こる。
CudaとcuDNNは既にGoogle Colaboratoryにインストールされているのだが、以下の表の通りcuDNNのバージョンがTensorflow2.9の動作条件に足りていない。

Cuda cuDNN
Google Colaboratory 11.1 8.05
Tensorflow2.9 11.0~11.7 8.1以上

Tensorflow2.7にバージョンを下げることでも動くようになるが、今回はCudaとcuDNNのバージョンを上げることでTensorflow2.9を使えるように対処することにした。

opencv-pythonのエラー

AttributeError: module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline'

という謎エラー。opencv-pythonをアップグレードすれば解決。

これらを解決するのにかなりの時間を費やしてしまった。

3. SavedModelの保存

学習を終えたらSavedModelを保存する。
Google Colaboratoryを全て実行すると、手順1.で作ったフォルダの中にoutputというフォルダが新たにできている。
その中のsaved_modelフォルダを次の記事で使うので、ローカルにダウンロードしておく。

ちなみにsaved_model自体はローカルアプリでならそのまま使える。

まとめ

Tensorflow.jsでブラウザを使う前に、TensorflowのObject Detection APIがかなりの曲者だった。
元々インストールしていたTensorflowが途中で最新版に塗り替えられていることに気づいた時は目眩がした。その後もGPU関連で首を絞められるような思いをしつつも、何とか自作モデルを完成させられたのでバンザイ!!!
次はWindowsデスクトップでGPU使って学習できるといいな…
後編もTensorflow.jsで血を吐きます。お楽しみに。

後編はこちら

参考記事・サイト

この他にも数多くの記事やサイトを参考にしましたが、主に参考にした代表的なものを以下に紹介します。
過去の知恵には頭が上がりません。

Google Colaboratoryのベース

まず最初に、この記事がなければGPUを使用しての学習は諦めていたと思います。
MITライセンスで配布されていたものをベースに今回のGoogle Colabファイルを作らせていただきました。
ライセンスにも記載しております。この場をもって感謝申し上げます。ありがとうございました。

【Tensorflow2 Object Detection API】オリジナルデータ学習ハンズオンのColab公開

Object Detection API全般

TensorFlow 2 Object Detection API tutorial
「Object Detection API」で物体検出の自前データを学習する方法(TensorFlow 2.x版)

Protobuf周り

ImportError: cannot import name 'builder' from 'google.protobuf.internal'

Tensorflow2.9 と Cuda, cuDNN周り

Trained failed when training SSD mobilenet on colab GPU
DNN library is not found ssd_mobile_net_v2 in Colab
TensorFlow 2.9.1 (GPU 対応可能)のインストール(Windows 上)
NVIDIA ドライバ,NVIDIA CUDA ツールキット 11.5,NVIDIA cuDNN 8 のインストール(Ubuntu 上)
NVIDIA CUDNN DOCUMENTATION
Index of /compute/cuda/repos/ubuntu2004/x86_64
Installing Tensorflow 2.9 with GPU Support
google colaboratory の cuda version, cudnn version

opencv-python周り

AttributeError: partially initialized module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline' (most likely due to a circular import)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1