こんにちは。アプリケーション共同開発部名古屋開発課の谷口です。 今年も WWDC が開催されましたね!弊社からも 2 名参加しました ( WWDC 2017 から帰国しました #WWDC2017 ) 。
私は機械学習に興味があるのですが、WWDC でも Core ML というフレームワークが新たに公開されました。今回は、こちらを実際に使ってみてわかったことを解説します。
注意
本記事は、ベータ版のドキュメントを参考にしています。今後変更や追加などが予想されますので、Core ML を利用する際は必ず最新版のドキュメントを参照して下さい。
Core ML について
機械学習には、主に2つのフェーズがあります。
- 大量のデータを学習させることでモデルを作成する
- モデルに未知のデータを与えて推論 (分類、予測) を行う
iOS11 SDK の Core ML の登場により、この推論がより簡単にできるようになりました。 これまでも iOS 側で推論を行うための機能は存在しており、iOS10 SDK で以下の2つが追加され話題となりました。
- Accelerate に追加された Basic Neural Network Subroutines(BNNS)
- Metal Performance Shaders に追加された Convolutional Neural Network(CNN)
今回発表された Core ML はそれらの上位層になるフレームワークで、学習済みモデルを、.mlmodel という Core ML が扱う形式に変換することで、Xcode にインポートすることができます。
そもそも、クライアントサイドで推論を行うことは、サーバーサイドで行うことと比較して、
- データを端末内に保持しておける
- ネットワークの使用量を抑えられる
- サーバーサイドに必要なストレージ量を抑えることができる
というメリットがあります。
また、Core ML を使うことで、
- モデルを作成するのに複雑なコードを書かなくて済む
- パフォーマンスチューニングやエネルギー効率改善を自分で行わずに済む
というメリットがあります。
Core ML を利用するにあたって、具体的には、Keras や Caffe のような機械学習フレームワークが出力したモデルから .mlmodel というファイルを作成し、これを Xcode にインポートします。 以下では、.mlmodel ファイルの作成方法を見ていきます。
Keras のモデルから .mlmodel を作る
今回は mnist データセットを使った手書き数字認識を行うための学習を例に、実際に .mlmodel ファイルを生成します。以下は学習を行う python のコードです。
from keras import backend as K from keras.datasets import mnist from keras.utils import np_utils from keras.models import Sequential from keras.layers import Dense, Flatten, Convolution2D, MaxPooling2D from keras.optimizers import Adadelta import coremltools batch_size = 128 num_classes = 10 epochs = 1 img_rows, img_cols = 28, 28 (x_train, y_train), (x_test, y_test) = mnist.load_data() if K.image_dim_ordering() == 'th': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 y_train = np_utils.to_categorical(y_train, num_classes) y_test = np_utils.to_categorical(y_test, num_classes) model = Sequential() model.add(Convolution2D(30, 5, 5, activation='relu', input_shape=input_shape)) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(num_classes, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer=Adadelta(), metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, nb_epoch=epochs, verbose=1, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
.mlmodel ファイルを生成するには、 coremltools というライブラリが必要です。 ここで注意なのですが、このライブラリを使うには (2017/06/21 時点) python 2.7 系、Keras は 1.2.2 、そのバックエンドに使う tensorflow は 1.0 or 1.1 系が必要です。
.mlmodel ファイルを生成するには、上記のコードの末尾に以下のようなコードを追加します。
coreml_model = coremltools.converters.keras.convert(model) coreml_model.save('my_model.mlmodel')
ここでは my_model という名前で .mlmodel ファイルを生成しています。このファイルを Xcode9 にインポートすると、Xcode がコンパイルを行い、そのリソースを使って推論が可能となります。
デフォルトのままだと、入力は配列とみなされます。 以下のようなコードで生成すると、入力を CVPixelBuffer にすることもできます。
coreml_model = coremltools.converters.keras.convert(model, image_input_names='image')
推論結果も同様に、デフォルトでは配列とみなされてしまいます。 以下のようなコードで生成すると、推論結果にラベルをつけることが可能で、こうすると配列から結果を得るステップを飛ばせます。
coreml_model = coremltools.converters.keras.convert(model, input_names='image', image_input_names='image', class_labels=['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'])
最後に
Core ML により、iOS で Deep Learning の推論がより簡単にできるようになりました。また、一緒に発表された Vision との連携も可能です。こちらも試してみたいですね!
参考
フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!
フェンリルの Facebook ページでは、最新トピックをお知らせしています。よろしければいいね!してください!