0
0

More than 1 year has passed since last update.

TensorFlow 2.xでObject Detection APIを使うにはTensorFlowバージョンを揃える必要がある話

Last updated at Posted at 2021-09-23

機械学習周りで物体検出したいとき、TensorFlowとともにObject Detection APIを利用することがあります。

Object Detection API側のアップデートで新規Docker環境が動かなくなったことがありました。

TL; DR

tensorflowおよびtensorflow関連ライブラリでバージョンを揃えればOKです。以下どちらかを行います。

  1. ベースとなるimageで最新のTensorFlow (GPU)バージョンのimageを使用する
  2. (workaround) Dockerfile内で同一バージョンのtensorflow, tensorflow-text, tf-models-officialをインストールする
    • TensorFlow 2.4.0未満の場合、Object Detection APIの特定コミットをチェックアウトする

検証環境

  • Ubuntu 20.04 LTS(カーネル: 5.4.0-81-generic)
  • Docker version 19.03.13
  • Dockerfile: Object Detection API公式で提供されているDockerfileから、ベースとなるimageをtensorflow/tensorflow:2.4.0-gpuに変更したもの

発生した問題

Object Detection API学習用のDockerコンテナを作って、model_main_tf2.pyで学習をかけました。すると、tensorflow-textのライブラリ部分で参照エラーが発生しクラッシュしました。

tensorflow.python.framework.errors_impl.NotFoundError: /usr/local/lib/python3.6/dist-packages/tensorflow_text/python/metrics/_text_similarity_metric_ops.so: undefined symbol: _ZN10tensorflow8OpKernel11TraceStringEPNS_15OpKernelContextEb

このエラーが出る理由は、tensorflow関連ライブラリ間でバージョンが一致していないためです。バージョンが異なると、tensorflow関連ライブラリのバイナリ間で差異が出ます。そのため、一部シンボルを読み出せなくなる可能性があります。

なぜバージョンが一致しなくなるかですが、Object Detection API(object_detectionライブラリ)のインストール時、常に最新のtensorflowライブラリをインストールしてしまうためです。これにより、2つのバージョンのtensorflowライブラリがインストールされてしまい、整合性が取れなくなります(詳しい理由については付記を参照ください)。

対策

tensorflowライブラリとその関連ライブラリのバージョンを合わせればよいので、以下のどちらかで解消されます。

  1. ベースとなるimageで最新のTensorFlow (GPU)バージョンのimageを使用する
  2. Dockerfile内で同一バージョンのtensorflow, tensorflow-text, tf-models-officialをインストールする
    • TensorFlow 2.4.0未満の場合、Object Detection APIの特定コミットをチェックアウトする

1.ベースとなるimageで最新のTensorFlow (GPU)バージョンのimageを使用する

DockerfileでベースにしているTensorFlow (GPU)を最新版に変更します。

2021.09.23現在、2.6.0が最新です。そこで、Dockerfileを以下の通り書き換えます(適宜、最新のバージョンに読み替えてください)。

- FROM tensorflow/tensorflow:2.2.0-gpu
+ FROM tensorflow/tensorflow:2.6.0-gpu

2. (workaround) Dockerfile内で同一バージョンのtensorflow, tensorflow-text, tf-models-officialをインストールする

学習環境側で制約があり、どうしてもTensorFlowのバージョンを特定のバージョンに揃えたい場合があります。

その場合、Dockerfileを以下のように書き換えます。

※ TensorFlow 2.5.0をNVIDIA GPUと共に使いたい場合

FROM tensorflow/tensorflow:2.5.0-gpu
ARG DEBIAN_FRONTEND=noninteractive

# Install apt dependencies
RUN apt-get update && apt-get install -y \
    git \
    gpg-agent \
    python3-cairocffi \
    protobuf-compiler \
    python3-pil \
    python3-lxml \
    python3-tk \
    wget

# Add new user to avoid running as root
RUN useradd -ms /bin/bash tensorflow
USER tensorflow
WORKDIR /home/tensorflow

# Clone Object Detection API
RUN git clone https://github.com/tensorflow/models/ /home/tensorflow/models/

# Workaround: If you use TF 2.2.x, uncomment the line below.
# WORKDIR /home/tensorflow/models/
# RUN git checkout 03a6d6c8e79b426231a4d5ba0cf45be9afc8bad5

# Workaround: If you use TF 2.3.x, uncomment the line below.
# WORKDIR /home/tensorflow/models/
# RUN git checkout cf82a72480a41a62b4bbe0f1378d319f0d6f5d5c

# Compile protobuf configs
RUN (cd /home/tensorflow/models/research/ && protoc object_detection/protos/*.proto --python_out=.)
WORKDIR /home/tensorflow/models/research/

RUN cp object_detection/packages/tf2/setup.py ./
ENV PATH="/home/tensorflow/.local/bin:${PATH}"

# Workaround (For Tensorflow < 2.5.1): Remove tf-models-official dependency from object_detection, will install it manually.
RUN sed -i -e 's/^.*tf-models-official.*$//g' ./setup.py

RUN python -m pip install -U pip

# Workaround: Lock tensorflow and corresponding tf-models-official versions.
RUN python -m pip install tensorflow==2.5.0 tensorflow-text==2.5.0 tf-models-official==2.5.0
RUN python -m pip install .

ENV TF_CPP_MIN_LOG_LEVEL 3

変更点1. 使いたいバージョンのtensorflow、および対応するtensorflow-textとtf-models-official(学習済みモデル利用のためのライブラリ)を手動でインストールします。なお、tensorflow/tensorflow:x.x.x-gpuをベースimageとして使う場合、初期状態でtensorflowライブラリは入っていないため、特定バージョンのTensorFlowを指定する必要があります。

RUN python -m pip install -U pip
+ 
+ # Workaround: install tensorflow and corresponding tf-models-official versions.
+ RUN python -m pip install tensorflow==2.5.0 tensorflow-text==2.5.0 tf-models-official==2.5.0
RUN python -m pip install .

ENV TF_CPP_MIN_LOG_LEVEL 3

変更点2. (使いたいTensorFlowのバージョンが2.5.1未満の場合) object_detectionライブラリの依存関係から、tf-models-officialを削除してください(その代わりに、変更点1でtensorflowに対応したバージョンのtf-models-officialをインストールしています)。

ENV PATH="/home/tensorflow/.local/bin:${PATH}"

+ # Workaround (For tensorflow < 2.5.1): Remove tf-models-official dependency from object_detection, will install it manually.
+ RUN sed -i -e 's/^.*tf-models-official.*$//g' ./setup.py

RUN python -m pip install -U pip

最新のobject_detectionライブラリのsetup.pyでは、tf-models-official>=2.5.1に依存関係に指定されています。そのため、それ以前のtf-models-officialを依存関係を含めるために上記変更が必要です(object_detectionライブラリはバージョニング未対応で、過去のリリースバージョンを特定することが難しいことが理由です)。

変更点3. (使いたいTensorFlowのバージョンが2.4.0未満の場合) インストールに使うobject_detectionのソースコードについて、古いコミットを指定します。最新のobject_detectionライブラリでは、tf-models-officialの2.4.0未満に対応していないため実行時エラーになります1

以下の部分について、TensorFlow 2.2.xを使う場合は上の2行、2.3.xを使う場合は下の2行をコメントアウトしてください。

TensorFlow 2.2.xの場合

+ 
+ # Workaround: If you use TF 2.2.x, uncomment the line below.
+ WORKDIR /home/tensorflow/models/
+ RUN git checkout 03a6d6c8e79b426231a4d5ba0cf45be9afc8bad5

TensorFlow 2.3.xの場合

+ 
+ # Workaround: If you use TF 2.3.x, uncomment the line below.
+ WORKDIR /home/tensorflow/models/
+ RUN git checkout cf82a72480a41a62b4bbe0f1378d319f0d6f5d5c

以上の変更により、使いたいバージョンのTensorFlowのみがインストールされ、学習が可能になります。

付記: なぜObject Detection APIで最新のTensorFlowライブラリがインストールされてしまうのか?

object_detectionライブラリは、setup.py上でtf-models-officialライブラリ(学習済みモデルを使うためのライブラリ)を依存関係に持ちます。

REQUIRED_PACKAGES = [
    ...,
    'tf-models-official>=2.5.1',
]

tf-models-officialライブラリのsetup.pyを見てみると、

...
if project_name == 'tf-models-nightly':
  version += '.dev' + datetime.datetime.now().strftime('%Y%m%d')
  install_requires.append('tf-nightly')
  install_requires.append('tensorflow-text-nightly')
else:
  install_requires.append('tensorflow>=2.4.0')
  install_requires.append('tensorflow-text>=2.4.0')
...

となっていて、特定バージョン以上のtensorflow, tensorflow-textライブラリを依存関係を持ちます。そのため、すでにtensorflowライブラリをインストールしていても最新のバージョンがインストールされます2

一方で、tensorflow-gpuは自動的にアップデートされません。そのため、前述の通りtensorflowとバージョンが不整合になり得ます。

参考: どうすればこの問題が起こらないか?

ライブラリ側で以下の2点が対応されれば、本問題は解消されます。また、TensorFlow 2.4.0未満でObject Detection APIが実行時エラー問題も解消されます。

  • object_detectionライブラリがtf-models-officialライブラリ同様にTensorFlowのバージョンに揃えてバージョニングされている
    • 例えば、TensorFlow 2.4.0に対し、tf-models-officialとobject_detectionのバージョンがともに2.4.0になる
  • tf-models-officialが特定のTensorFlowのバージョンに依存関係が固定されている
    • 例えば、TensorFlow 2.4.0に対し、tensorflow==2.4.0, tensorflow-text==2.4.0が依存関係で固定されている

参考ページ

公式GitHub issue #9911: Dockerfile installs two tensorflow versions when building


以上、ご覧いただきありがとうございました!


  1. object_detectionライブラリがtf-models-officialライブラリと対応してバージョニングされていないため、特定のコミットを指定する必要があります。 

  2. tf-models-officialのバージョンは対応するtensorflowライブラリのバージョンと同じになっており、そのバージョンが依存関係の下限になります。 

0
0
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
0
0