6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【TPUを使いたい人向け】Tensorflow Object Detection API を使ってみた 2

Last updated at Posted at 2020-06-19

はじめに

RHEMS技研のIchiLabです。
(※タイトルのTPUはTensor Processing Unitの略であり、熱可塑性ポリウレタンの事ではありませんのでご注意を。)

前回記事はこちらです。
【初心者向け】Tensorflow Object Detection API を使ってみた

TensorFlowのObject Detection API(以下、API)は物体検出のAIを作るのにとても便利です。
一方、以下のような悩みを持つ方は少なくないと思います。

  • 学習時間が長すぎる
  • 高性能なGPU(Tensorコアが搭載されている等)は高価すぎて買えない
  • TPUというディープラーニングに最適なものがあるらしいがどう使えば良いかよく分からない
  • Cloud TPUはめちゃくちゃ使用料が高すぎる

今回は、個人レベルでもお金が出せそうな範囲でCloud TPUを使用できた方法について、この場を借りて備忘録として残しておきます。
本記事の方法でAPIを使用すると、GCPのCloud TPUを最初から最後まで使うよりもずっとずっと安く済ませることが可能になります。

皆様にも少しでもお役に立てれば幸いです。

前置き

大まかな方法

結論から書くと、できるだけ安く抑えてTPUを用いてAPIを使用する方法は以下の内容がベストだと考えます。

  1. Google Colaboratoryの無料枠で学習させる
  2. 無料枠から弾かれている間に学習させたい場合は、GCPのVMとCloud TPU(いずれもプリエンプティブ)で続きを行う

Google Colaboratoryは他記事でもたくさん紹介されているので詳細は割愛しますが、

  • 無料で使える(12時間未満の制限あり)
  • ブラウザからPythonを動かせる
  • Jupyter Notebookのような操作性
  • 高価なGPU・TPUが無料で使える
    といった特徴の素晴らしいサービスです。

素晴らしい上に高性能な環境を無料で手に入れられる代償として、使いすぎるとしばらくGPUまたはTPUを使わせてもらえないことがあります。

そのような時に、自前でも同様の環境を用意できるようにしておくと、お金はかかりますが再び使えるまで待つ時間は節約できますよね。

Google Colaboratory Proという月額9.99ドルの素敵なサービスもありますが、本記事執筆時点(2020/06)では米国のみのサービスとなっております。
(日本からでも登録できたという他記事もありますが、規約違反になる可能性もありますので自己責任で & 私は試していません)

前提条件

ここでの説明は、以下の条件を前提として記載しております。

  • APIを使用したことがある(推奨)
  • GCPを触ったことがある(推奨)
  • アノテーション済みの教師用データが存在する(必須)
  • Googleアカウントを持っている(必須)
  • GCPの課金設定を終えている(クレジットカード等の登録)(必須)

注意事項(お金の話)

ここで紹介する方法は、必ずGCPのサービスを使用します。
そしていずれの方法でもCloud Storageの利用料などで必ずお金がかかってきます。
GCPは初回だと300ドルの無料枠が用意されていますが、
無料枠にTPUの使用料は含まれていなかったり、Cloud Storageの無料枠にもいくつか制限がありますので、必ずご自身で内容を確認してから行ってください。
(Cloud MLには無料枠が用意されていますが、私は試しておりません)

共通の前準備

TPUを使用して学習させるためには、Cloud Storageに保管している必要があります。

ここでは、以下の名称であることと仮定して説明していきます。
プロジェクトID : gcp-project-123
バケット名 : my-bucket-123

ローカルPCから手早くバケットにコピーしたいなら、-mオプションを忘れずに!

Macのzshで今いるディレクトリのフォルダをバケットに送り込むコマンド例
gsutil -m cp -r \* gs://my-bucket-123/

バケット内のフォルダ構成は、以下のようにしました。
(※以降の説明もこの構成を前提に話を進めていきます)

gs://my-bucket-123/
├── models
│     ├── ssd_mobilenet_v1_fpn (転移学習元のモデルデータ)
│             └── .ckpt 他いろいろ
├── data
│     ├── save (学習データ保管用ディレクトリ)
│     ├── train (教師用データ保管用 ~ tfrecord)
│     └── val (検証用データ保管用 ~ tfrecord)
├── hoge.config (コンフィグデータ)
└── tf_label_map.pbtxt (ラベルデータ)

今回は転移学習元に、ssd_mobilenet_v1_fpn_cocoを使用しました。
なお、Tensorflow detection model zooのページには、TPUをサポートしたtrained modelに☆マークがついています。

コンフィグの内容については前記事で詳しく説明しましたので割愛しますが、
上記ファイルがCloud Storageになったことで、以下の項目もそれに合わせる必要があります。

fine_tune_checkpoint: "gs://my-bucket-123/models/ssd_mobilenet_v1_fpn/model.ckpt"
label_map_path: "gs://my-bucket-123/tf_label_map.pbtxt"
input_path: "gs://my-bucket-123/data/train/{filename}.tfrecord
input_path: "gs://my-bucket-123/data/val/{filename}.tfrecord

(※{filename}の部分の書き方は前記事参照)

1. Google Colaboratoryを使って行う方法

無料枠で行えるうちは、こちらで行いましょう。
ただし、先述しましたがCloud Storageの料金はかかってきます。

1-1. APIのソースをドライブに置く

ローカルでもコンテナでも良いので、一度git cloneしたものを、自分のGoogleドライブ内に保管します。

ちなみに最新のmasterでやるとうまく出来たものが色々と出来なくなったりとトラブルが多かったので、
私の試したおすすめは以下のブランチです。

git clone -b tf_2_1_reference https://github.com/tensorflow/models.git

cocoAPIも忘れずに。

git clone --depth 1 https://github.com/cocodataset/cocoapi.git

なお、ここではソースコードは以下のディレクトリに置くと仮定します。

/content/drive/My Drive/models/research
/content/drive/My Drive/cocoapi/PythonAPI

1-2. 新しいノートブックを作る

ブラウザ上で、Googleドライブから、
「新規」→「その他」→「Google Colaboratory」を選択します。

タイトルを、「Untitled0.ipynb」から任意の名前に変更します。(推奨)

上のメニューから、「ランタイム」→「ランタイムのタイプを変更」→ハードウェア アクセラレータを「TPU」に指定し、「保存」します。
次に、「接続」を選択します。

1-3. Googleドライブのマウント

まずはAPIのソースが読めないと始まらないのでマウントします。

from google.colab import drive
drive.mount('/content/drive')

1-4. GCPプロジェクトの設定

Cloud Storageと連携するために、gcloudコマンドでプロジェクトの設定を行います。

from google.colab import auth
auth.authenticate_user()
project_id = 'gcp-project-123'
!gcloud config set project {project_id}
!gsutil ls my-bucket-123

Googleドライブと同様の認証です。
成功すると、バケットの中身がlsコマンドによって確認出来ます。

1-5. cocoAPIのインストール(初回のみ)

%cd /content/drive/My\ Drive/cocoapi/PythonAPI
!make
!cp -r pycocotools /content/drive/My\ Drive/models/research/

1-6. protocの実行(初回のみ)

.protoを.pyに変換します。

%cd /content/drive/My\ Drive/models/research
!protoc object_detection/protos/*.proto --python_out=.

1-7. tensorflowのバージョンを変更する

Tensorflow Object Detection APIはtensorflowの2.Xに対応していません。
一方、Google Colaboratoryは初めから2.X系がインストールされています。
そのため、バージョンを確認してインストールし直す必要があります。

!pip list | grep tensor
!pip install tensorflow==1.15.0rc3

1-8. 環境変数の設定

%env PYTHONPATH=/env/python:/content/drive/My Drive/models/research:/content/drive/My Drive/models/research/slim

1-9. APIのテストコードの実行

無事に環境構築を終えているかをテストしましょう。
うまくいっていれば「OK」と複数行にわたって表示されます。

ちなみに本記事では少し古いブランチのソースを使用していますが、最新ではmodel_builder_tf1_test.pyという名前に変更されています。

%cd /content/drive/My Drive/models/research
!python object_detection/builders/model_builder_test.py

1-10. Tensorboard起動(必須ではない)

以下のように学習データを保存するディレクトリを指定して起動しておくと、lossの動きや1秒あたりの学習step数などが確認できます。

%load_ext tensorboard
%tensorboard --logdir gs://my-bucket-123/data/save

1-11. 学習開始

学習には、model_main.pyではなく、model_tpu_main.pyを使用します。
オプションにGCPプロジェクトIDやTPU名を指定することができますが、Google Colaboratoryの環境内では不要でした。
おそらく環境変数に元からTPUのアドレスが登録されているからなのではないかと思われます(推測)。
%envで確認するとTPU_NAMEという名称でgrpc://に続くTPUのアドレスが登録されています)

%cd /content/drive/My Drive/models/research
pipeline = 'gs://my-bucket-123/hoge.config'
save = 'gs://my-bucket-123/data/save'
train_step = 1000
mode = 'train'
batch_size = 64

!python object_detection/model_tpu_main.py \
 --pipeline_config_path={pipeline} \
 --mode={mode} \
 --num_train_steps={train_step} \
 --eval_training_data=True \
 --train_batch_size={batch_size} \
 --model_dir={save} \
 --alsologtostderra

1-12. おまけ(Colabratoryの使用時間を確認する方法)

Google Colaboratoryは12時間未満の使用制限がありますが、
実際にあと何時間使えるのかがどこかに書いているわけではありません。
下記のコードを実行すると、それを知ることが出来ます。

pythonだとdatetimeモジュールが便利ですが、あえて使用せず書いてみました。

import time, psutil

COLAB_LIMIT_HOUR = 12 # Google Colabratoryの無料枠は約12時間

def time_conversion(second):
  h = second // 3600
  m = second % 3600 // 60
  s = second % 60
  return h, m, s

now = time.time() # 今の時間
boottime = psutil.boot_time() # 起動した時間

elapsed_time = now - boottime # 経過時間
remaining_time = COLAB_LIMIT_HOUR * 60 * 60 - elapsed_time # 残り時間

print("経過時間は %d 時間 %d 分 %d 秒です" % (time_conversion(elapsed_time)))
print("残り時間は %d 時間 %d 分 %d 秒です" % (time_conversion(remaining_time)))

学習を始めてしまうと終わるまで他の実行は待機になってしまうので、
これをやるときは何かの処理が完了している場合にしましょう。

2. 自分でGCPのVMとCloud TPUを立ち上げて行う方法

さて、もしもGoogle Colaboratoryで「しばらく使えないから待ってね」と言われてしまい、どうしても待てない場合はこちらの手段で実施してみましょう。

2-1. VMとCloud TPUを立ち上げる

はじめに、Compute EngineとCloud TPUを有効にしておく必要があります。
初回は下記のように表示されます(執筆時点の画像)
Compute Engineの場合
左上の「ナビゲーションメニュー」→「Compute Engine」→「VMとインスタンス」
ss001.png
自動で準備が始まる。

Cloud TPUの場合
左上の「ナビゲーションメニュー」→「Compute Engine」→「TPU」

ss002.png
初回は「APIを有効にする」を選択する必要がある。
(これだけでTPUの課金は始まらないのでご安心を)

これらが準備出来た方、もしくは既に有効になっている方は、Cloud Shellを開きます。
Cloud Shellは右上の方に下のようなアイコンがあります。
ss003.png
少し待って開いたら、ctpuコマンドでVMとTPUを同時に立ち上げます。

ctpu up --zone=us-central1-b --tf-version=1.15 --machine-type=n1-standard-4 --name=mytpu --preemptible --preemptible-vm

ここでの重要なポイントは、VMとTPUのオプションにpreemptibleを入れること、
つまりプリエンプティブを使用することです。

次の表は、公式の料金計算ツールで、TPU V2のLocationがus-central1の場合で計算した結果です。

TPU Class Regular Preemptible
1時間あたり 約485円 約146円

プリエンプティブに関しては、公式ドキュメントをご参照ください。

コンソールやgcloudコマンドからでも同様の操作は可能です。
詳しくは公式ドキュメントのTPUの作成と削除に記載されています。

コマンドを実行すると、下記のように確認が表示されます。

  Name:                 mytpu
  Zone:                 us-central1-b
  GCP Project:          gcp-project-123
  TensorFlow Version:   1.15
  VM:
      Machine Type:     n1-standard-4
      Disk Size:        250 GB
      Preemptible:      true
  Cloud TPU:
      Size:             v2-8
      Preemptible:      true
      Reserved:         false
OK to create your Cloud TPU resources with the above configuration? [Yn]:

yを入力してEnter / returnでそれぞれの作成が始まります。
machine typeにn1-standard-4を選択した理由は、Google Colaboratory環境のメモリに近いからというだけですので、必要に応じて変更してください。

ちなみに、もしも誤ってCompute Engineのデフォルトサービスアカウントを消してしまっていると、上記のctpuコマンドでの作成が不可能になってしまいます。

2020/06/20 00:00:00 Creating Compute Engine VM mytpu (this may take a minute)...
2020/06/20 00:00:07 TPU operation still running...
2020/06/20 00:00:07 error retrieving Compute Engine zone operation: 

(こんな感じのエラーに... いつ消してしまったのでしょうか?)
解決策が分からなかったので私は新しいプロジェクトを作り直しました。

「・・・時を戻そう。」

2-2. 起動したばかりのTPUを停止させる

Cloud TPUは秒単位で課金されていきます。
無事起動が確認できたら、とりあえず速攻「停止」させましょう。

2-3. SSHで作成したVMインスタンスの中に入る

インスタンスが無事起動したら、下記の「SSH」から中に入りましょう。

ss004.png

接続が完了すると、下記のようにコンソール画面が開きました。
ss005.png

ここからはこの中で作業していきます。

なお、ここでgcloudコマンドでTPUの状態を確認することも可能です。


gcloud config set compute/zone us-central1-b
Updated property [compute/zone].

gcloud compute tpus list
NAME   ZONE           ACCELERATOR_TYPE  NETWORK_ENDPOINTS  NETWORK  RANGE          STATUS
mytpu  us-central1-b  v2-8              10.240.1.2:8470    default  10.240.1.0/29  STOPPING

余談ですがTPUのステータスは次のように表示されます。

作成中 起動中 起動 停止中 停止
CREATING STARTING READY STOPPING STOPPED

2-4. aliasを設定(必須ではない)

pythonなのかpython3なのか、はっきり統一させたいのでこの項目を加えました。
常にpythonは3.Xを使っていきたいので、以下のように設定を変更します。

.bashrcを開く

vi ~/.bashrc

1番最後の行に設定を追加する
I押してShift+Gで1番下へ移動して下記入力してesc押して:wqで上書き!

alias python="python3" 
alias pip='pip3'

設定を反映

source ~/.bashrc

これでpythonpython3ということになりました。

2-5. 必要なライブラリのインストール

ここからはAPIの環境構築とほとんど同じになりますが、割愛せず記載していきます。

sudo apt-get update
sudo apt-get install -y protobuf-compiler python-pil python-lxml python-tk
pip install -U pip && pip install Cython contextlib2 jupyter matplotlib tf_slim pillow

次にAPIのソースコードとcocoAPIを持ってきます。

git clone -b tf_2_1_reference https://github.com/tensorflow/models.git
git clone --depth 1 https://github.com/cocodataset/cocoapi.git

繰り返しますが本記事の説明で使用しているAPIのソースコードは上記のブランチです。

2-6. cocoAPIのインストール

続いてcocoAPIのインストール。

makeで以下のように失敗してしまいました。

x86_64-linux-gnu-gcc: error: pycocotools/_mask.c: No such file or directory

これを回避するために、Makefileを少し変更します。

cd cocoapi/PythonAPI
vi Makefile

Makefileを開いたら、pythonの部分をpython3に変更します(2箇所あります)。

make
cp -r pycocotools /home/ichilab/models/research && cd ../../ && rm -rf cocoapi

※ichilabの部分はあなたのユーザー名に変更してください。

2-7. protocの実行

.protoを.pyに変換します。

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

2-8. 環境変数の設定

ここの部分は一度SSHの画面を閉じてしまうと、再度行う必要がありました。

(pwd = models/research)
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
source ~/.bashrc

2-9. APIのテストコードの実行

無事に環境構築を終えているかをテストしましょう。
成功なら「OK」と複数行にわたって表示されます。

python object_detection/builders/model_builder_test.py

一応バケットの中身も見えるか確かめておくと良いかもしれませんね。

gsutil ls gs://my-bucket-123

2-10. 止めていたTPUを再開させる

停止させたままでは学習できませんので、ここで再び起動させましょう。
起動が確認できたら次です。

2-11. 学習開始

学習開始です。

python object_detection/model_tpu_main.py \ 
--tpu_name=mytpu \ 
--model_dir=gs://my-bucket-123/data/save \ 
--mode=train \ 
--pipeline_config_path=gs://my-bucket-123/hoge.config \ 
--alsologtostderra

オプションの説明を簡単に書きます。

  • --gcp_project : プロジェクトIDです。省略可能でした。
  • --tpu_name : ctpuコマンドで立ち上げた時に名付けたものです。
  • --tpu_zone : TPUのタイムゾーンです。省略可能でした。
  • --model_dir : 学習させたckptファイルたちの保存先を指定します。
  • --pipeline_config_path : 設定(コンフィグ)ファイルの保存場所を指定します。

ちなみに私はここで最新のソースを使用した場合、

tensorflow.python.framework.errors_impl.InvalidArgumentError: From /job:tpu_worker/replica:0/task:0:

のエラーに相当悩まされました。
これが先述したブランチのソースコードを使用している唯一の理由です。
コンフィグもその他のファイルも全く同じ条件下でしたので、今のところ原因は分かっておりません。

2-12. 学習が終わったらTPUとVMを停止・削除

用が済んだら、TPUを優先的に停止・削除しましょう。

料金はどれくらいになるのか

一通り環境構築の説明を終えたところで、結局どれくらい金がかかるのかが気になりますよね。

ちゃんとした比較を載せられないのは申し訳ないのですが、
Google Colaboratoryで100,000Step学習させたときは、400円もいかないくらいで済んでいます。
自分のプロジェクトでVMとTPUを立ち上げて使用した場合、さすがに100,000Stepも実施したことはないのですが、
TPUは先述した料金を目安に考えていただいて、Compute Engineが約6時間使用して4円、External IPの使用料に1円で合計10円未満でした。

この辺は私の記事よりも公式の料金計算ツールを使用していただくのが限りなく正解に近いでしょう。

おわりに

いかがでしたでしょうか?

意外とCloud TPU × Tensorflow Object Detection APIの環境構築についてのまとめ記事が見つからなかったりするので、これを機にTPUで学習させてみようと思う方や、GCPに興味を持つ方が増えれば幸いです。

学習速度の加速とともに皆様の物体検出AIの研究も加速されることを心より祈っております。

6
3
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?