スポンサーリンク

【TensorFlow Lite】Object Detection APIで作成の自作モデルをXcodeでビルドする手順ご紹介。

TensorFlow
スポンサーリンク

今回の記事は「Object detection API」で作成した自作モデルを「TensorFlow Lite」形式に変換し、Xcodeでbuildしてアプリに組み込む方法をご紹介します。初心者でも気軽にサンプルを動かせるように簡単に解説していきますので是非参考にして下さい。

スポンサーリンク

【TensorFlow Lite】Object Detection APIで作成の自作モデルをXcodeでビルドするまでの手順

流れとしては下記になります。

・TensorFlowとObject Detection APIの実行環境を構築
  DockerでTensorFlow、Object Detection API実行環境構築方法
・画像の整理(これは自身の好きな画像にする場合は適宜コード置き換えてください。)
  自身の物体検知させたい画像を選択してください。
・画像の水増し(必要な場合)
  画像の輝度調整、水平垂直移動方法
・アノテーション作業
  アノテーション作業とはアノテーション自動化
・転移学習
  転移学習方法TFRecord形式のデータを転移学習する方法
・TensorFlow学習グラフ(.pb)をTensorFlowLite形式(.tflite)に変換
  pbからtfliteへの変換方法
・googleテンプレートの指定箇所に自作モデルを置き換える
  Object Detection APIに自作学習モデルを入れ込む方法
・Xcodeにてbuild
  カメラ関連アプリの実機テスト方法

では実際に流れを説明していきます。

TensorFlowとObject Detection APIの実行環境を構築

Docker上で環境構築していきます。「jupyter notebook」もインストールする事でコンテナ内の操作がブラウザでできるので便利です。VScodeでも接続し、操作することができるのですか私のPCのスペック的にコンテナが停止してしまうのでメモリ調整等もいちいちめんどくさいですし「jupyter notebook」で接続でいきます。OSに依存しないのでMacでもWindowsでも作成可能となっております。コンテナのOSはUbuntuです。これでTensorflow環境構築は完了している状態まで持っていきます。

docker run -it -p 8888:8888 tensorflow/tensorflow /bin/bash

apt-get update
apt-get install git wget unzip protobuf-compiler python-pil python-lxml python-tk

pip install Cython contextlib2 pillow lxml jupyter notebook matplotlib tf_slim opencv-python

git clone https://github.com/tensorflow/models.git
git clone https://github.com/tensorflow/tensorflow.git

git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make
cp -r pycocotools /models/research/
pip install --user pycocotools

cd ../.. && cd models/research
protoc object_detection/protos/*.proto --python_out=.

wget -O protobuf.zip https://github.com/google/protobuf/releases/download/v3.0.0/protoc-3.0.0-linux-x86_64.zip
unzip protobuf.zip

./bin/protoc object_detection/protos/*.proto --python_out=.

export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
source ~/.bashrc

python object_detection/builders/model_builder_tf1_test.py
OK が出力

cd ../..
jupyter notebook --ip=0.0.0.0 --allow-root

jupyter notebbokが開ます

詳細な説明は上記のリンク記事でしておりますのでそちらを参考にして見てください。その場合ファイルを書くのが困難ですが、vimやVScodeを接続などでファイル内の編集を行ってください。

「Object Detection API」で使用する画像の準備

ここは好きな画像を設定してください。参考までに私は非常口を検出させてみたいと感じた(謎)ので非常口にフォーカスを絞って行っていきます。

「非常口」の文字を検出させる為に下記の操作を行っていきます。

「Object Detection API」で使用する画像の水増し

コードのみ貼り付けます。詳しくは過去記事を参照ください。

輝度調整

import tensorflow as tf
import tensorflow.image
import os
import glob
from PIL import Image
import numpy as np

img_dir = glob.glob('/exit/*.jpg')
#画像の読み込み

height = 300
width = 400
#画像のサイズを指定
i = 0
for name in img_dir:
    
    count = name.split(".")[0].split("/exit/exit")[1]
    #画像を保存する際に仕様している番号
    load_img = tf.read_file(name)
    #画像の読み込み
    img = tf.image.decode_jpeg(load_img, channels=3)
    #画像の調整
    for i in range(1,5):

        before_img = tf.image.adjust_brightness(img, delta=0.0625 + 0.0625*i)
        #画像の輝度を指定して変更する
        #before_img = tf.image.random_brightness(image,max_delta,seed=None)
        #ランダムに画像の輝度変更する

        with tf.Session() as sess:
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(coord=coord)
            img = sess.run(before_img)

            Image.fromarray(np.uint8(img)).save('/exit/brit/exit' + str(count) + '_' + str(i) + '.jpg')
        i = i + 1
            #画像の保存先を指定

水平垂直移動

from tensorflow.keras.preprocessing import image
import numpy as np
from PIL import Image
import glob

img_dir = glob.glob('/exit/*.jpg')
#img_dirに今回水増しする画像のリストを格納

def make_generator(num):#ImageDatageneratorの仕様作成関数
    global datagen
    if num == 0:
        #縦移動
        datagen = image.ImageDataGenerator(height_shift_range=0.5)
    elif num == 1:
        #横移動
        datagen = image.ImageDataGenerator(width_shift_range=0.3)
    elif num == 2:
        #回転
        datagen = image.ImageDataGenerator(rotation_range=20)

for make_number in range(3):
    for img_l in img_dir:
        img = image.load_img(img_l)
        img = np.array(img)
        
        make_generator(make_number)#ImageDatageneratorの仕様作成関数

        # ミニバッチを生成する Python ジェネレーターを作成する。
        x = img[np.newaxis]  #  (Height, Width, Channels)  -> (1, Height, Width, Channels) 
        gen = datagen.flow(x, batch_size=1)  # 1枚しかないので、ミニバッチ数は1

        for i in range(5):
            batches = next(gen)  # (NumBatches, Height, Width, Channels) の4次元データを返す。
            # 画像として表示するため、3次元データにし、float から uint8 にキャストする。
            gen_img = batches[0].astype(np.uint8)

            im = Image.fromarray(gen_img)
            #np.save('exit/generate_zurasu/exit' + str(i) + '.jpg',gen_img)

            im.save('exit/generate_zurasu/exit' + str(y) + '_' + str(i) + '.jpg')

それぞれフォルダのパス等を自身のものに合わせてもらえればそのまま使用できるかと思います。もしもimportできないモジュールがあればpip installしてください。

ちなみにここで記載するのもどうかと思うのですが今回のpython環境は仮想環境を作っていません。Docker環境を立てた段階で最終的にコンテナ管理を行う予定なのが理由です。もし、ローカル環境で行うのであればtensorflowとopencvは何かとバージョン問題があるので仮想環境を作ることをお勧めします。

アノテーションによる「Object Detection API」の訓練データ作成

アノテーション作業自体は簡単でVottを使用して行います。操作方法等詳しくは過去記事をみてください。操作としては対象にひたすら「枠付」、「タグ付」、最後にTFRecord形式に変換です。
Vottの操作自体はワンタッチで大体おこなえるので便利ですが枚数が多ければしんどいので自動化も検討してみてください。私の過去記事で単一の物体検知に関しての自動化は行えていますので参考記事を下記に記載しておきます。

Vottの自動化記事はこちら

「Object Detection API」でTFRecordを既存モデルに転移学習

次に転移学習を行なっていきます。過去記事ではinception_v3での転移学習を行なっていますが今回はせっかくですのでmobilenet_v2での転移学習を行なっていきます。偉大なこの方のgitレポジトリをクローンします。

git clone https://github.com/karaage0703/object_detection_tools

この方のフォルダに入ります。
cd data
./change_tfrecord_filename.sh
TFRecordの名前の一括変更。
この方の操作方法に従い、dataフォルダのtrainとevalにTFRecordを格納させていく。
pbtxtもdataに保存です

cd model
./get_ssdlite_mobilenet_v2_coco_model.sh

データの取り込み

configファイルもあるので中身のnum classを自身の検知させたい対象に合わせる。(1の場合,1、2の場合,2)

model {
  ssd {
    num_classes: 1 今回はexitかどうかのみなのでクラス(ラベル)は1で設定
    box_coder {
   (以下省略)
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
この方のレポジトリから出て/models/researchで下記実行

python object_detection/model_main.py --pipeline_config_path="./object_detection_tools/config/ssdlite_mobilenet_v2_coco.config" --model_dir="./saved_model_01" --num_train_steps=10000 --alsologtostderr
学習スタート

学習が始まります。私はアノテーションデータ大体50枚程度で3時間程度かかりました。Dockerのメモリは初期設定で2Gなのですがそれでは足りないので4Gまで拡張しました。これでギリギリできます。

この学習が終わればckptという学習結果がsaved_model_01フォルダに格納されます。
このckptが一番進んでいるものckpt :10000?を使用していきます。

TensorFlow学習グラフ(.pb)をTensorFlowLite形式(.tflite)に変換

ここからは過去記事にも書いたのですが通常のtensorflow形式のpbモデルとして使用する場合と、tfliteに変換するための前段階ようのpbファイルを作成する2通りの変換があります。過去記事では追加事項にてtflite用変換のコードを記載しています。

今回は携帯に搭載することが目的なのでtflite変換用です。ちなみにtflite変換用のpbでも普通にtensorflowのpbグラフとしても使用できる気がするのですがまあそこは置いておきます。と言うかもしかすると変換の際に何かミスがなければ通常のpb形式もtflite形式に変換できるのかもしれない。。まあ気になる方は確認してみてください。

models/research#python object_detection/export_tflite_ssd_graph.py --input_type image_tensor --pipeline_config_path [pipelineのpath] --trained_checkpoint_prefix [ckptのpath] --output_directory [出力先フォルダ] -add_postprocessing_op=true
slimのエラー出ればslimフォルダで
python setup.py build
python setup.py install
でエラー解消
tflite_graphをtflite形式に変換する 
models/research#tflite_convert --output=[出力先path(/models/original_data/result1.tflite)] --graph_def_file=[tflite_graph.pbグラフpath(/models/original_data/detect_test/tflite_graph.pb] --input_arrays=normalized_input_iamge_tensor --output_arrays=TFLite_Detection_PostProcess,TFLite_Detection_PostProcess:1,TFLite_Detection_PostProcess:2,TFLite_Detection_PostProcess:3 --input_shapes=1,300,300,3 --allow_custom_ops

これで、「tflite_graph.pb」を「result1.tflite」に変換できます。

TensorFlow Liteのテンプレートアプリの指定箇所に自作モデルを配置

TensorFlow Liteのホームページにある例で「Object Detection API」gitからクローンし、Xcodeで開きます。

プロジェクトを開いた後は、「ModelDataHandler」のフォルダ内の「ModelDataHandler.swift」ファイルの下記箇所を修正します。

自作モデルの名前を記載。

自作モデルにインプットする画像のサイズを記載する。

後は「Model」フォルダに自作のモデルを配置し、それに対応する正解ラベルのテキストを配置します。これで一様は準備します。

これをXcodeにてビルドすると動きますのでそちらで試してみましょう。

カメラクラスを使用しているので実機での検証が必要です。
実機テストは過去記事にありますのでご参照ください。

「Xcodeのビルドを実機で行う方法ご紹介。」

では今回の記事は以上です。他にも多数の機械学習関連の記事やSwiftでの開発関連記事を記載しているので是非そちらも参考にして下さい。

おすすめ情報ご紹介。

下記リンクよりU-NEXTの契約をすると31日間無料でU-NEXTの全動画約21万作品を見放題です。31日期間に解約すれば0円です。今だけのおすすめ情報なのでまだ登録していない人は是非!

スポンサーリンク
TensorFlow
スポンサーリンク
シェアする
スポンサーリンク
SunnyDayTravel-Blog

コメント

  1. […] 【TensorFlow】Object Detection API のTensorFlow LiteモデルをiOSに搭載する手順。〜画… […]

タイトルとURLをコピーしました