開発ノート

20年の時を超えて同じ顔を見つける

家族アーカイブに対する顔認識は、この中の顔が形を変えていくことを思い出すまでは、解決済みの問題に思える。生まれたばかりの赤ちゃんと、その子が成長した10歳の姿は、人間の目に違って見えるだけではない — 認識モデルが出力する数値ベクトル、顔の特徴ベクトルも、単一の類似度しきい値では両端を同時に押さえられないほど大きくずれる。アーカイブ全体に対して一回のグローバルなクラスタリングを、生まれたばかりの子と10歳の子を同じ人物として捉えられるほど緩いしきい値で実行すると、今度は別人まで捉えてしまうようになる。他人同士を区別できるほど厳しくすると、成長していくすべての子どもが、年齢を重ねるたびに複数の「人物」に分裂してしまう。

これがこの記事の核心となる問題だ:「どうやって顔を認識するか」ではなく — それは成熟したモデルによって、ほぼ解決済みの問題だ — 「20年の子ども時代を通じて顔が経験する変化を、どうやってアイデンティティとして追跡するか」だ。これはまったく別の問題で、はるかに書かれることが少ない。

まず時間窓、それから連鎖させる

うまくいったアプローチは、1回のクラスタリングに20年分をカバーさせようとするのをやめて、代わりに、それぞれ半年分だけをカバーする、たくさんの小さくて簡単なクラスタリングを行い、その結果を連鎖させることだった。

ステップ1:半年単位の時間窓の中で、コサイン類似度0.50という厳しいしきい値で、貪欲法によるクラスタリングを行う。半年という窓の中では、年齢による変化は本当に小さい — 子どもは6ヶ月でよく調整されたクラスタリングを脅かすほど顔の構造を変えないので、厳しいしきい値を使っても厳しいままで安定して機能する。

ステップ2が実際のトリックだ。各半年の時間窓から得られたクラスターを、隣接する最大4つの時間窓にわたって、ずっと緩いコサイン類似度0.42というしきい値で連鎖させ、Union-Findを使って推移的に連結する。理屈はこうだ:10年をまたぐ直接比較を破綻させてしまうほどの年齢による変化も、半年から半年への1回のホップだけをつなぐには十分小さい。だから、システムが「新生児から10歳まで」をまたぐ比較を1回で行う必要は一度もなく、それぞれが単体では簡単な短いホップの連鎖だけで、結果的に長い距離を積み重ねられる。Union-Findがここで正しい構造なのは、アイデンティティが推移的だからだ — 時間窓Aのクラスターが時間窓Bのクラスターと連結し、Bがさらに時間窓Cと連結するなら、AとCは一度も直接比較されなくても、最終的に同じグループになるべきだ。

0.50
半年の時間窓内でのコサイン類似度のしきい値
0.42
時間窓をまたいで連鎖させる際のコサイン類似度のしきい値
4
連鎖が広がれる隣接時間窓の数
年齢による変化は半年の中では小さく、10年をまたぐと大きい — だから、たった1回の比較に10年をまたがせようとしてはいけない。

連鎖を隣接する4つの時間窓(半年という時間窓のサイズを考えると、2年分)に制限しているのは、意図的な制約であって、見落としではない。緩い0.42のしきい値を無制限に連鎖させると、誤差が積み重なっていく:2ホップ目で少し甘すぎる統合が、4ホップ目でさらに少し甘すぎる統合の土台になり、最終的には、連鎖がそこまでずれていく過程を一歩一歩の甘い統合として重ねた結果、2人の異なる子どもが同一のアイデンティティを共有することになってしまう。連鎖の範囲を制限することで、各連鎖の最悪ケースの誤差を有限に抑えている。

ゴミクラスターは、クラスターが少ないことよりも悪い

連鎖は候補となる人物クラスターを生成するが、そのすべてが誰かに見せるに値するわけではない。純度ゲートが連鎖の後に実行され、内部的な一貫性が信頼できるほどではないクラスターを捨てる。これはかなり攻撃的だ:元になったアーカイブでは、この処理によって表示対象のクラスター数が545から281まで削られた。これは小さな削減ではなく、生の出力の半分以上を捨てているということだ。代わりのやり方 — 誰かに545人の候補「人物」を見せて、その3分の1が実際には断片や誤った統合である — は、もっと少なく、もっとクリーンなものを見せるよりも悪い。誰もクラスタリングアルゴリズムの後始まりをしたいわけではない。ほとんどすでに正しい、短いリストが欲しいのだ。

修正は、再クラスタリングを乗り越えて残らなければならない

これはどれも一発限りの処理ではない。クラスタリングはアーカイブが増えたりモデルが改善されたりするたびに再実行され、そのたびに、誰かがすでに行った人間による修正 — クラスターの名前変更、同じ人物だったのに分かれていた2つの統合、実は違う人物だったのに分割 — を失うことは許されない。だから、すべての修正は、クラスタリング出力そのものとは別の、名前をキーとする永続的な上書きテーブルに書き込まれ、再クラスタリングのたびに再適用される。クラスタリングアルゴリズムは提案する側で、上書きテーブルが最終決定権を持つ。これはコード自動生成に対するバージョン管理と同じ原理だ:再生成可能な出力に、人間が手で編集した部分を静かに上書きさせてはいけない。

正直な限界:兄弟姉妹

このシステムについて言える最も有用なことは、賢く振る舞おうとしていない部分についてだ。このアーカイブでは、兄弟姉妹同士のコサイン類似度はおよそ0.33で測定される — 無関係な2人の他人よりは近いが、クラスタリングが実際に使っている0.50や0.42のしきい値のどちらよりも、意味のある差で下だ。これは、もっと積極的なシステムなら統合を自分に説得しかねないくらい近く、時々間違えるくらい遠い。この境界で賭けをするのではなく、このシステムは、僅差の類似度を、行動の指示ではなく、問いかけの信号として扱う:こういうケースは、統合の提案として人間の確認を求める形で表示され、自動で統合されることは決してない。誤った自動統合は、2人分の年表を同時に静かに壊してしまう。断られた提案は、何のコストもかからない。

これが顔認識を超えて重要な理由: この全体の形 — 強い信号は局所的に信頼し、隙間は慎重に連鎖させ、誰かに見せる前に内部的な一貫性でゲートをかけ、本当にあいまいなケースについては人間に最終判断を委ねる — は、変化を通じてアイデンティティを追跡する必要があるあらゆる場面に現れるパターンだ。顔が年を取ることは、家族の写真アーカイブが避けられずに出会う、そのバージョンにすぎない。
← 記事一覧へ戻る