銀行書類上のスタンプと署名を検出するためのYOLOv11のファインチューニング—実践ガイド

Dev.to / 2026/4/30

💬 オピニオンTools & Practical UsageModels & Research

要点

  • 本記事は、自然画像を前提とした学習では崩れがちな、スキャン・撮影・透かし付きの実運用バンキング文書に対して、YOLOv11をスタンプ/署名検出にファインチューニングするための実践的な手順を示している。
  • 著者は、レイアウト推論型モデル(LayoutLMv3やDonut)や古典的なOpenCV手法よりもYOLOv11が適しているとし、YOLOの高速性、精度/再現率の調整のしやすさ、小さな物体(低解像度スキャンで見つかりやすいスタンプ等)への対応を理由に挙げている。
  • モデル設計よりもデータ準備とアノテーションが難所だとして、ラベル付けと形式出力に関するツール選択(Roboflow、コンプライアンス上SaaSを避ける場合のCVATなど)や、クラス設計の規律を具体化している。
  • 事業課題を解く最小限のクラス体系から始めることを推奨しており(例:signature、stamp、必要ならhandwritten_initials)、クラスを増やすことで学習データ要求や失敗モード、デバッグ難度が上がる点を強調している。
  • 全体として、この投稿は規制のあるバンキング環境で必要になる実装上の工夫(例えば推論レイテンシ制約)を含め、オンラインのYOLOチュートリアルと実エンジニアリングのギャップを埋める「プレイブック」として位置付けている。

毎日、バンキング業務オペレーションのチームは数千件の書類を手作業でレビューしています - 
ローン申請書、KYCフォーム、契約書 - 正しいスタンプ、
正しい署名を、正しい場所にあるかどうかを探すのです。これは遅くて高コストで、そして
まさにコンピュータビジョンが自動化すべき種類の仕事です。
問題は、オンライン上のほとんどのYOLOチュートリアルが、自然写真の中で車や
犬、人物を検出する方法を教えていることです。ところが、それは
書類にはうまく適用できません。書類は構造化されており、品質はさまざまで、
携帯電話で斜めから撮影されることもあれば、ファックスで送られることもあり、
しばしば透かしが入り、そしてほとんどの場合、照明が一貫していません。同じフォーム上のスタンプを
きれいなPDFで検出できるモデルは、そのフォームを
電話で撮影した写真では崩壊します。
"ここ数週間、規制のある銀行環境で、書類上のスタンプと署名を検出する
YOLOv11ベースのディテクタの実装に深く取り組んできました。"
その作業は、既製のチュートリアルが終わる場所と、
本当のエンジニアリングが始まる場所を教えてくれました。ここにプレイブックがあります。

なぜ代替案よりYOLOv11なのか

書類のオブジェクト検出には、いくつか妥当な出発点があります。

  • LayoutLMv3やDonutのようなレイアウト対応モデル - 構造化されたフォームには強いですが、重く、限定された用途(狭いタスク)向けにファインチューニングするのが難しく、推論も遅いです。検出したいのがオブジェクトの一部(スタンプ、署名、頭文字)だけなら過剰です。  - 古典的なOpenCVのアプローチ - テンプレートマッチング、輪郭検出、Hough変換。高速で軽量ですが、実運用のスキャンには脆くて不安定です。  - YOLOファミリー(v8、v11) - 書類に対するオブジェクト検出のちょうど良いところです。速く、よくドキュメントされており、ファインチューニングも容易で、精度/再現率のトレードオフはオペレーションチームの要件に合わせて調整できます。 私はYOLOv11を選びました。ultralyticsのPythonパッケージが大部分の面倒な作業を引き受けてくれます。推論は適度なGPUであればページあたり100ms未満で動き、さらにアーキテクチャは小さな物体を扱います - スタンプがスキャン解像度の低い場所にあることが多いため - 古いバージョンよりも得意です。 ## 80%:データ準備とアノテーション 実運用でCVを出荷した人なら誰でも同じことを言うはずです。モデルを作るのは簡単です。時間を奪われるのはデータです。 アノテーションツール。 私はRoboflowを使いました - バウンディングボックスのラベリング用のクリーンなWeb UI、学習/検証/テストの自動分割、YOLO形式への簡単なエクスポートが可能です。コンプライアンス上の理由でSaaSが使えない場合は、CVATがオープンソースの代替です。 クラス分類。 初日から10クラスを定義したくなる衝動を抑えてください。まずはビジネス課題を解く最小のセットから始めます:
  • signature  - stamp -(必要に応じて、フォームに含まれる場合はhandwritten_initials) クラス数が増えるほど、クラスごとのラベル付き例の数が増えるとは限らず、失敗パターンが増え、デバッグしづらいモデルになります。あとからクラスを分けることはできますが、ぐちゃぐちゃになったものをきれいに統合することはめったにできません。 学習/検証/テスト分割の規律。 ドキュメントを3つの分割(splits)に分けるときは、ランダムに行うのではなく出典(source)ごとに分けてください。同じフォームテンプレートが学習(train)と検証(val)の両方に出ていると、あなたの検証指標は嘘をつくことになります - モデルはオブジェクトではなくフォームのレイアウトを学習しているのです。誤った予測が実際のお金につながるような規制環境では、嘘をつく検証セットは許されません。 データ拡張戦略 - そしてなぜデフォルトは書類では間違っているのか。 市販/既製のYOLOデータ拡張のデフォルトは、自然画像向けに設計されています。回転は最大30°まで含まれ、mosaic、MixUpも含まれます。書類ではそれは積極的に間違いです:
  • 回転は厳密に制限する(±5°)。 書類はまっすぐ(upright)です。大きく回転させると、実運用の入力を反映しない学習例が生成されます。  - mosaic拡張はオフにすべき。 4つの書類を2×2のグリッドに貼り付けると、推論時には存在しない入力が作られてしまいます。  - 代わりに役立つもの: 明るさ/コントラストの変動(スキャン品質の違い)、JPEG圧縮ノイズ(低品質スキャン)、部分的な遮蔽(書類の一部が隠れている)、ガウスぼかし(ピンぼけの携帯写真)。 "私のプロジェクトで最も大きな精度向上は、携帯で撮影したスキャン向けに拡張を行ったことでした。実運用データは、私の学習セットが前提としていたよりもずっと雑でした - そのギャップを埋めることの方が、どんなアーキテクチャ変更よりも重要だったのです。" ## 本当に効く学習設定 ほとんどのYOLOのハイパーパラメータはデフォルトのままで問題ありません。書類で効果が出るのは、次の部分です:
 from ultralytics import YOLO
model = YOLO('yolo11m.pt')
results = model.train(
 data='dataset.yaml',
 epochs=100,
 imgsz=1024, # 小さなスタンプには大きいimgszが効く
 batch=8,
 lr0=0.001,
 patience=20, # mAPが頭打ちになったら早期停止
 augment=True,
 mosaic=0.0, # 書類ではオフ
 degrees=5, # 回転を制限
 fliplr=0.0, # 書類を左右反転しない
 )
 ```
{% endraw %}

返却形式: {"translated": "翻訳されたHTML"}2    ここで 注意 喚起:
**{% raw %}`imgsz=1024`{% endraw %}  640.**  解像度  スタンプ  適用 すると  
  ピクセル-小さすぎる ため モデル  確実  検出 でき 入力 サイズ
  大き すると 計算 コスト  画像 あたり 増えます  クト  する  向上
  大きい
**水平 反転**  する ** 反転 された フォーム  誤った フォーム です
 製品 入力    一度--ことない 状態  生成 して しまう 拡張 
 実際  あなた  重要視 している 入力  対する 汎化  損ないます
## 実際に最適化すべき指標
多く  チュートリアル では デフォルト  {% raw %}`mAP@0.5`{% endraw %}. になっています  された
 環境 での ドキュメントAI では それ 
 間違った 主要 指標 です
Ops チーム  **精度**  重視します モデルが ここ 署名 あります
 と言ったとき  それが 正しい 必要 あります 誤検出false positive  そこに あるはず のない ドキュメント  下流  流し レビュアー
時間  無駄にします 見逃しfalse negative  回復 可能です-ドキュメント  手動 レビュー  戻り それが 既存  ベースライン
です 両方  追跡 しますが 1つ だけ 最適化 する 必要  ある なら 精度  最適化 てください あなた  Ops マネージャー  感謝 する でしょう
## 推論とデプロイ
GPU 上で 動く モデル  楽しい です CPU 上で 動く モデル 
出荷 可能です ドキュメントAIほとんど  ワークロードあなた  1分あたり 数十〜数百ページ  処理 する 一方 数百万 では ない
ではONNX  エクスポート した モデル による CPU 推論 のほうが デプロイ  速く 運用 コスト  安く
GPU ドライバ  取り合い になって ほしく ない  強く 制限 された 本番環境 との 互換性  非常に 高い です
流れ  次のとおり
1. 訓練  {% raw %}`ultralytics` PyTorch バックエンド訓練時GPU
2. 訓練済み 重み  ONNX  エクスポート
3. `ultralytics` ONNX-runtime 経由で CPU   提供
Step 2  1行 です

```python
 from ultralytics import YOLO
model = YOLO( 'best.pt')
 model.export(format= 'onnx') # best.pt の横に best.onnx を書き出します
 ``` 

Step 3 - 推論 サービス

```python
 from fastapi import FastAPI, UploadFile
 from ultralytics import YOLO
 from PIL import Image
 import io
app = FastAPI()
 model = YOLO( 'best.onnx') # ONNX runtime、CPUのみ
@app.post( '/detect')
 async def detect(file: UploadFile):
 image = Image.open(io.BytesIO(await file.read()))
 results = model(image)
detections = []
 for r in results:
 for box in r.boxes:
 detections.append({
  'class': model.names[int(box.cls)],
  'confidence': float(box.conf),
  'bbox': box.xyxy.tolist()[0],
 })
return { 'detections': detections}
 ```

この スニペット  最も 重要   `model = YOLO( 'best.onnx')` 
モジュール レベル先頭  置い います 起動 時に モデルを 1回 だけ ロード  リクエスト ごと には ロード ません
 リクエスト  毎回 モデル  リロード する のが YOLO エンドポイントで 最も よく ある 本番  ミスです 私は それ  こと  あります その差 レスポンス 時間
 50ms  5,000ms  という ことです
コンテナ について:スリムな Python ベース イメージ `python:3.11-slim`  十分です CUDA なしGPU ドライバ なしNVIDIA 依存 なし イメージ サイズ 
500MB 未満  収まり 単位  起動 でき どこ  動きます強く 制限 された 社内 VMオンプレミス 環境 にも。
GPU依存 サービス  出荷 する ため  必要 承認  か月 かかる ような 現場 でもその 問題  ありません
本当  トレードオフ こうです つまりの四半期 では なく 今日 デプロイ できる サービス  得る 代わり リクエスト ごとの
レイテンシ  少し 手放す こと です

返却形式: {"translated": "翻訳されたHTML"}## What the tutorials don't tell you
チュートリアルが教えてくれないこと
標準的なYOLOブログ記事が飛ばしてしまう3つの教訓:
**1. 奇妙なスキャンのロングテールこそが、現場で破綻が起きる場所です。**
横方向のバンディングが入ったFAXのページ、部分的にコピーされた書類、1つの角が切り取られた電話の撮影画像、裏面から滲み出てしまうウォーターマーク。あなたの学習データセットには、これらが十分に含まれていないはずです。できるだけ早く実際の現場入力のサンプルを用意してください(たとえ50枚だけでも)—それを訓練ではなく評価に使います。そうすれば、世界が実際にどのように見えるかが分かります。
**2. 入力画像のハッシュとともに、すべての予測を記録してください。**
モデルが本番で失敗したとき、後からでも「それを壊したまさにその入力」を特定できる状態にしたいはずです。入力をハッシュ化し、予測をログに残し、両方を保存します。それが、ハンティングせずにラウンド2の学習データを作る方法です。
**3. mAP@0.95を追いかけないでください。**
収穫逓減です。ビジネスで「リコール70%のときに精度95%」が必要なら、その運用ポイントに最適化します—曲線全体を要約する指標のために最適化しないでください。運用チームに相談してください。彼らが本当に気にしている数値を取り出します。それに対して学習してください。
## Closing
ドキュメントAIにおけるボトルネックはモデルではありません。ボトルネックは、
アノテーションの規律、実際の本番入力に合わせてチューニングされたデータ拡張、そして負荷で破綻しないデプロイです。規制産業向けにコンピュータビジョンを作っているなら—銀行、保険、法律、ヘルスケア—上のプレイブックが、私がうまくいったやり方です。フレームワークは変わります。データの規律は変わりません。