0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

乃木坂46の動画にメンバーの名前をラベリングするAIの開発

0
Posted at

やりたいこと

乃木坂46は現在46名前後のメンバーが在籍しており、新規ファンが顔と名前を一致させるまでには相応の時間がかかります。InstagramリールやTikTokで動画を見かけても、初見のユーザーは「この子は誰?」で止まってしまい、検索して調べるという一手間がそのまま離脱につながります。既存ファンにとっては当たり前の顔と名前の一致が、新規層にとっては最初の壁になっている、というのが出発点の課題感です。

この「認知のハードル」を、動画に自動で名前を重ねるAIで下げられないか。そのために作ったのが、Instagramリールの動画URLを送ると、映っているメンバーの名前と信頼度を自動でラベリングした動画を返す仕組みです。

企画背景 — なぜ今、動画×顔認識なのか

乃木坂46のファン数自体は減少傾向にあると考えられます。ファン数を直接測る公式指標は存在しないため、代わりにシングルCDの初週売上枚数で見てみると、過去のシングル(「シンクロニシティ」等)ではミリオンセラーとなる初週111.7万枚を記録していたのに対し、2026年7月発表の通算41作目のシングルでは初週51.0万枚まで落ち込んでいます(乃木坂46 発売日・売上枚数一覧)。

今回のターゲットは、「乃木坂46という名前は聞いたことがあるが、追いかけてはおらずメンバーも分からない」層です。こうしたユーザーがアイドルと思いがけず出会う場は、Instagramリールのようなショート動画であることが多いと考えられます。SNSや動画サービス上で偶然商品やコンテンツを知り興味を持った経験がある人は64.5%にのぼり、そのうち約7割が「ショート動画」をきっかけに挙げたという調査があります(調査データ)。また、TikTokでよく見る動画の傾向は1位が「面白い」、2位が「かわいい」というデータもあります(調査データ)。

これらを踏まえると、Instagramのリール動画でメンバーを「かわいい」と感じたことがきっかけでファンになるユーザーは一定数いるのではないか、というのが今回の仮説です。

対象読者

  • AIを推し活に活かすにはどんなことができるのか知りたい方
  • 動画×AIのアイデアの種を探している方
  • 同じように動画に顔認識を組み込んでみたい方

実現した体験

作ったのは、InstagramリールのURLを1つ入力するだけのシンプルなWebフォームです。裏側でリール動画をダウンロードし、フレームごとに顔を検出、事前に学習したメンバーの特徴量と照合し、名前と信頼度を焼き込んだ動画を返します。

フロントの画面はこちらです。

image.png

URLを送信すると、推論中の画面に切り替わります。

image.png

処理が完了すると、動画のダウンロードができる画面に切り替わります。

image.png

実際に、以下の元動画を送信してみます。

すると、以下のように名前と信頼度がラベリングされた動画が出来上がります。

DcXgV5DT2Wn (1).gif

Before After
「これ誰だっけ…」とURLを検索窓にコピーして調べる 動画に名前と信頼度が自動で表示される

名前が分かればそのままメンバー名で検索でき、関連コンテンツへの導線が生まれます。「誰が誰か分からない」で止まっていたユーザーを、「この人が気になる」の一歩先に進めることが狙いです。

システムの全体像

リポジトリはこちらです。

リポジトリ内にある動画や画像ファイル、pklファイルは著作権の関係があるため使わないようにお願いいたします。

フロントは静的なフォーム1枚。ユーザーの操作から結果表示までを、非同期ジョブとして裏側のFastAPIサーバーが処理します。

① ユーザー
   │ Webフォームにリール URLを入力して送信
   ▼
② FastAPI (ECS Fargate)
   │ job_idを発行し、202ですぐ応答。実処理はバックグラウンドタスクへ
   ▼
③ 動画ダウンロード (yt-dlp)
   │ Instagram CookieはAWS SSM Parameter Storeから都度取得
   ▼
④ フレーム解析・顔照合 (DeepFace + OpenCV)
   │ 10フレームに1回、顔を検出→特徴量抽出→face_dbと類似度計算→名前を描画
   ▼
⑤ S3へアップロード
   │ 結果動画を保存し、公開URLをジョブステータスに書き込む
   ▼
ユーザー
   フロントが7秒間隔でポーリングし、completedになったら動画とダウンロードリンクを表示
ステップ 内容 使用技術
1. リクエスト Webフォームにリール URLを入力して送信 S3静的ホスティング + fetch()
2. ジョブ受理 job_idを発行し202を即返却、実処理は非同期化 FastAPI BackgroundTasks
3. 動画取得 URLから動画本体をダウンロード yt-dlp + boto3(SSM)
4. 顔照合 間引いたフレームで顔検出・特徴量抽出・類似度計算・描画 DeepFace(Facenet, RetinaFace) + OpenCV
5. 結果配信 結果動画をS3へ保存しURLを返却 S3(IP制限つき公開)

image.png

計算方法の詳細

仕組みの核は、画像を数百次元の数値ベクトル(Embedding)に変換し、ベクトル同士の近さで人物を判定するという一般的な顔認識の手法です。学習フェーズと推論フェーズに分けて整理します。

学習フェーズ — メンバーごとの「顔の特徴」を1本のベクトルに集約

  1. ネット上から収集したメンバーごとの画像(1人あたり数十枚)を、S3のraw-photos/<メンバー名>/配下に配置する。
  2. 各画像をDeepFace(Facenetモデル)に通し、顔ごとに512次元のEmbeddingベクトルを抽出する。1枚に1人しか映っておらず、検出信頼度が0.6を超える画像のみを採用し、写り込みノイズを除く。
  3. 1人分のEmbeddingが複数得られるので、その中央値を取り、「そのメンバーを代表する1本のベクトル」としてface_dbに登録する。平均ではなく中央値を使うことで、外れ値になりやすい写りの悪い写真の影響を抑える。
  4. 全メンバー分の代表ベクトルをface_db_YYYYMMDD_HHMM.pklとしてS3へアップロードする。

推論フェーズ — 動画の顔とface_dbを照合する

similarity = (A・B) / (‖A‖ × ‖B‖)   ← コサイン類似度

動画から10フレームごとに1枚を抽出し、写っている顔ごとにEmbedding(A)を計算。face_dbに登録された各メンバーの代表ベクトル(B)とのコサイン類似度を総当たりで求め、しきい値0.80を超えた中で最もスコアが高いメンバーをラベルとします。

同じフレームに複数人が映っているケースでは、類似度が高い候補から順にラベルを確定させ、一度使ったラベルは他の顔に重複して割り当てないようにしています。しきい値未満、もしくは検出信頼度0.3以下の顔はUnknownとして扱います(複数人が映るフレームでの実際の描画結果は、前述の完成動画GIFを参照してください)。

全フレームではなく間引いて処理しているのは、推論精度と処理時間のバランスを取るためです。直前の判定結果を次の数フレームに引き継ぐことで、体感の追従性を保ちつつ計算量を抑えています。

精度向上のための工夫

顔認識は「モデルを繋いだだけ」では実用に耐える精度が出にくく、データの前処理・後処理のロジックで底上げしている部分が大きいです。実装の中で効いている工夫を挙げます。

  • 中央値によるノイズ除去: 1人につき複数枚のEmbeddingを平均ではなく中央値で集約することで、写りの悪い写真1枚が代表ベクトルを大きく歪めるのを防ぐ。
  • 登録時の信頼度フィルタ: 学習用画像は「1枚に1人だけ映っていて、検出信頼度0.6超」のものだけを採用し、複数人が写り込んだ画像や不鮮明な検出結果をface_dbに混入させない。
  • 推論時のしきい値チューニング: 類似度のしきい値を0.80、検出信頼度の下限を0.3に設定。実際の動画で検証しながら、誤認識(false positive)と未検出(false negative)のバランスが取れる値を採用している。
  • ラベル重複の排除: 同一フレーム内で複数の顔が同じメンバー名に紐づいてしまう問題を、類似度が高い候補から順に確定させ使用済みラベルを除外するロジックで防止。
  • 検出器の使い分け: 学習(登録)時は精度重視のRetinaFaceを使用。動画推論時も同じ検出器・モデル(Facenet)で統一し、学習と推論の条件をずらさないようにしている。
  • フレーム間引き+結果の引き継ぎ: 10フレームに1回のみ推論し、それ以外のフレームは直前の判定結果を描画に流用。精度を落とさずに計算コストを抑える。

「精度を上げる」以外の設計判断

顔認識の精度そのものだけでなく、継続的に運用・更新できる形にするための判断をいくつか行っています。学習パイプラインとCI/CD構築それぞれで積み重ねた判断をまとめます。

判断 採用した設計 理由
再学習の起動方法 写真アップロード完了後、_UPLOADEDというマーカーファイルの作成をトリガーにする 何十枚もの写真をaws s3 syncで一括アップロードすると、写真の数だけS3イベントが発火してしまう。「アップロードが終わってから明示的に1回だけ合図する」形にすることで、学習ジョブの多重起動というリソースの無駄遣い・レースコンディションを防ぎ、起動タイミングを人間側でコントロールできるようにした
通知経路 S3イベント通知 → EventBridge → CodeBuild(Lambdaは挟まない) Lambdaで中継することもできるが、そのためだけの関数を書いて保守するコストがかかる。EventBridgeならプレフィックス条件でのフィルタリングとCodeBuild起動をコード無しで完結でき、保守対象を増やさずに済む
ECSタスクの分離 API用と学習用でECSクラスター・タスクを分離し、それぞれ専用のCodeBuildパイプライン(Dockerイメージのビルドも別々)を用意 APIは本番のラベリングAPIを常時稼働させている環境。学習タスクを同居させるとリソース競合や設定ミスがAPI側に影響するリスクがあるため、用途ごとにクラスター・パイプライン・イメージを分けて障害の影響範囲を切り離した
デプロイ方式 CodeDeployと連携する従来のBlue/Greenではなく、ECSネイティブBlue/Greenを採用 2025年7月に追加された新しいECSコンソールでは、デプロイコントローラーがデフォルトでECSに固定されCODE_DEPLOYへ直接切り替えにくくなっている。AWS自体が新規構築ではネイティブBlue/Greenを推奨している流れも踏まえ、taskdef.jsonappspec.yamlを管理する必要がない分シンプルな構成にした
テストの組み込み方 CodePipeline上に専用のTestステージを設けず、buildspec.ymlbuildフェーズ内でdocker build --target testとしてpytestを実行 テストが1件でも落ちればdocker build自体が失敗しビルドが止まる。専用ステージを増やさずに「テストが通らなければ先に進めない」構成を実現できる

CI/CDと再学習パイプライン

実装だけでなく、「動かし続ける」ための自動化にも力を入れています。

再学習パイプライン

  1. メンバーの新しい写真をS3のraw-photos/<メンバー名>/aws s3 syncでアップロード
  2. アップロード完了後、_UPLOADEDというマーカーファイルを配置
  3. EventBridgeがマーカーファイルの作成を検知し、学習用CodeBuildを起動
  4. CodeBuildがDockerイメージをビルド・ECRへpushし、学習用ECS Fargateタスクを起動
  5. 学習タスクがS3から画像を読み込み、Embeddingを再計算して新しいface_db_*.pklをS3へアップロード
  6. 学習の成功をEventBridgeが検知し、API側のCodePipelineを自動的に再実行

API側CI/CD

  • ソースをCodeCommitへpushすると、CodePipelineが Source → Build → Deploy を自動実行
  • Buildステージではdocker build --target testでpytestを実行し、テストが通ってから--target servingで本番イメージをビルド
  • DeployステージはECSネイティブBlue/Greenでトラフィックを新旧タスク間に切り替え

この2つを繋ぐことで、「新しい写真を置く → マーカーファイルを置く」の2アクションだけで、顔認識モデルの更新から本番反映までが無人で完走する状態になっています。

使用技術一覧

レイヤー 技術
フロントエンド HTML / CSS / JavaScript(素の fetch API)、S3静的ホスティング
バックエンドAPI FastAPI、Python
顔認識・ML DeepFace(Facenetモデル、RetinaFace検出器)、OpenCV、NumPy
動画取得 yt-dlp
インフラ実行基盤 Amazon ECS(Fargate)、ALB、VPC、Amazon ECR
CI/CD AWS CodeCommit、CodeBuild、CodePipeline
自動化・イベント連携 Amazon EventBridge
ストレージ・設定管理 Amazon S3、AWS Systems Manager Parameter Store(SecureString)
IaC AWS CloudFormation

終わりに

「乃木坂46の動画に名前を付けたい」という個人的な思いつきから始めたプロジェクトですが、実際に作ってみると顔認識モデル単体の精度以上に、それを支えるデータの前処理・しきい値のチューニング・学習と本番を安全に切り分ける仕組みづくりに多くの時間を使うことになりました。一人で企画からインフラ構築まで通しで担当したことで、動くものを作ることと、運用し続けられる形にすることの間にあるギャップを実感できたのが今回一番の収穫です。

今後は、識別精度が低いメンバー・似た顔立ちのメンバーへの対応強化や、処理レイテンシのさらなる短縮、Instagram以外のプラットフォーム(TikTok等)への対応拡張に取り組んでいきたいと考えています。同じように「好きなコンテンツ×AI」で何か作ってみたい方の参考になれば嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?