iOSで機械学習の推論をするためにCoreMLを使おうとした時のつらみと回避方法まとめ
iOSで機械学習の機械学習の推論をする場合、Core MLやPytorch Mobileなどの選択肢がありますが、
Apple謹製のCore MLを使ってみようと思う人は多いはずです。
Core MLのメリットとしては
Pytorch MobileはiOS12以上なのに対し、Core MLはiOS11以上をサポートしているでのサポート範囲が広い
Core MLで作ったモデルはiPhoneのスペックに応じて最適化され、高速に実行される
Appleがサポートしているので安心
と言ったところがあります。
ただ、実際使ってみると画像分類などはQiitaにも多数使ってみた的な記事があるのですが、
マイナーなタスクのモデルを使ってみるとつらいところもあったので、まとめてみました。
(この記事自体はどちらかのライブラリを推奨するものではございません。)
目次
CoreMLのつらいところ
サポートされている演算がそんなに多くない
ちょっとマイナーな演算を使おうとすると、サポートされてないことがあります。
そんなときにはどうするかというと、サポートされている演算で書き直すか、自分でPRを作るなどしてサポートしてもらうという手があります。
私は5つほど未サポートの演算にぶつかり、以下のような方法で回避しました。
triu -> PR作った
logical_or -> PR作った
outer -> PR作った
einsum -> reshapeとmatmulを使って書き直した
einopsのrearrange -> reshapeやpermuteを使って書き直した
という感じでわりとサポートされていない演算を迂回したりサポートするのに時間がかかりました。
Flexible Input Shapeのトラブルがかなり多い
報告されているイシューのリストも参照してみてください。
例えばEnumerated sizeを複数同時に適用できないというようなバグがあります。
また、私がハマったバグとしてはflatten
がFlexible Shapeと合わせて使えないというバグがありました。
ValueError: Cannot add const [10*is0]
というエラーメッセージがでましたがわかりづらいです。
結局flatten
は諦めて、reshape
を使ってモデルを書き直すことで、回避することができました。
エラーメッセージがわかりづらい
flatten
の件もそうですが、全体的にエラーメッセージはわかりづらいです。
たとえば、coremltoolsでコンバートしたモデルの推論をしようとするとRuntimeError: value type not convertible
というエラーが出ることがあります。
このランタイムエラーというのが曲者で、ようはPythonのOSSライブラリ内のエラーであればスタックトレースが表示されてコードが読めるのですが、
クローズドソースのCore ML内のランタイムではなにが起きているかを推定するのが難しいです。
value type not convertible
の場合は、Inputされた行列のなにかがおかしいと考えられます。
例えば、int32
とint64
を入力してしまっているとかnumpy.ndarray
ではなくtorch.tensor
を入力しているという誤りが考えられます。
また入力がImageType
の場合には、PIL
のImage
型を入力する必要があります。
他にも色々エラーが起こりえますが、どこで起きているかわからないエラーが多いので、
原因箇所の特定にはモデルの層をエラーが出なくなるまで後ろから減らしていくなどのテクが必要となります。
古いiOSでは一部のテンソル演算が使われておらず、なんだかんだでサポート対象のiOSのバージョンが上がってしまう
例えばcumsum
がiOS14以上だったりします。
coremltoolsのサポート体制が薄めな気がする
PRを出したらしっかりレビューしてもらえましたし、実力あるメンバーが開発についていると思いますが、
時間的なリソースがあまり注がれてないのかPRのマージに時間がかかることがあります。
Swiftでの画像などの前処理がつらい
例えばゼロ行列を得るのもそこそこ苦労します。 (実装方法例)
torch
ならtorch.zeros
やtorch.zeros_like
などが使えますが、Core MLのMultiMLArray
ではそのようなものがありません。
回避方法としては、torchモデルになるべく前処理を組み込んで、Swiftではあまりテンソル演算をしないのがよいと思います。
多少の演算をしたい場合は上記のHelperが便利な時があります。
CoreMLのいいところ
つらいところばかり書いてしまいましたが、いいこともあります。
- すでに使われているモデルをそのまま使う分にはそんなにつらくないです
逆に、マイナーなタスクや、マイナーな演算を使いたい場合はそれなりに苦労すると思ってよいです。
- XCode + Swift上での開発体験はいいです
モデルのサイズや概要を表示してくれたり、入出力の変数の型を表示してくれます。
というわけで、以上Core MLについてでした。