UIへの誤発火を44%→22%に。外側のifを1本も足さずに
モデルの仕事を、外側のifで肩代わりしない——正解データの定義を「画面のどこか」から「字幕の枠の中」へ変えた話
モデルの誤りを、外側のifで消すのは簡単だ。位置で落とす。一定時間は発火させない。例外を足す。数字もすぐ改善する。
だが、その区別が入力から判断できるものなら、外側のifはモデルの弱さを隠しているだけかもしれない。
LYRの字幕判定器では、UIへの誤反応をルールで抑えていた。原因を辿ると、間違っていたのはモデルではなく「正解」の定義だった。ただし、ラベルを直すだけでも足りなかった——位置で決まる問題なのに、モデルに位置を渡していなかったからだ。
この記事は マニフェストの4番目の原則 処理を高速化するより、処理自体を減らす のケーススタディです。外側に足したifは、たいてい「減らせる処理」として数えられていない、という話。
前回、OCRを呼ぶ回数を減らすために、常時起動の安い判定器(Awake Layer)を置いた話を書いた(第1回)。「いま画面に読むべき文字があるか」を見て、高価な処理を起こすかどうかを決める層だ。
運用に入れて、すぐ問題が出た。この層は、字幕以外の文字にも反応する。
動画アプリの右側に並ぶ操作ラベル、ブラウザのURLバー、右上の「⋮」メニュー、ゲームのHUD。人間には「それは字幕じゃない」と一目で分かるが、判定器にとっては同じ「文字らしい何か」だった。反応すればOCRが起きる。電力を払い、あげくUIの断片が翻訳結果に混ざる。
注:本図は本文で扱う 44%→22% と同じ現象を公開可能なデータで再現したもので、コーパスも実装も異なるため数値は一致しない。アカウント名とアイコンはぼかしている。
外側で消すのは、簡単だった
最初の対処は、当然のように外側のフィルタだった。
位置で落とす。短すぎるものを落とす。発火してから一定時間は次を撃たない。同じものが続いたら抑制する。——どれも数行で書けて、どれも効く。実際、発火の抑制時間を延ばす1行の変更で、冗長な発火は録画5本すべてで -32〜-78%、電力指標も -27〜-31% 落ちた。
数字だけ見れば勝ちだ。だが代償がついてきた。抑制を強めた分、字幕が差し替わったときの反応が最大2秒遅れ、取りこぼしもわずかに増えた。つまりこれは改善ではなく、ダイヤルだった。無駄な発火と、遅れ・取りこぼしを、左右に振り分けているだけ。
冗長発火を減らして遅延を増やしたなら、それは改善ではなく、トレードオフの操作点を動かしただけだ。
そして気づいた。これらのifは全部、同じ一文で説明できる。
モデルが間違えることを前提に、その尻拭いを外側で買っている。
保険料は毎フレーム、端末の上で支払われる。原因を直さない限り解約できず、例外が増えるほど保険契約も積み上がる。 位置フィルタ、抑制時間、連結条件、例外の例外——外側のロジックは、内側の弱さを隠したまま増えていく。
正解データの定義を変えた
そこで、外側をいじるのをやめて、モデルが何を「正解」と教わっていたかを見に行った。
ラベルはこう定義されていた——「画面のどこかで文字が読めたら、字幕あり」。
これでは、UIに反応するのは誤作動ではない。教えたとおりに動いている。 URLバーの文字も、操作ラベルも、「画面のどこかで読めた文字」だ。モデルは正しく、私のラベル定義が間違っていた。
直し方は、外側のifを1本足すことではなく、定義を書き換えることだった。
「画面のどこかで読めたら」→「字幕の枠の中で読めたら」
これだけで、UIの文字はモデルにとって負例(そこで反応してはいけないもの)になる。外側で消していた区別が、学習の中に移る。
結果、字幕の外にある文字での誤発火は、ゲーム系の映像で 20%、ドラマ系で 23% のフレームが「あり」から「なし」へ是正された。外側のifを1本も足さずに。
位置の問題を、位置なしで学ばせていた
正直に書くと、ここで一度スカを引いた。
ラベル定義を直しただけの再学習は、効果ゼロ(変化なし)だった。理由は考えてみれば当たり前で、モデルに渡していた入力は画面の見た目だけであり、「その文字が画面のどこにあるか」という情報がそもそも渡っていなかった。位置で決まる区別を、位置を見せずに学ばせようとしていた。
入力に位置の情報を加えて初めて、装飾やUIへの誤発火は 約44% → 約22% と半分になった。
ここが実務的にいちばん大事な教訓だと思う。
モデルに解かせると決めたなら、解くための情報を渡す。 渡さずに「学習でなんとかなる」は、外側のifと同じ雑さだ。
外側のロジックが正当化される条件
とはいえ、「外側のロジックは常に悪」ではない。同じ時期に、外側で解くのが明確に正しかったケースもある。
ブラウザで漫画を読むモードで、右上の「⋮」メニューが1文字として誤認識され、訳に混ざっていた。文字の中身では字幕と区別できない。ここで採った手は、位置のしきい値を勘で決めることでも、モデルに学ばせることでもなく、OSに実際の描画領域を聞くことだった。コンテンツ表示領域の座標はOSが正確に持っている。その外側を捨てるだけで、実機3回とも「⋮」とURLバーが消え、本文だけが訳された。
この2つの違いは、はっきりしている。
| 問題 | 解く場所 | 判断理由 |
|---|---|---|
| ブラウザのUI領域 | 外側 | OSだけが正確なコンテンツ境界を持つ。モデルには原理的に見えない情報 |
| 画面内の字幕とUIの区別 | モデル側 | 画像と位置から判別できる |
| 発火の連打制御(重複排除) | システム側 | 変わっていないものを再処理しない、は時系列上の製品要件 |
| モデルの誤発火の後始末 | 原則としてモデル側 | 入力から判断できるのに、外で補修している |
線引きはこうなる。
外側のロジックが特に有効なのは、モデルが原理的に知り得ない情報か、決定論的に適用すべき制約を注入するとき。 モデルが入力から判断できることを外側で処理しているなら、それはモデルの弱さを隠す負債だ。
念のため補足すると、重複排除そのものは負債ではない。同じ字幕が変わっていない間は再処理しない、という状態管理は製品仕様であって、モデルの尻拭いではない。この記事で負債だったのは、誤発火を隠すためにその抑制時間を延ばしたことだ。同じコードでも、何を隠しているかで意味が変わる。
推測に基づく位置ヒューリスティックと、OSが持つ実領域は、外見が似ていてもまったく別物でもある。前者は端末や画面の向きが変わるたびに壊れ、後者は壊れない。
それでも、まだ勝ち切っていない
きれいに終わらせたいところだが、事実は書いておく。
判定器の信号定義を正す方向は、全ジャンルで勝ったわけではない。人手で正解を作って比べると、講演系の映像では字幕の捕捉が 35% → 63%(統計的に明確、p≈1e-4)と本物の勝ちだった。しかしニュース系は、既存モデルのしきい値を上げるだけで同等以上になった——つまりこの勝ちは再学習の手柄ではなく、交絡だった。再学習モデルが勝ったのではなく、比較対象の操作点が揃っていなかっただけである。再現率かしきい値を揃えた対照を置くまで、「学習が効いた」とは言えない(対照を取るまで、「なぜ」を語らない)。他のジャンルは有意差なし。現時点で本番全面採用を正当化する根拠はまだ無い。
それでも、外側にifを積む道には戻らない。理由は単純だ。
外側のパッチは、増えることはあっても消えない。モデルを正せば、外側のパッチが消える。 前者は処理を足し続け、後者は処理を減らす。同じ「効いた」でも、残高の向きが逆になる。
教訓
- 誤作動を見たら、まず「正解」の定義を読む。 モデルは誤っていたのではなく、間違った目的を正しく学んでいることがある。外側で殴る前に、定義を疑う。
- モデルに解かせるなら、必要な情報を渡す。 位置で決まる問題を、位置なしで学ばせることはできない。性能は ラベル定義 × 入力情報 × モデル能力 で決まる。
- 外側のルールは、情報の所在で正当化する。 OSだけが持つ情報は外から入れる。入力から判断できる区別を外側で肩代わりすると、処理と例外が積み上がる。
これは マニフェストの4番目の原則——処理を高速化するより、処理自体を減らす——の、少し裏側からの現れだ。外側のifは、足したときには「対策」に見える。減らせる処理として見えるようになるのは、それが何を隠しているかを言葉にできたときだった。
付録:生データ
| 実験 | 改善 | 代償・留保 |
|---|---|---|
| 発火抑制 500→2000ms(1行変更) | 冗長発火 -32〜-78%(録画5本すべて)、電力指標 -27〜-31% | 字幕差し替えの遅延 最大2秒、取りこぼし微増=ダイヤル |
| ラベル再定義(画面のどこか→字幕の枠の中) | ゲーム系 20% / ドラマ系 23% のフレームを「あり→なし」に是正 | 枠を固定矩形で近似(動く字幕を過剰に「なし」と数え得る)、目視確認はドラマ系の一部のみ |
| ラベル修正のみの再学習 | 変化なし(wash) | 入力に位置情報が無かった |
| 位置チャネルの追加 | 装飾・UIへの誤発火 約44% → 約22% | 同一の再現率で揃えて比較 |
| OSの表示領域による除外 | 実機 3回中3回でUI混入が消滅 | 表示領域を取得できる場合に限る(取れない場合は保険の帯フィルタ) |
| 信号定義の再学習(人手正解・録画1本ずつ除外) | 講演系 捕捉 35% → 63%(p≈1.2e-4) | ニュース系は交絡(しきい値調整で同等以上)、他ジャンルは有意差なし。全面採用の正当化には至っていない |
注記: 電力指標の一部は発火数×コストの相対値(ハーネス上の積算)であり、実機の電力計による実測ではない。