【ITニュース解説】The CoreML Model Was Fine. The Photo Was Too Big.
2026年10月13日に「Dev.to」が公開したITニュース「The CoreML Model Was Fine. The Photo Was Too Big.」について初心者にもわかりやすく解説しています。
ITニュース概要
デバイスで家畜を数えるアプリで、高解像度写真をそのまま画像認識モデルに入力すると、対象が小さくなり認識精度が低かった。これはモデルの問題ではなく、画像縮小で情報が失われたため。画像を複数に分割し、それぞれをモデルで認識させ結果を統合することで、精度が大幅に向上した。モデルを疑う前に、入力画像処理を見直すことが重要だ。
ITニュース解説
スマートフォンなどのデバイス上でAI(人工知能)を活用したアプリケーションを開発する際、AIモデル自体は正しく機能しているにもかかわらず、期待通りの結果が得られないという状況に直面することがある。これは、モデルに入力されるデータ、特に画像データが、モデルの能力を十分に引き出せる形で準備されていないことが原因である場合が多い。
とある開発者は、Appleが提供する機械学習フレームワーク「CoreML」と、高速な物体検出アルゴリズムである「YOLO」を組み合わせて、スマートフォン上で家畜の数を数えるアプリを開発していた。このアプリは、インターネット接続なしでデバイス単体で動作するため、現場での利便性が高いという特徴を持つ。当初、開発者は画像をモデルに渡すための一般的な方法を採用していた。具体的には、Appleの画像処理フレームワークであるVisionを用いて、機械学習モデルに対するリクエストを作成し、画像をモデルが処理できるサイズに自動的に縮小して入力するように設定していた。この「imageCropAndScaleOption = .scaleFit」という設定は、画像全体がモデルの入力サイズに収まるように、縦横比を保ちながら自動的に縮小するという意味である。
しかし、このアプリを広大な牧草地で撮影された実際の写真、およそ250頭の羊が写っている12メガピクセルの高解像度画像でテストしたところ、検出された羊の数はわずか14頭という結果だった。これは明らかに、実際の羊の数と大きくかけ離れており、問題があることを示していた。開発者は当初、AIモデルそのものに原因があるのではないかと考えたが、調査の結果、問題はモデルの性能ではなく、モデルに画像が与えられるまでの「画像パイプライン」、つまり画像の前処理方法にあることが判明した。
12メガピクセルの広大な牧草地の写真を、モデルの入力サイズに合わせて全体を収めるように大きく縮小した結果、遠方に写っている小さな羊たちは、画像上でわずか数ピクセル程度の点にまで小さく潰れてしまっていた。このような極端に小さい物体は、どんなに高性能なAIモデルであっても、特徴を認識し、羊として検出することは困難である。モデルは与えられたピクセル情報に基づいて判断するため、十分な情報がなければ正しく認識できないのは当然のことであった。
この問題の解決策として、開発者はAIモデル自体を再学習させたり、より複雑なモデルに置き換えたりするのではなく、画像パイプラインの改善に着目した。採用されたのは「タイリング(Tiling)」と呼ばれる手法である。この手法は、元の高解像度画像を一度だけ全体として処理するだけでなく、その画像を複数の小さな領域(タイル)に分割し、それぞれのタイルを個別にモデルに入力して処理するというものだ。この時、タイル同士が少しだけ重なるように設定することで、タイルの境界線で物体が分断されてしまうリスクを低減する。具体的には、元の画像を一度全体で処理するパスに加えて、例えば4:3の画像であれば、横方向に3分割し、それぞれに0.25(25%)の重なりを持たせることで、複数のタイルが生成される。この記事の例では、全フレームのパスと合わせて合計13回の推論(モデルの実行)が行われることになる。
このように画像を分割して個別に処理することで、AIモデルは元の画像を大きく縮小された状態で見るのではなく、各タイル内では比較的大きなスケールで物体を見ることが可能となる。その結果、遠くの小さな羊も、いずれかのタイル内では十分なピクセル数を持って表現され、モデルが認識できるようになるのである。
タイリング処理の後のステップも重要である。各タイルで検出された物体の位置情報(バウンディングボックス)は、タイル内の座標で示されているため、これらを元の画像全体の座標系に変換し直す必要がある。また、タイルの端で物体が途切れて検出されたバウンディングボックスは、信頼性が低いため除外される。最後に、複数のタイルから得られた多くの検出結果の中から、同じ物体が重複して検出されないように統合する処理が必要となる。この統合には「NMS(Non-Maximum Suppression)」という技術が使われる。通常のNMSは、バウンディングボックスの重なり具合を「IoU(Intersection over Union)」という指標で判断し、重なりが大きいものを抑制する。しかし、タイリングの場合は、羊の頭だけが検出されたバウンディングボックスが、羊全体を囲むバウンディングボックスの中に含まれていても、IoUだけでは重なりが小さいと判断され、重複してカウントされる可能性があった。このため、開発者は「Intersection-over-smaller」という、より厳密な重なり判断基準も採用した。これは、2つの領域の重なりを、小さい方の領域の面積で割ることで、より細かい重複も検出できるようにする手法だ。さらに、同じ羊が異なるタイルや処理で、異なるクラス(例えば「若い羊」と「大人の羊」)として検出される可能性も考慮し、クラスに依存しない「class-agnostic NMS」を用いることで、確実に同じ羊を一度だけカウントするようにした。
このタイリングによる画像パイプラインの改善によって、元々14頭しか検出できなかった牧草地の羊が、173頭も検出されるようになった。これはまだ完璧な数ではないものの、アプリが実用レベルに達する劇的な改善である。また、元々適切に検出できていた近距離の鶏の写真では、検出数が必要以上に増えることもなく安定していた。これは、今回の修正が、画像のスケールが問題となっていたケースで特に有効に働き、すでに問題なく検出できていたケースには悪影響を与えなかったことを意味する。
この一連の経験から得られる重要な教訓は、AIモデルの性能が期待外れだった場合、まず疑うべきはモデルそのものではなく、「モデルにどのようなデータが入力されているか」という点である。特に、スマートフォンなどのデバイス上で動作するAIアプリケーションにおいては、モデルの構造や学習データを変更することは難しい場合が多い。その一方で、画像がモデルに渡されるまでの前処理、すなわち「画像パイプライン」は、比較的柔軟に変更することが可能であり、この部分を最適化することで、大きなコストをかけることなく、AIアプリケーションの性能を飛躍的に向上させられることが少なくない。