Python
機械学習
Swift
TensorFlow
coreML

TensorFlowで作ったモデルをCore MLで利用する

tfcoreml(リポジトリ名は "tf-coreml")という、TensorFlowで学習したモデルを、Core MLモデル(.mlmodel)に変換するツールがあります。

TensorFlow LiteもCore MLモデルへの変換をサポートしているみたいな記事もありましたが、まだLiteがどういうものなのかよくわかってないのと、ググッてtfcoremlが一番上に出てきたし、メンテもアクティブにされてるようなのでこちらを試してみた次第です。

tfcoremlのインストール

$ pip install -U tfcoreml

でいけます。

が、僕はしばらくTensorFlowを触ってなかったので、次のエラーに遭遇しました。

Could not find a version that satisfies the requirement tensorflow>=1.1.0 (from tfcoreml) (from versions: )
No matching distribution found for tensorflow>=1.1.0 (from tfcoreml)

tfcoremlは要TensorFlow 1.1.0以上です。

というわけで最新版(2018.3.9現在、v1.6)にアップグレード。その手順は記事もたくさん出ているので省略します。

再度インストールを実行すると、

(tensorflow) $ pip install -U tfcoreml

無事入りました。

Successfully installed coremltools-0.8 six-1.10.0 tfcoreml-0.1.1

ちなみに現状ではtfcoremlはpython v2.7版のみです。3.x版はありません

変換対象のモデルを用意する

READMEに

frozen .pb graph file to be converted

とあるので、変換対象としてfrozenな.pbフォーマットのモデルファイルを用意します。

すぐに試せるものとして、READMEに

Below is a list of publicly available TensorFlow frozen models that can be converted with this converter:

と、公開されているTensorFlowのfrozenモデルのうち、本コンバータで変換可能なもののリストが掲載されています。

本記事では "Inception v3 (non-Slim)" を使うことにします 1

変換スクリプトを書く

READMEには

import tfcoreml as tf_converter
tf_converter.convert(tf_model_path = 'my_model.pb',
                     mlmodel_path = 'my_model.mlmodel',
                     output_feature_names = ['softmax:0'],
                     input_name_shape_dict = {'input:0' : [1, 227, 227, 3]})

というサンプルが載っています。これを自分が変換したいモデルに合わせて書き換えるわけですが、本記事で使おうとしているInception v3のサンプルが、リポジトリ内のtf-coreml/examples/inception_v3.ipynbにあるので、これにしたがって書き換えます。

converter.py
import tfcoreml as tf_converter

tf_converter.convert(tf_model_path = 'tensorflow_inception_graph.pb',
                     mlmodel_path = 'tensorflow_inception_graph.mlmodel',
                     output_feature_names = ['softmax/logits:0'],
                     input_name_shape_dict = {"Mul:0":[1,299,299,3]})

変換スクリプトを実行

(tensorflow) $ python converter.py 

NotImplementedError: Unsupported Ops of type: DecodeJpeg. Kindly refer to the "examples/inception_v3.ipynb" notebook on how to strip input pre-processing from the TF graph before conversion to CoreML.

エラーが出てしまいました。input pre-processingをstripする方法がexamples/inception_v3.ipynbにあるから参照しろと。

なんやかんや変換スクリプトを追加・修正して、〜.mlmodelが生成されるようになります。(修正後のスクリプトは諸事情により割愛)

あと、CoreML+Visionで使うときの入力の型をimageにするために、変換スクリプト内で呼んでいるtf_converter.convertで、引数image_input_namesを追加する必要もありました。

iOSで使う

こちらの記事に書きました:

トラブルシューティング: 変換実行時にImportErrorが発生する

こういうやつ:

ImportError: dlopen({path-to-tensorflow}/lib/python2.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.so, 6): Symbol not found: _PyUnicodeUCS2AsASCIIString

詳細は別記事に書きました:

関連記事


  1. 「それ、Appleが配布してるのがもうあるよ」というツッコミがありそうなので念のため注釈入れておくと、Inception v3を使うのはあくまで記事用です。実際の目的としては自分たちがTensorFlowを使って独自に学習させたモデルを利用することです。