🔗

Core MLのLinked Modelとパイプライン

2021/12/14に公開

Core MLのリンクモデルとは

リンクモデル(Linked Model)[1]は、ダイナミックリンクライブラリのように動的にリンクできるモデルです。

リンクモデルを使用するメリット

たとえば2種類の画像分類モデルがあるとして、従来だと次のようにそれぞれが特徴抽出器を持っていたところが、

scale=0.9

リンクモデルを使用することで、次のように複数のモデルでひとつの特徴抽出器を共有することが可能となります。

1つのリンクモデル(特徴抽出器)を2つの画像分類モデルで共有

一般的にCNNパラメータは特徴量抽出部分も含めると小さいものでも数MB〜数十MB程度にはなるので、従来はひとつのアプリで多数の画像分類モデルを使用することは(アプリのバイナリサイズや起動時間への影響を鑑みて)ためらわれたのですが、リンクモデルによってそのサイズの問題は劇的に解消されることになります。

また、画像分類モデル毎にすべてのパラメータを学習することなく、特徴抽出器の部分を再利用できるので、モデルの学習も格段に楽になります。

リンクモデルとパイプライン

先の図では、リンクモデルとして共用する特徴抽出部分と、犬や猫など特定の対象を検出するよう学習させた分類モデルとを組み合わせて、ひとつのモデルのように使用しています。

これを実現しているのがCore MLのパイプライン機能です。

https://zenn.dev/shu223/articles/coreml-pipeline

上に挙げた記事の冒頭でパイプライン化のメリットとして

モデルサイズがトータルで小さくなる

と述べましたが、そのメリットはまさにこのようにリンクモデルと組み合わせることで発揮されるわけです。

この件に関してはこちらの記事で具体的に解説しています。

https://zenn.dev/shu223/articles/createml-model

リンクモデルの作成方法

Core MLモデルをリンクモデルとするには、まずspecificationVersion_MINIMUM_LINKED_MODELS_SPEC_VERSIONをセットし、

spec = coremltools.proto.Model_pb2.Model()

spec.specificationVersion =  coremltools._MINIMUM_LINKED_MODELS_SPEC_VERSION

SpecのlinkedModel.linkedModelFile.linkedModelFileName^ linkedModelFileフィールドにリンクモデルとして読み込むファイル名をStringParameter型でセットします。

# StringParameterオブジェクトを作成
fileName = coremltools.proto.Parameters_pb2.StringParameter()
fileName.defaultValue = 'hoge.mlmodelc'

# CopyFromメソッドでlinkedModelFileNameの値を上書き
spec.linkedModel.linkedModelFile.linkedModelFileName.CopyFrom(fileName)

またSpecのlinkedModel.linkedModelFile.linkedModelSearchPathに、リンクモデルファイルを探索するパスをStringParameter型でセットします。

searchPath = coremltools.proto.Parameters_pb2.StringParameter()
searchPath.defaultValue = '.:$BUNDLE_MAIN'
spec.linkedModel.linkedModelFile.linkedModelSearchPath.CopyFrom(searchPath)

パスは相対パスあるいは絶対パスで指定できます。複数パスを指定することができ、":"で区切ります。上のサンプルで指定している$BUNDLE_MAINはメインバンドル内を探索することを表し、$BUNDLE_IDENTIFIER(identifier)で指定したIDのバンドル内を探索先として指定することも可能です。

以上でリンクモデルとしての最低限の指定は完了です。

参考書籍

https://shu223.booth.pm/items/1723495

目次

第1章 準備
  • 1.1 Core ML Toolsとは
  • 1.2 Core ML Toolsの環境構築
第2章 Core ML Toolsはじめの一歩
  • 2.1 2行のコードで学習済みモデルをロードする
  • 2.2 2行のコードでCore MLモデルに変換する
  • 2.3 変換したモデルを.mlmodelファイルとして保存
第3章 Core MLモデル作成の基礎
  • 3.1 HDF5ファイルを読み込む
  • 3.2 Core MLモデルに変換する
  • 3.3 Core MLモデルの入力の型を変更する
  • Core MLモデルから自動生成されるSwiftコード
  • Visionはどのように画像分類モデルを判定するか?
第4章 オンデバイス学習 - UpdatableなCore MLモデルの作成
  • 4.1 モデルのパーソナライゼーション
  • 4.2 ベースとなるモデルの作成
  • 4.3 Updatableなモデルに変換する
  • 4.4 損失関数をセットする
  • 4.5 最適化アルゴリズムをセットする
  • 4.6 エポック数をセットする
  • 4.7 モデルを保存する
第5章 オンデバイス学習 - iOSで学習
  • 5.1 MLUpdateTask
  • 5.2 学習データの準備
  • 5.3 学習タスクの実行
  • 5.4 オンデバイスで学習したモデルを保存する / MLUpdateContext, MLWritable
  • 5.5 推論処理の実行
第6章 TensorFlowモデルの変換 - 基礎編
  • 6.1 tfcoreml
  • 6.2 tfcoremlを用いたCore MLモデルへの変換(最小実装)
  • 6.3 より扱いやすいCoreMLモデルに変換する
  • 6.4 iOSで推論を実行
  • 6.5 入力画像の前処理を指定する
第7章 TensorFlowモデルの変換 - 画風変換モデル
  • 7.1 学習済みモデルからグラフ定義を読み込む
  • 7.2 変換に必要なグラフの情報を取得する
  • 7.3 tfcoremlを用いて変換する
  • 7.4 Core MLモデルの出力の型を変更する
  • 7.5 iOSで画風変換を実行
第8章 Flexible Shape - 超解像モデル
  • 8.1 Flexible Shapeとは/使いどころ
  • 8.2 超解像モデルをCore MLモデルに変換する
  • 8.3 Flexible Shapeを適用する
  • 8.4 iOS側での推論処理の実行
第9章 Core MLモデルのサイズを小さくする
  • 9.1 本章で利用する感情認識モデルについて
  • 9.2 重みを16ビット化する
  • 9.3 クォンタイズ
  • 9.4 iOSでの推論結果の比較
  • 9.5 さらなるモデルサイズ削減
第10章 パイプラインモデルとリンクモデル(Linked Model)
  • 10.1 パイプラインの構築
  • 10.2 リンクモデル(LinkedModel)
  • CreateMLのモデルはなぜ小さいのか
第11章 モデルの可視化
  • 11.1 Netron
  • 11.2 coremltoolsのvisualize_spec
  • 11.3 TensorBoard
  • 11.4 Kerasのplot_model
第12章 mlmodelファイルフォーマット
  • 12.1 mlmodelファイルフォーマットを理解するメリット
  • 12.2 .protoファイルの読み方
  • 12.3 coremltoolsとprotobuf
  • 12.4 protobuf API
付録A coremltools逆引きリファレンス
  • A.1 MLModelオブジェクトを生成する
  • A.2 モデルのspec(Model_pb2.Model)を取得する
  • A.3 .mlmodelファイルの保存・読み込み
  • A.4 NeuralNetworkBuilderを生成する
  • A.5 モデルの中身を調べる
  • A.6 Core MLモデルにクラスラベルを与える
  • A.7 モデルの入力・出力をカスタマイズする
  • A.8 モデルサイズを圧縮する
  • A.9 オンデバイス学習関連
  • A.10 FlexibleShape関連
  • A.11 misc.
脚注
  1. 日本語で「リンクトモデル」とするか迷いましたが、おそらく耳慣れない表現であるので「リンクモデル」としました。 ↩︎

Discussion