花サーチは、カメラで撮影した花・植物をオンデバイスで認識するiOSアプリです。ネットワーク接続不要で、写真が端末外に送信されない設計にこだわりました。その内部実装を紹介します。

目次


認識モデルは独自学習

花サーチの認識モデルは、日本で身近な花・野草・樹木・野菜 622 種(公開版 1.0 時点)を対象に、このアプリのために独自に学習したものです。

当初は Hugging Face で公開されている汎用の花分類モデルを組み込んでいましたが、App Review で「他の開発者のアプリと類似している」と指摘を受けました。調べてみると、そのモデルは公開元自身が App Store に出しているアプリでも使われており、アプリ内のUIや機能をどれだけ独自実装しても「同じアセットを同梱している」と見なされる状況でした。この経験から、認識モデルそのものを自前で用意する方針に切り替えています。


Vision FeaturePrint + 独自の分類層という構成

新しいモデルは次の2層構成です。

  1. 特徴抽出: iOS に内蔵されている Vision フレームワークの FeaturePrint.Scene(画像を 768 個の数値からなる特徴ベクトルに変換する OS 標準の機能)
  2. 分類層: その特徴ベクトルを 622 クラスに振り分けるロジスティック回帰(ソフトマックス回帰)

特徴抽出器が OS 側にあるため、アプリに同梱するのは分類層だけです。旧構成では特徴抽出器 52MB + 分類ヘッド 22MB を同梱していましたが、新モデルは 約 2MB に収まり、アプリ全体でも約 5MB です。第三者製の学習済み重みはアプリから完全になくなっています。

最初は Create ML の MLImageClassifier で学習していましたが、種数が数百に増えると学習のたびに全画像の特徴抽出をやり直すのが重くなったため、途中から「特徴ベクトルを一度ファイルに書き出し、分類層だけを numpy で学習する」方式に切り替えました。こうすると、種を数種追加したときも差分の画像だけ特徴抽出すればよく、再学習は数分で終わります。反転・切り出しの簡単なデータ増強も特徴ベクトルの段階で行い、最後に coremltools で Core ML モデルに書き出しています。

学習に使っていないテスト画像 16,000 枚あまりでの正解率は、上位 1 候補で 70%、上位 3 候補に正解が含まれる割合で 84% でした(花だけに限ると 78% / 89%)。似た花同士の取り違えはどうしても残るため、アプリでは上位 3 候補を表示し、確信度が低いときは断定せずに「該当する花が見つかりませんでした」と候補だけを示します。同じ属の種で確信度が割れたときは「ワスレグサ属(ノカンゾウ/ヤブカンゾウ/ゼンテイカ)」のように属名でまとめて表示します。


対象種の選び方

1万種以上を扱う汎用モデルから、あえて 622 種に絞りました。理由は2つあります。

  • 日本のユーザーが実際に出会う花に集中できる: 桜・梅・アジサイ・ヒガンバナのような季節の花、タンポポ・カタバミ・ヒメジョオンのような道端の草花、ニッコウキスゲ・ミズバショウ・コマクサのような高原や湿原の山野草、園芸店の花に加えて、春と秋の七草、イチョウ・ケヤキなどの街路樹や庭木、野菜・ハーブ、トリカブトのような注意が必要な植物まで横断的に選びました。学名の羅列ではなく、和名で「あの花だ」と分かる範囲を狙っています。
  • 候補が絞られるほど当たりやすい: 分類先が少なければ、似た花と取り違える機会もそれだけ減ります。

種リストはテキストファイル1枚で管理していて、追加・削除して再学習すれば対応種を変えられます。園芸品種(バラの品種など)は写真から区別が難しいため、種または属レベルにまとめています。


学習データの集め方

学習写真は市民科学プラットフォーム iNaturalist の公開 API から集めました。条件は次の通りです。

  • クリエイティブ・コモンズ・ライセンス(CC0 / CC BY / CC BY-NC など)が付いた写真のみ
  • コミュニティによって同定が確定した「研究品質(Research Grade)」の観察のみ
  • 「開花中」のアノテーションが付いた観察を優先し、不足分だけアノテーション無しで補う
  • 1つの観察からは写真を1枚だけ採用し、同じ個体・同じ撮影者に偏らないようにする

こうして集めた約 158,800 枚を 85:15 に分けて学習と評価に使いました(評価用の写真は固定し、種を増やしても同じ写真で比較できるようにしています)。写真の出典とライセンスは一覧ファイルに記録しています。写真そのものはアプリには含まれません。


顕著性検出によるトリミング補助

花の認識精度は、対象物が画像内でどれだけ大きく写っているかに強く依存します。背景が多いと余計な情報がノイズになり、誤判定につながります。

そこで、撮影・選択した画像から花の部分だけを自由な矩形で切り出せるトリミング機能を用意しました。トリミング画面を表示した直後、Visionの顕著性検出機能(画像のどこに視線が集まりやすいかをAIが推定する機能)を非同期で走らせ、検出に成功すれば初期のトリミング範囲を花の位置に自動で合わせます。検出できない場合は画像周囲15%を切り取った範囲を初期値にします。

自動トリミングはあくまで初期値で、その後手動での調整も可能にしています。全自動にしすぎず、モデルが外した場合にユーザー側で補正できる余地を残すことを重視しました。


苦労した点

一番大きかったのは、モデルを「借りる」のをやめて「作る」に切り替えた判断です。汎用モデルは対応種数では圧倒的でしたが、アプリの独自性という観点では弱点になりました。自前で学習してみると、対象を絞ったことで和名表示や種の選定にアプリとしての意図を込められるようになり、結果的に「日本の身近な花の図鑑」というコンセプトがはっきりしました。

もう1つはデータ収集です。API のレート制限を守りながら数百種分の写真を集めるには時間がかかりますが、Python 標準ライブラリだけで書いたスクリプトで再実行可能にしておいたことで、種リストを見直すたびに差分だけ取り直せるようになりました。

オンデバイス推論・トリミング補助・独自学習のどれも地味な積み重ねですが、電波のない野外でもその場で花の名前にたどり着けるようになったときは手応えがありました。画像認識モデルを組み込んだアプリ開発の参考になれば幸いです。


追記: 1.0 公開と次のバージョン

2026 年 10 月 2 日、バージョン 1.0 が App Store で公開されました。App Store で見る

公開後の次のバージョンでは、ユーザーが実際に撮った写真でうまく認識できなかった高山のリンドウ類(ミヤマリンドウ・トウヤクリンドウ・コケリンドウ・オヤマリンドウ)を学習対象に加えて 626 種にし、撮らなくても名前や季節から花を探せる「図鑑」タブを準備しています。図鑑の写真は iNaturalist の CC ライセンス写真を Wi-Fi 接続時に取得して端末に保存し、解説は Wikipedia 日本語版(CC BY-SA)を出典付きで載せる構成です。