Kerasで作成したCore MLモデルの入力の型を変更する

次のように普通にKerasでMNISTモデルをつくってcoremltoolsでCore MLモデルに変換すると、入力の型が`multiArrayType`(Core MLでは`MLMultiArray`)になる。

(Kerasでモデル構築)

def create_keras_base_model(url):    
   import keras
   from keras.models import Sequential
   from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
   
   keras.backend.clear_session()
   model = Sequential()
   model.add(Conv2D(32, kernel_size=(3, 3),
                    activation='relu',
                    input_shape=(28, 28, 1)))
   model.add(Conv2D(64, (3, 3), activation='relu'))
   model.add(MaxPooling2D(pool_size=(2, 2)))
   model.add(Dropout(0.25))
   model.add(Flatten())
   model.add(Dense(128, activation='relu'))
   model.add(Dropout(0.5))
   model.add(Dense(10, activation='softmax'))
   model.compile(loss=keras.losses.categorical_crossentropy,
                 optimizer=keras.optimizers.SGD(lr=0.01),
                 metrics=['accuracy'])
   model.save(url)
keras_model_path = './KerasMnist.h5'
create_keras_base_model(keras_model_path)

(coremltoolsで`.mlmodel`ファイルに変換)

def convert_keras_to_mlmodel(keras_url, mlmodel_url):
   from keras.models import load_model
   keras_model = load_model(keras_url)
   
   from coremltools.converters import keras as keras_converter
   class_labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
   mlmodel = keras_converter.convert(keras_model, input_names=['image'],
                               output_names=['digitProbabilities'],
                               class_labels=class_labels,
                               predicted_feature_name='digit')
   
   mlmodel.save(mlmodel_url)
    
coreml_model_path = './MNISTDigitClassifier.mlmodel'
convert_keras_to_mlmodel(keras_model_path , coreml_model_path)

(作成したモデルの入力形式を確認する)

import coremltools
spec = coremltools.utils.load_spec(coreml_model_path)
builder = coremltools.models.neural_network.NeuralNetworkBuilder(spec=spec)
builder.inspect_input_features()

出力結果:

[Id: 0] Name: image
         Type: multiArrayType {
 shape: 1
 shape: 28
 shape: 28
 dataType: DOUBLE
}

形状が1x28x28、値がDOUBLE型の`multiArrayType`ということで、このままだといろいろとめんどくさい

たとえば入力型が画像じゃないと、Visionで扱えないので、Core ML単体で扱うことになる。

`MLMultiArray`の扱いは慣れてないと色々と戸惑うかもしれない。

というわけで、画像型に変更する方法が以下:

ここから先は

855字 / 1画像
文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/