Swift Playgroundsで学ぶiOSプログラミング

iPadで機械学習を利用するプログラムを作る

文●柴田文彦 編集●吉田ヒロ

2018年05月02日 17時00分

モデルクラスをコピーして書き換える

 ここで1つの前の図、Xcodeでモデルを選択した図をもう一度見てください。中央付近に「Model Class」という領域があり、「MarsHabitatPricer」というクラス名が表示されています。よく見ると、その名前の右に右矢印ボタンがあります。それをクリックしてみましょう。

 すると、このモデルから自動生成したクラスのソースコードが表示されます。

Xcodeでは、プロジェクトに含まれるCore MLモデルファイルからそれをクラスとして利用するためのソースコードを自動生成することができます。今回は、このコードの一部を除いてほぼそのままコピーして利用します

 Xcodeでアプリをプログラムする際には、このソースコードを参照しながらそのクラスを利用するためのコードを書けばいいわけです。Swift Playgroundsには、XcodeのようにCore MLモデルからソースコードを生成する機能はありません。そこで、このXcodeが表示したコードをコピーしてプレイグラウンドのプログラムに張り付けて使うことにします。実際には、このコードは多くのコメントを含んでいるので、それらは省いて構いません。MacでXcodeが使える人は、iCloud Driveをうまく使ってiPad上で作成したプレイグラウンドのファイルをMacで開き、Xcodeからコピーしたソースをペーストしてもいいでしょう。

 いずれにしても、このモデルクラスの定義を上から順に見ていくことにします。この中には3つのクラスが定義されています。上から順に、MarsHabitatPricerInput、MarsHabitatPricerOut、MarsHabitatPricerの3つです。それぞれ、パラメータの入力、結果の出力、予想を実行するためのものだとわかります。

 まずはMarsHabitatPricerInputクラスの定義の先頭部分です。

iPadのプレイグラウンド上のソースコードにXcodeからコピーしたCore MLモデルのクラスのソースコードを入力します。まずは、パラメータの入力に関するMarsHabitatPricerInputクラスの前半です

 入力する3つのパラメータ、solarPanels、greehouses、sizeそれぞれの型がわかります。アプリ側は、それらに従って引数を与えればいいのです。

 MarsHabitatPricerInputクラスの後半は、パラメータとして設定した値を確認するためのメソッドと、このクラス自身を初期化するinitメソッドが定義されています。

同じMarsHabitatPricerInputクラスの後半です。このクラスに続くMarsHabitatPricerOutputクラスの先頭部分も見えています

 2つめのMarsHabitatPricerOutクラスの定義も、入力用のクラスと同様です。

Core MLモデルからの出力の仕様を定義するMarsHabitatPricerOutputクラスです。基本的な構造は入力用のクラスとほぼ同じです。コメントは削除してありますが、ここまではコードに手を加える必要はありません

 3つめのMarsHabitatPricerクラスが、このモデルの本体ということになりますが、ここには注意すべき記述が登場します。

Core MLモデルの本体とも言えるMarsHabitatPricerクラスの先頭部分です。ここには、コンパイルしたCore MLモデルファイル「MarsHabitatPricer.mlmodelc」を読み込むコードがありますが、この部分は変更する必要があります

 それはCore MLのモデルファイルを読み込んで、自分自身を初期化するコードです。この部分をよく見ると、モデルファイルの拡張子が「mlmodelc」となっています。すでに示したように、元の拡張子は「mlmodel」でした。つまり「c」が後ろに付いていますが、これはコンパイルされたファイルであることを示しています。Xcodeでは、プロジェクトに含まれる元のモデルファイル(.mlmodel)を、自動的にコンパイルした結果のファイル(.mlmodelc)から、MLモデルのオブジェクトを生成しているのです。

 このMarsHabitatPricerクラスの定義コードを利用するには、あらかじめモデルファイルをコンパイルしておく必要があることを意味しています。実は、Xcodeのコマンドラインツールを使えば、手動でMLモデルをコンパイルすることができます。しかし、Xcode環境を持っていない人は、その機能を利用できません。それでは、iPadのSwift Playgroundsだけを利用している人は、CoreMLを利用できないのでしょうか?

 今回あれこれ検討した結果、なんとCoreML自身にモデルクラスをコンパイルする機能が含まれていることに気付きました。MLModelのクラスメソッドcompileModelです。このメソッドに元のMLモデルのURLを与えてやればコンパイル後のモデルを得ることができます。さらにそれを使ってモデルクラスを初期化することも可能となります。

 その部分を適宜書き換えたMarsHabitatPricerクラスの定義の前半を示します。

コンパイルする前の元のCore MLモデルファイル「MarsHabitatPricer.mlmodel」をコンパイルしながら読み込むコードに変更したMarsHabitatPricerクラスの前半部分です。こうすることで、モデルファイルさえ用意すれば、Swift Playgrounds単独でCore MLモデルが利用できるようになります

 後半のpredictionメソッドの定義は、自動生成された元のコードのままで機能します。

機械学習の成果から、実際に予想値を得るためのpredictionメソッドの定義です。パラメータの与え方によって2とおりの定義がありますが、実質的には同じものです。これからわかるのは、肝心の機械学習の成果を利用する部分はブラックボックスだということです

火星に住むための環境を整えるコストを計算する

 上の図の最後にクラス定義の外に3行だけの短いコードがありますが、それがいわば今回のアプリの本体です。そこでは、まずMarsHabitatPricerクラスのオブジェクトを作成し、そのオブジェクトのpredictionメソッドに3つのパラメータを与えて予想結果を引き出します。その結果に含まれるpriceプロパティが、火星基地を作るための金額の予想値です。

 このプログラムを実行する前に、あと1つだけやるべきことがあります。このプレイグラウンドにモデルファイルを読み込むことです。これまでのように、画像ファイルを追加するのと同じ方法で、「+」ボタンをタップしてiCloud Driveから読み込んでください。

プログラムを実行する前に、アップルのサイトからダウンロードしたサンプルプロジェクトに含まれていたCore MLのモデルファイルをiCloud Driveからプレイグラウンドに取り込んでおきます。方法は画像ファイルを取り込むのとまったく同じです

 もちろんその前に、アップルからダウンロードしたプロジェクトに含まれるモデルファイルをiCloud Driveにコピーしておく必要があります。プログラムの変更によってコンパイル前のファイルを読み込むようにしてあるので、手動のコンパイル操作などは不要です。プロジェクトに含まれる「MarsHabitatPricer.mlmodel」をそのまま利用します。

 このプログラムの実行結果、つまり金額の予想値はプレイグラウンドのデバッグ機能を使って確認しましょう。

今回のプログラムではユーザーインターフェースを何も用意しなかったので、入力のパラメータはプログラムのメソッド呼び出しの引数として直接指定し、実行結果はプレイグラウンドのデバッグ機能を使って確認します。上で示したXcodeのシミュレータによる実行結果と一致していることが確かめられます

 結果は16903.769となっています。単位は百万ドルです。入力パラメータを上で示したXcodeで作成したアプリの実行結果と同じにしてあるので、結果も一致していることが確かめられるでしょう。

次回の予定

 今回は、プレイグラウンド上でCoreMLを使って、とりあえず機械学習の成果を利用するための手順を確認できました。今回の操作でなんとなくわかったと思いますが、CoreMLは肝心の機械学習の成果に関する部分は完全なブラックボックスとして扱います。次回は、また別のモデルを使って、機械学習の成果を確かめることにしましょう。今回は目をつぶっていたユーザーインターフェースも用意して、それなりに役立つアプリ風のプログラムにすることを目指します。

■今回作ったプログラム

mobileASCII.jp TOPページへ