2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

coremltoolsのドキュメントを参考に、torchvisionにあるMobileNetV2をCoreMLモデルに変換してみます。

実はもうAppleが公開しているCoreMLモデルにMobileNetV2があるのですが、 これと同じモノをどのような手順で作ることができるのか を追ってみようと思います。

とにかくCoreMLモデルを作る

Google Colaboratoryでも手元のMacでもよいので、以下を実行します。

手元のMacで行う場合はminiforgeなどでPython環境を作るのがよさそうです

import torch
import torchvision

# 学習済みMobileNetV2モデルをロード
torch_model = torchvision.models.mobilenet_v2(pretrained=True)

# 推論モードに設定
# https://stackoverflow.com/questions/60018578/what-does-model-eval-do-in-pytorch
torch_model.eval()

# モデルをトレースする
# 入力テンソルはMobileNetV2の仕様に準拠したランダムな値
example_input = torch.rand(1, 3, 224, 224) 
traced_model = torch.jit.trace(torch_model, example_input)
out = traced_model(example_input)

# CoreMLモデルに変換
model = ct.convert(
    traced_model,
    convert_to="mlprogram",
    inputs=[ct.TensorType(shape=example_input.shape)]
)

# CoreMLモデルを保存
model.save("MobileNetV2.mlpackage")

できあがった .mlpackage を開くと以下のような画面が表示されます。

スクリーンショット 2024-01-08 15.45.32.png

中身はよくわかりませんが、モデルの変換はできていそうです。

Appleが公開しているモデルと比較する

Appleが公開している MobileNetV2.mlmodel を開くと Preview というタブがあり、ここに画像を放り込むことでモデル動作検証が行えるようになっています。

スクリーンショット 2024-01-08 15.57.56.png

一方自分で作成した MobileNetV2.mlpackage を開くと Preview タブは表示されません(前項のスクリーンショット参照)。
モデルの概要と Predictions タブの中身を比較すると、以下の違いがあることがわかります。

  • Model TypeNeural Network Classifier でない
  • InputImage(Color 224 x 224) でない
  • OutputDictionary (String → Double) でない

ドキュメントにもあるようにPreview を使えるようにするには上記のフォーマットになるよう変換する必要があります。

Previewできるモデルにする

import torch
import torchvision

torch_model = torchvision.models.mobilenet_v2(pretrained=True)

torch_model.eval()

example_input = torch.rand(1, 3, 224, 224) 
traced_model = torch.jit.trace(torch_model, example_input)
out = traced_model(example_input)

# 分類ラベルをダウンロード
# https://apple.github.io/coremltools/docs-guides/source/convert-a-torchvision-model-from-pytorch.html#download-the-class-labels
import urllib
label_url = 'https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt'
class_labels = urllib.request.urlopen(label_url).read().decode("utf-8").splitlines()
class_labels = class_labels[1:] # remove the first class which is background
assert len(class_labels) == 1000

# 入力をテンソルからImageに変更
# 合わせてtorchvisionモデル用の前処理を追加
# https://apple.github.io/coremltools/docs-guides/source/convert-a-torchvision-model-from-pytorch.html#preprocess-the-image-input-for-torchvision-models
image_input = ct.ImageType(
  name="input_1",
  shape=example_input.shape,
  scale=1/(0.226*255.0),
  bias=[-0.485/(0.229), -0.456/(0.224), -0.406/(0.225)]
)

model = ct.convert(
    traced_model,
    # Model Type: Neural Network Classifier
    convert_to="neuralnetwork",
    # Input: Image(Color 224 x 224)
    inputs=[image_input],
    # Output: Dictionary(String → Double)
  	classifier_config=ct.ClassifierConfig(class_labels)
)

model.save("MobileNetV2.mlpackage")

スクリーンショット 2024-01-08 15.59.27.png

今度は Preview タブが表示されるようになりました!
試しに画像を放り込んでみると、分類がうまくいっていないだけでなく、なぜか100%を超えちゃっています🤔

出力の正規化

これは torchvisionモデルが、出力の正規化を行っていないことが原因 でした。
https://pytorch.org/hub/pytorch_vision_mobilenet_v2/
なので、以下のようにモデル出力の後にSoftmax関数を追加し、正規化された出力を得られるようにします。

torch_model = torch.nn.Sequential(
    torch_model,
    torch.nn.Softmax(dim=1)
)

これで変換したCoreMLモデルで試してみると、今度は100%を超えないようになりました!
結果や精度もAppleのものに近いので問題なさそうです。

スクリーンショット 2024-01-08 15.56.40.png

おわりに

とりあえず既存モデルをcoremltoolsを使ってCoreMLモデルに変換できることと、その際の注意点を理解できました。これで転移学習やファインチューニングなりで作ったカスタムモデルでも、同じワークフローでCoreMLモデルを作り出すことができそうです。

また別の記事で、カスタムモデルとVision Frameworkを使った事例を紹介しようと思います。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?