MENU

問い合わせ


    【YOLOで作る画像認識ツール 第11回(最終回)】運用の注意点とライセンス(AGPL-3.0):精度の低下に気づく仕組みと、連載のまとめ

    前回の第10回では、APIをDockerで動かす形を整えました。最終回の今回は、動かし始めたあとに何が起きるかと、ライセンスを整理し、連載全体をまとめます。

    画像認識は、作って終わりではありません。撮影条件が少し変わるだけで、結果が変わることがあります。その変化に、気づける仕組みが必要です。

    目次

    この回で作るもの

    • 稼働後の変化(精度の低下のきざし)を記録・判定する app/monitor.py
    • 撮影条件の変化で、結果がどう変わるかを試す tools/drift_demo.py

    稼働後の精度は「直接は測れない」

    第6回では、正解データと突き合わせて精度を測りました。しかし、稼働後の本番の写真には、正解がありません。全部に正解を付けていては、AIを使う意味がなくなります。

    そこで、正解がなくても測れる変化のきざしを記録します。

    • 1回の処理で見つかった件数
    • 信頼度の平均
    • 何も見つからなかった画像の割合

    「普段と違う」ことに気づければ、原因(照明・カメラ・対象の変化)を調べるきっかけになります。

    実装

    集計して記録する

    # app/monitor.py(抜粋)
    @dataclass(frozen=True)
    class RunStats:
        images: int
        detections: int
        mean_confidence: float | None  # 何も見つからなければ None
        empty_images: int  # 何も見つからなかった画像の数
    
    
    def summarize(per_image: list[list[Detection]]) -> RunStats:
        confidences = [d.confidence for detections in per_image for d in detections]
        return RunStats(
            images=len(per_image),
            detections=len(confidences),
            mean_confidence=round(statistics.fmean(confidences), 3) if confidences else None,
            empty_images=sum(1 for detections in per_image if not detections),
        )

    記録は、1行1件の形式(JSON Lines)で追記します。画像のファイル名や中身は残しません。

    「普段」との違いを判定する

    # app/monitor.py(抜粋)
    def check_drift(baseline, current, confidence_drop=0.10, empty_rate_rise=0.20, count_drop_ratio=0.30) -> list[str]:
        """普段(baseline)と比べて、気になる変化があれば、その内容の一覧を返す。空なら問題なし。"""
        warnings: list[str] = []
        ...  # 信頼度の平均の低下、何も見つからない割合の増加
        # 信頼度の平均だけでは、自信の低い結果が消えて平均が上がる場合に気づけない。1枚あたりの検出件数も見る
        base_count = baseline.detections / baseline.images if baseline.images else 0.0
        now_count = current.detections / current.images if current.images else 0.0
        if base_count > 0 and (base_count - now_count) / base_count >= count_drop_ratio:
            warnings.append(f"1枚あたりの検出件数が減っています({base_count:.1f} → {now_count:.1f})")
        return warnings

    3つの見方を組み合わせているのは、1つだけでは見落とすためです。実際にそうなった例を、次で見ます。

    動かして確かめる:撮影条件が変わったら

    サンプル写真に、2種類の変化を加えて、結果を比べます。

    • 明るさ:照明が暗くなった想定
    • JPEG画質:カメラやアプリの設定で、画像の圧縮率が変わった想定
    python tools/drift_demo.py

    開発環境での結果です(基準は、元の写真をPNG=圧縮による劣化のない形式で保存したもの)。

    条件                      件数      信頼度の平均  気になる変化
    基準(変化なし・PNG)             4       0.613  -
    明るさ 0.5倍                 4       0.638  -
    明るさ 0.3倍                 3       0.629  -
    JPEG 画質 75               2       0.762  1枚あたりの検出件数が減っています(4.0 → 2.0)
    JPEG 画質 30               0           -  信頼度を出せるだけの検出がありません(何も見つかっていません); 何も見つからない画像の割合が増えています(0% → 100%); 1枚あたりの検出件数が減っています(4.0 → 0.0)
    JPEG 画質 10               1       0.309  信頼度の平均が下がっています(0.613 → 0.309); 1枚あたりの検出件数が減っています(4.0 → 1.0)

    意外な結果でした。

    • 明るさの変化:この写真では、0.5倍まではほぼ変わらず、0.3倍でも検出が1件減った程度でした。暗さの影響は、思ったより小さい結果でした(写真や対象によって変わるはずで、この結果を一般化はできません)
    • JPEG画質の変化:画質75(多くのカメラの標準に近い値)に再保存しただけで、検出が4件から2件に減りました。画質30では、何も見つかりませんでした

    「画質を少し変えただけ」で、結果が大きく変わりました。 カメラの設定変更、写真を送るアプリの圧縮、撮影担当者の交代などが、本番では実際に起こります。

    さらに、画質75の行に注目してください。信頼度の平均は、0.613から0.762に上がっています。 自信の低い結果が消えたために、残った結果の平均が上がったのです。もし信頼度の平均だけを見ていたら、この変化に気づけません。検出件数も一緒に見ているから、気づけました。

    テスト

    pytest -q      # 37件成功
    ruff check .   # 問題なし

    集計、変化の判定(信頼度の低下・何も見つからない割合の増加・件数の減少)、信頼度が上がっても件数の減少を拾えること、記録が追記されることを確認しています。

    ライセンスの整理(AGPL-3.0と商用ライセンス)

    第0回でも触れたとおり、Ultralytics(YOLO)は、オープンソースのライセンス「AGPL-3.0」で公開されています。公式のREADMEでは、商用利用のためのライセンスとして「Ultralytics Enterprise License」も案内されています。

    📰 出典:Ultralytics 公式リポジトリ README(ライセンスの項)

    一般的には、AGPL-3.0のソフトウェアを、ネットワーク越しにサービスとして提供する場合、そのソフトウェアを使ったシステムのソースコードの公開が求められることがあると説明されます。ただし、自社のシステムがこれに当たるか、商用ライセンスが必要かは、使い方(社内だけか、社外に提供するか等)によって変わります。この記事では、個別の判断はしません。契約・法務の担当者や、専門家、提供元に確認してください。

    発注のときは、次の点を、開発会社に確認するのが現実的です。

    • どのAIモデル・ライブラリを使い、それぞれのライセンスは何か
    • 商用ライセンスが必要な場合、その費用は誰が負担し、契約は誰の名義か
    • ライセンスの対応が必要になった場合に、別のモデル(ライセンスの条件が異なるもの)に切り替える選択肢はあるか

    この連載のまとめ:全12回で分かったこと

    回学んだこと
    0〜1学習済みモデルは数日で動く。ただし、知らない対象は間違える。信頼度のしきい値で、見逃しと誤検出が入れ替わる
    2〜3画像に描いて確認する。信頼度が高くても間違う。数える業務は、撮影ルールまで設計が要る
    4〜5APIと画面にして初めて、現場で使える。認証・外部通信の確認が必要
    6精度は、適合率と再現率で測る。テスト用の正解付き写真は、発注者が用意する
    7追加学習は、データの量・質で決まる。検証の数字だけで安心してはいけない
    8AIを100%信じず、人が確認する設計にする。自信が高い間違いは、しきい値では防げない
    9〜10速度・構成は、枚数と応答時間で決まる。変換しても、再評価が必要。運用の準備(ログ・ヘルスチェック)
    11稼働後は、変化に気づく仕組みが必要。ライセンスは、事前に確認する

    「精度○%」より先に決めること

    連載を通して、画像認識の発注で大切なのは、AIの選び方よりも、次のような発注者側の準備だと分かりました。

    1. 何を判定したいか、写真つきで具体的に決める
    2. 現場で撮った、テスト用の正解付き写真を用意する
    3. 見逃しと誤検出のどちらが困るか、許容できる誤差を決める
    4. AIが間違えたときの、人の確認の流れを決める
    5. 稼働後の変化に気づく方法と、再学習の体制を決める
    6. ライセンス・個人情報・外部通信の扱いを確認する

    発注者向けメモ:稼働後の保守に含めるものを決める

    画像認識のシステムは、稼働後の精度の見守りと、必要に応じた再学習が、保守の中心になります。ここが契約に含まれているかどうかで、数か月後の安心感が大きく変わります。

    発注者がやること チェックリスト

    • ☐ 稼働後に、精度の低下のきざし(件数・信頼度の変化)を記録・確認する担当者と頻度を決めた
    • ☐ 撮影条件(カメラ・照明・画像の設定)を変えるときは、事前に連絡する運用にした
    • ☐ 再学習が必要になったときの、費用・期間・写真の用意の分担を決めた
    • ☐ 使っているAIモデル・ライブラリのライセンスを確認し、商用の条件を、法務や専門家に確認した
    • ☐ 開発会社が交代しても再現できるよう、環境・学習データ・評価用の写真が、納品物に含まれることを確認した

    開発会社への質問例

    • 「稼働後の精度は、どのような指標で、どのくらいの頻度で確認しますか。異常はどう通知されますか」
    • 「カメラの交換や、画像の圧縮設定の変更が、精度に影響することはありますか。事前に確認できますか」
    • 「再学習は、保守の範囲に含まれますか。含まれない場合の費用の目安を教えてください」
    • 「使うAIモデルのライセンスを、書面で教えてください。商用利用の条件は確認済みですか」
    • 「学習に使った写真、評価用の写真、学習の設定は、納品物に含まれますか」

    まとめ

    第11回(最終回)では、次のことを行いました。

    • 稼働後の変化のきざし(件数・信頼度・何も見つからない割合)を記録・判定する仕組みを作った
    • 画像の圧縮率を少し変えるだけで、検出が大きく減ることを確認した
    • 信頼度の平均だけでは、変化を見落とす例を確認した
    • ライセンス(AGPL-3.0と商用ライセンス)の確認点を整理した
    • 連載全体の学びと、発注者側の準備をまとめた

    全12回を通して作ったのは、画像認識の小さな試作です。ここから、自社の対象・現場に合わせて、写真を集め、精度を測り、人の確認を組み込み、見守る。この積み重ねが、実用に至る道です。自社の画像認識の相談は、まず小さな試作(PoC)から始めるのが、現実的な進め方です。

    この連載の記事一覧

    この記事は連載「YOLOで作る画像認識ツール」の1回です。連載のほかの回は次のとおりです(連載の一覧ページ)。

    システム制作・運用・保守のお問い合わせはこちら


      よかったらシェアしてね!
      • URLをコピーしました!
      • URLをコピーしました!

      この記事を書いた人

      株式会社THIRD HERO代表取締役 朝野貴朗
      Webシステム開発を中心に、toC向けサービスサイトの運営、ツール開発などを行ってまいりました。

      目次