5回作り直しても当てずっぽうだった原因は、モデルではなくラベルだった
正解が約1秒ずれていた——監査したら、陽性のほうが画素変化が小さかった(AUC 0.056)
字幕が切り替わった瞬間だけを見つけて、重い処理(文字認識と翻訳)を呼ぶ回数を減らしたかった。そのための小さな判定モデルを、5通り作り直した。入力を変え、構造を変え、集約の仕方を変えた。どれも精度は当てずっぽうと変わらなかった。
原因はモデルではなく、正解ラベルが約1秒ずれていたことだった。監査すると、ラベルが「変化あり」と言っているフレームのほうが、「変化なし」より画素の動きが小さい——ラベルは正解の逆を向いていた(AUC 0.056)。
そして壊れたラベルは、二重に損をさせる。悪いモデルを作るだけでなく、既にあった良い実装を「取りこぼし25%」と過小評価していた。正しいラベルで測り直したら、その実装の真の取りこぼしは401件中1件だった。
注:黒背景(映像が黒く、字幕だけが合成される条件)での測定。AUCは1に近いほど良く、0.5が当てずっぽう。
5回作り直しても、当てずっぽうと同じだった
作ろうとしていたのは、「画面の字幕が切り替わったか」を判定する小さなモデルだ。これが当たれば、下流の重い処理(文字認識と翻訳)を呼ぶ回数を減らせる。
5回、作り直した。
- 生の画面(グレースケール)を入力に
- 文字らしさのマップを入力に
- その両方を2チャンネルで
- 全体を平均する層を外して、位置情報を潰さないように
- さらに構成を調整
結果は、どれも当てずっぽうと変わらなかった。ここで普通に出す結論は2つある——「このタスクは学習で解けない」か「モデルが小さすぎる」。私も、そう書きかけた。
モデルではなく、ラベルを疑う
書きかけて、手が止まった。5回とも同じ結果というのは、むしろ不自然だ。入力も構造も変えたのに全部が同じ床に張り付くなら、共通しているものを疑うほうが筋がいい。共通しているのは、正解ラベルだ。
そこで、ラベル自体を採点することにした。学習に一切使っていない、独立な信号で。使ったのは、隣り合うフレームの画素差分——「画面がどれだけ動いたか」だけを見る、モデルとは無関係な量だ。
字幕が切り替わったフレームなら、画素は大きく動くはずだ。だから、ラベルが正しければ「陽性フレームのほうが画素の動きが大きい」となるはずだった。
結果は AUC 0.056。正例率を下回る——つまり逆相関だった。ラベルが「変化あり」と言っているフレームのほうが、画面が動いていない。
ラベルは、正解の逆を向いていた。
原因を辿ると、単純だった。ラベルは公式の字幕トラック(何時何分に何を表示するか、というデータ)から作っていた。だが実際の画面では、字幕はフェードインしながら現れ、表示時間も想定値で埋められている。結果、ラベルは画面の変化より約5フレーム(1秒)遅れて立っていた。
もう一つ落とし穴があった。「別のラベル候補で検証しよう」と考えたが、その候補も同じ字幕トラックのタイミングから作られていた。同じ出所のラベル同士を比べても、一致するのは当たり前で、何も検証できない——同語反復だ。
ラベルを作り直す
直し方は、字幕トラックを捨てて、画面そのものから作ることだった。
本番と同じ検出・認識を、全フレームに流す。読み取れたテキストが前のフレームから変わったところを陽性にする。エピソード1本で約8,000フレーム、実時間の数十倍の速さで回せた。
作り直したラベルを、同じやり方で採点する。
| 字幕トラック由来(旧) | 全フレーム認識(新) | |
|---|---|---|
| 画素差分での AUC | 0.056 | 0.508 |
| 再現率(適合率0.5の点) | 0% | 94% |
| 最適なずれ補正 | −5フレーム | 0(ずれ無し) |
最適なずれ補正が 0 になったのが、いちばん分かりやすい証拠だ。旧ラベルは、5フレーム戻して初めて画面と噛み合っていた。
壊れたラベルは、良い実装まで過小評価する
ここからが、本当に高くついた部分だ。
同じ壊れたラベルで、既にある実装も評価していた。ハッシュを使った、学習を使わない素朴な判定器だ。旧ラベルでの成績は「取りこぼし25〜28%」。だから私は「ここを学習で置き換える価値がある」と考えて、冒頭の5回に着手した。
正しいラベルで測り直すと、その実装は——適合率98.8% / 再現率99.5%。ほぼ天井だった。
「取りこぼし」に見えていたものの正体も分かった。取りこぼしと判定されたフレームを1件ずつ見ると、401件中400件は、そもそも画面に文字が無かった。字幕トラックが「表示中」と言っているだけの、実際には空のフレームだ。真の取りこぼしは、1件だった。
つまり、置き換える余地は最初から無かった。 学習型のプロジェクトはここで閉じた。5回の作り直しが無駄だったというより、壊れたラベルが「やる価値がある」という嘘の投資判断を作っていた。
残課題
作り直したラベルも、万能ではない。
画素差分は、大きく動いたが文字ではないもの(シーンの切り替わり、画面全体の暗転)を区別できない。適合率を0.7まで上げると再現率は0%に落ちる——ラベルの監査には使えるが、これ自体を判定器にはできない。
そしてこの検証は、映像が黒く字幕だけが合成される条件で行ったものだ。背景が動く映像では、画素差分そのものが別の意味を持つ。同じ手順をそのまま持ち込めるとは限らない。
教訓
- 5回作り直して当てずっぽうなら、疑うのはモデルではなくラベル。 入力も構造も変えたのに全部が同じ床に張り付くなら、共通しているもの——正解データ——を先に採点する。
- 監査は「学習に使っていない独立な信号」で。 ラベルと同じ出所のデータで検証すると、一致するのは当たり前で何も分からない。今回は画素差分という、モデルとも字幕トラックとも無関係な量が効いた。
- 壊れたラベルは、二重に損をさせる。 悪いモデルを作るだけでなく、既にある良い実装を過小評価して、やる価値のない投資を「やる価値がある」に見せる。5回の失敗より、この誤った判断のほうが高くついた。
これは マニフェストの1番目の原則——「まず計測せよ」——の、いちばん手前にある話だ。測る前に、測る物差しのほうを測る。採点者を疑うのと同じ規律が、正解データにも要る。
付録:生データ
黒背景(映像が黒く、字幕だけが合成される条件)での測定。AUCは1に近いほど良く、0.5が当てずっぽう。
| 項目 | 実測 | 条件・留保 |
|---|---|---|
| 5回の作り直し | 生画面/文字らしさマップ/2チャンネル/全体平均層の除去、いずれも当てずっぽう水準 | 入力・構造・集約を変えても全部が同じ床に張り付いた=共通項(ラベル)を疑う根拠 |
| 旧ラベルの監査 | 画素差分での AUC 0.056(正例率を下回る=逆相関)、適合率0.5での再現率 0% | 学習に使っていない独立な信号で採点。陽性フレームのほうが画面が動いていなかった |
| ずれの正体 | 画面の変化より 約5フレーム(≒1秒)遅い | 字幕トラックの想定表示時間+フェードインに由来。最適なずれ補正が −5 だった |
| 作り直したラベル | 画素差分での AUC 0.508 / 適合率0.5での再現率 94% / 最適なずれ補正 0 | 本番と同じ検出・認識を全フレーム(1話あたり約8,000枚)に実行し、テキストの変化点を陽性に |
| 既存実装の再評価 | 適合率 98.8% / 再現率 99.5%(旧ラベルでは「取りこぼし25〜28%」) | 学習を使わないハッシュベースの判定器。旧ラベルが過小評価していた |
| 「取りこぼし」の内訳 | 取りこぼし判定 401件中400件は、実際には文字が無いフレーム | 真の取りこぼしは1件。字幕トラックが「表示中」と言っているだけの空フレームだった |
| 意思決定への影響 | 学習型で置き換える余地はゼロと判断し、プロジェクトを終了 | 壊れたラベルが「やる価値がある」という誤った投資判断を作っていた |
| 監査手法の限界 | 画素差分は適合率0.7で再現率 0% | 大きく動いたが文字でないもの(シーン切替・暗転)を区別できない。ラベル監査には使えるが判定器にはできない |