Xcode
iOS
apple
Swift
ios11

【iOS11】mlmodelファイルからSwiftコードを生成するコマンド【CoreML】

この記事はAppleの公式のドキュメントには(恐らく)記載されておらず、動作検証ベースでの内容になるので、ご留意ください。

はじめに

iOS11から新しく加わったCoreMLフレームワークにて使用する「.mlmodel」ファイルについての記事です。
こちらでまとめたように、Xcode9以降で.mlmodelファイルをプロジェクトのターゲットに加えると、Swiftのコードが自動生成されます。

今回は、XcodeによるSwiftコードの自動生成ではなく、コマンドラインからSwiftコードを生成する方法を紹介します。

コマンドラインでmlmodelからSwiftコードを生成

▼ やり方

次のようなコマンドでmlmodelからSwiftコードを生成することができます。

/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc generate [mlmodel path] [output path] --language [Swift|Objective-C] [--swift-version 4.0]

具体例はこんな感じ
/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc generate ./mymodel.mlmodel . --language Swift --swift-version 4.0

/Applications/Xcode.app/Contents/Developerの部分はxcode-select -pのパス

▼ 使い所は?

例えば、mlmodelをアプリのバンドルに組み込むのではなく、ネットワークを介して取得するような設計をする場合(参考)、
Xcodeで自動コンパイルするのとは違って、mlmodelをSwiftのCoreMLで扱うためのSwiftのクラスを自分で書く必要が出てきます。

そのような時に、このコマンドを使ってボイラープレートとなるSwiftコードを生成することで、開発が楽になるかもしれません。

▼ 注意点

さて、このコマンドで生成されるSwiftコードの一部を下記に掲載します。

/// Construct a model that automatically loads the model from the app's bundle
convenience init() {
    let bundle = Bundle(for: mymodel.self)
    let assetPath = bundle.url(forResource: "mymodel", withExtension:"mlmodelc")
    try! self.init(contentsOf: assetPath!)
}

イニシャライザの一つですが、mlmodelをコンパイルした後のリソース(mlmodelc)が、アプリのbundleのなかにある前提でコードが生成されます。

上記のように、ネットワークを介してmlmodelを取得・コンパイルする場合は、その時に保存するmlmodelcのパスからイニシャライズするように書き換えてあげる必要がありそうです。
(実務レベルでは考えていないので、所感の注意点ですが。。)

そういった観点で、少し前の記述にて「ボイラープレート」という表現を使いました。

おわりに

このコマンド、ドキュメントが見つからないので積極的に使うものではないかもですが、面白いですね。

参考

https://blog.zedge.net/developers-blog/hotswapping-machine-learning-models-in-coreml-for-iphone