MicrosoftのAIをカスタマイズしてハンバーガーとチーズバーガーを区別させよう:特集:AIをアプリに組み込もう(3/3 ページ)
Custom Vision Serviceを使うと、独自の画像認識機能をプログラマーが簡単に作成し、AIにハンバーガーの見分けが付くかを試してみよう。
クラスライブラリを利用するコード
上のコードは.NET Standard 2.0ベースのクラスライブラリとして記述したものだ。よって、これをサポートするバージョンの.NET実装であれば、これを使用できるということ。例えば、.NET Framework 4.7をターゲットとしたコンソールアプリの例を以下に示す。
static async Task Main(string[] args)
{
Console.Write("画像ファイルのパス: ");
string imageFilePath = Console.ReadLine();
var result = await DetectHamburger(imageFilePath);
if (result.Predictions == null)
Console.WriteLine("判別できませんでした");
foreach (var item in result.Predictions)
{
Console.WriteLine($"{item.Tag}の可能性: {item.Probability:P3}%");
}
Console.ReadKey();
}
これを実行すると、例えば次のようになる。
また、以下のような画面デザインのUWPからも、上で作成したクラスライブラリを経由して、カスタマイズしたモデルのAPIを呼び出せる。
コードビハインドだけを以下に示す(XAMLコードは省略)。
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void fileOpenButton_Click(object sender, RoutedEventArgs e)
{
// FileOpenPickerインスタンス(openPicker)を生成し、ファイルを選択してもらう
var openPicker = new FileOpenPicker()
{
// 省略
};
openPicker.FileTypeFilter.Add(".jpg");
// ……
var file = await openPicker.PickSingleFileAsync();
if (file == null) return;
await ShowImage(file);
resultText.Text = "判別中……";
await MakeRequest(file);
}
private async Task ShowImage(StorageFile file)
{
// Imageコントロールにローカルファイルの画像を表示
}
private async Task MakeRequest(StorageFile file)
{
// StorageFileクラスからバイト配列を生成
byte[] byteData = null;
using (IRandomAccessStream stream = await file.OpenReadAsync())
{
byteData = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(byteData);
}
}
// クラスライブラリに定義したDetechHamburgerメソッドを呼び出し
var result = await DetectHamburger(byteData);
ComposeMessage(result);
}
private async void urlOpenButton_Click(object sender, RoutedEventArgs e)
{
// URLで指定された画像をImageに表示
// ……
resultText.Text = "判別中……";
var result = await DetectHamburgerUrl(urlTextBox.Text);
ComposeMessage(result);
}
private void ComposeMessage(CustomVisionSvc.CustomVisionResponse result)
{
// 画面最下部に表示する判定メッセージの作成
}
}
サンプルということもあり、ここでは[File]ボタンと[Url]ボタンがクリックされたら、指定されたローカル画像または画像URLを基に、Imageコントロールにそれを表示してから、画像の判定を行うコードを呼び出しているだけだ。ただし、UWPのStorageFileクラスは.NET Standard 2.0には含まれていないことなどから、自前でStorageFileクラスのインスタンスを基にバイト配列を作成して、それをメソッドに渡すようにしている(UWPからStorageFileクラスのインスタンスではなく、そのファイルパスをクラスライブラリに渡してみたところ、アクセス拒否例外が発生したので、深く考えずに自前でバイト配列を作成しているともいう)。
WPFアプリも作成したが、こちらは素直にファイルパスをDetectHamburgerメソッドに渡せばよい。そこを除けば、両者のコードは同様なものだ(Windows Formsアプリは作成していないが、まあ似たようなものだろう)。
動作確認
ここまで書いて、アプリの実行結果をキャプチャーするためには、もう一度マクドナルドのお世話になる必要があることに気が付いた(上の画像は撮影した画像をトリミング/サイズ変更したものなので、そりゃそういう結果になるだろうという気がするからだ)。
そういうわけで、マクドナルドでハンバーガーを今度は2つだけ購入した。もちろん、ハンバーガーとチーズバーガーである(店内で撮影および実食)。このデータを使って、検証をした結果が以下だ。
チーズバーガーの判定について見てみると、右側のキャプチャーではチーズバーガーを見事にハンバーガーと間違えている。「チーズの存在を明確に認識できる」場合にはチーズバーガーだと推測できるようだが、チーズが見えているところがわずかだったり、バンズと重なって色が分かりにくかったりすると判定に失敗するのだと思われる。この辺を解決するには、さらに多くの画像データの学習が必要なところだろう。ハンバーガーについても自信満々の解答とは思えない。
とはいえ、上で述べたような手順でCustom Vision Serviceのコンソール画面から再度学習をすれば、推測の精度はある程度は高まっていくはずだ。
なお、「ハンバーガーとチーズバーガーを区別できるか」という設問については、今回は「できるような、できないような」と言葉を濁して終わろうと思う(それでいいのか)。
本稿ではCustom Vision Serviceを使って、画像認識機能をカスタマイズしながら、ハンバーガーとチーズバーガーを区別できるかを見てきた。その過程で次のようなことが分かった。
- 画像の学習はとても簡単(だが、精度を出せるようにするには、似た画像だけでは難しいようだ)
- .NET Standard 2.0ベースのクラスライブラリに、APIアクセスを行うコードをまとめることで、さまざまなアプリに簡単に画像認識機能を追加できる
「AIとか機械学習とか……面倒くさそう」という方であっても、Microsoftをはじめとする企業や組織が提供しているAPIを活用することで、取りあえずのスタート地点には立てるのではないだろうか。
なお、Custom Vision Serviceにはプログラムから学習を行うためのAPI、カスタマイズしたモデルをモバイルデバイスにエクスポートする機能などもある。特に後者であれば、モバイルデバイスで写真を撮って、すぐさま「これは?」と問い合わせるといったアプリの実装に役立つだろう(マクドナルドのハンバーガーでは意味がなさそうだが、通りすがりに見掛けた鳥や花が何かを簡単に判別するといった使い道があるはずだ)。機会があれば、これらについても紹介するつもりだ。
最後に「一度にそれなりの量のデータを取りたい」からといって、一度にハンバーガーを8個も消費するのはよくない。ここまで読んだ皆さんは絶対にそんなことはしないようにしよう。
Copyright© Digital Advantage Corp. All Rights Reserved.