512x512への挑戦 - 情報ボトルネックの罠
前回、256x256のFaceswap-AutoEncoderを設計しました。3x3というボトルネックによって情報を極限まで絞り込み、アイデンティティをEncoderから削ぎ落とし、Decoderで付与する。この設計により、FaceSwapが可能になりました。
今回は、解像度を512x512に上げる実験です。
${\large \textsf{「解像度を2倍にすれば、より高品質なFaceSwapができる」}}$
そう考えるのは自然です。しかし、実際にやってみると、予想外の問題に直面します。
1. Naive実装 - 解像度を変えるだけ
まず、最もシンプルなアプローチを試してみます。
変更内容:
- 入力画像サイズ: 256x256 → 512x512
- モデル構造: 変更なし(同じEncoder/Decoder)
- 学習設定: 変更なし(LR、損失関数、エポック数など)
このモデルではCNNベースなので畳み込み層の構造上、異なる解像度の入力でも処理できるため、ほとんど何も変更せずに、512x512の学習が可能です。
では、何が起こるのか?
2. 何が起こったのか? - Bottleneckの変化
2.1 テンソル形状の変化
${\large \textsf{スワップができない!}}$
モデル図: 256x256の場合(前回)
モデル図: 512x512の場合(今回)
重要: 入力解像度が上がったため、ボトルネックが 3x3 → 7x7 に変化しています。
入力解像度が2倍になると、Encoder通過後の中間特徴マップも2倍(16x16 → 32x32)になります。その後のBottleneck層でさらに圧縮しても、最終的なサイズが大きくなってしまうのです。
2.2 圧縮率の変化
前回、256x256では圧縮率 21.3倍(約5%)という厳しい情報ボトルネックを作りました。
512x512では、どうなるでしょうか?
| 解像度 | 入力サイズ | Bottleneck | 圧縮率 |
|---|---|---|---|
| 256x256 | 256×256×3 = 196,608 | 3×3×1024 = 9,216 | 21.3倍 (4.7%) |
| 512x512 | 512×512×3 = 786,432 | 7×7×1024 = 50,176 | 15.7倍 (6.4%) |
圧縮率が 21.3倍 → 15.7倍 に下がっています。
つまり、情報ボトルネックが緩くなっているのです。
3. 問題の発覚 - Swapが起こらない
3.1 再構成はできる
学習を進めると、再構成(Reconstruction)は問題なく動作します。
通常の再構成フロー:
- Encoderで画像を潜在表現に変換
- 同じ人物用のDecoderで再構成
- 元の画像とほぼ同じものが出力される
L1 loss、LPIPS lossは順調に下がり、メトリクスからは一見、何の問題もないように見えます。

3.2 Swapが失敗する
FaceSwapの流れ:
- src画像をEncoderで潜在表現に変換(pose/expressionのみのはず)
- dst用のDecoderで再構成(dstのidentityを付与するはず)
- 期待: srcのポーズ・表情 + dstのidentity = FaceSwap
- 現実: srcのポーズ・表情 + srcのidentity = ほぼsrcのまま
つまり、Encoderが アイデンティティを削ぎ落とせていない のです。
3.3 Statistical Latent L2も無力
前回、Statistical Latent L2 Lossを使って、srcとdstの潜在分布を近づけることで、アイデンティティ分離を促進しました。
この損失は、バッチ全体の統計量(平均・分散)を一致させることで、Encoderが「アイデンティティに依存しない」特徴を学習することを促します。
256x256では、この損失が効果的に働き、EncoderはアイデンティティをBottleneckに残さないように学習しました。
しかし、512x512では、Latent L2損失があっても、Swapが起こりません。
4. 原因分析 - ボトルネックが広すぎる
4.1 空間解像度の比較
ボトルネックの空間サイズを比較してみましょう。
| 解像度 | Bottleneck | 空間次元の要素数 | 圧縮率(空間のみ) |
|---|---|---|---|
| 256x256 | 3×3 | 9 | 65,536 / 9 = 7,282倍 |
| 512x512 | 7×7 | 49 | 262,144 / 49 = 5,350倍 |
空間次元だけで見ると、512x512の方が圧縮率が低いです。
しかし、より重要なのは、絶対的な空間サイズです。
- 3x3: 9個の空間位置。「左上」「中央」「右下」のような、非常に粗い空間構造しか保持できない
- 7x7: 49個の空間位置。顔の「目」「鼻」「口」といった、より詳細な空間構造を保持できる
4.2 何が保存されるのか?
256x256の3x3では、空間情報がほとんど潰れるため、アイデンティティを保存する余地がありません。
3x3 bottleneck:
[全体のポーズ] [表情の大まかな方向] [照明の大雑把な情報]
→ 「誰か」を保存する空間がない
→ Decoderがidentityを付与せざるを得ない
一方、512x512の7x7では、空間情報がある程度残るため、アイデンティティを保存できてしまいます。
7x7 bottleneck:
[左目の位置] [右目の位置] [鼻の形] [口の形] [輪郭]
→ 顔の構造的な情報が残る
→ 「誰か」の特徴が潜在表現に含まれる
→ Decoderを交換してもidentityが変わらない
4.3 情報理論的な視点
前回、情報ボトルネックという概念を説明しました。
Encoderが学習する際、以下の2つの目標がトレードオフになります:
- 情報の圧縮: 入力をできるだけ小さな表現に圧縮する
- 情報の保持: Decoderが再構成できるよう、必要な情報を保持する
ボトルネックが十分に小さい場合(3x3):
Encoder: 「全ての情報を保存できない。何を捨てるべきか?」
→ 「identityを捨てて、pose/expressionを残す」
(なぜなら、Decoderがidentityを持っているから)
ボトルネックが大きすぎる場合(7x7):
Encoder: 「かなりの情報を保存できる。identityも入れよう」
→ 「pose/expression + identityを全部残す」
(Latent L2があっても、再構成誤差の方が大きいので優先される)
つまり、7x7は情報ボトルネックとして不十分なのです。
5. 損失値は下がる - しかし目的は達成されない
興味深いのは、損失値は正常に下がることです。
| Epoch | L1 Loss | LPIPS Loss | Latent L2 |
|---|---|---|---|
| 1 | 0.0234 | 0.142 | 0.0012 |
| 10 | 0.0089 | 0.068 | 0.0008 |
| 50 | 0.0043 | 0.032 | 0.0005 |
- L1、LPIPS: 再構成品質が向上している
- Latent L2: srcとdstの統計量も近づいている
しかし、FaceSwapは失敗します。
これは、損失関数が真の目的を捉えきれていないことを示しています。
- Latent L2は「統計的に似ている」ことを保証するが、「同じ空間領域に同じ情報を持つ」ことは保証しない
- モデルは、統計的には分布を近づけつつ、実際には各空間位置にidentity情報を保存している
6. まとめ - ボトルネックは設計の要
今回、512x512に解像度を上げる実験を行いました。
発見したこと
- Naive実装は失敗: 単に解像度を512x512にしても、FaceSwapは動作しない
- Bottleneckが拡大: 3x3 → 7x7に変化
- 圧縮率が低下: 21.3倍 → 15.7倍
- Identity分離の失敗: Encoderがidentityを削ぎ落とせない
- 損失値は正常: しかし、目的は達成されない
なぜ256x256では成功したのか?
前回、「3x3というボトルネックは aggressive」と言いました。
今回の実験で、それが意図的な設計だったことが明らかになりました。
3x3は、単なる「小さいサイズ」ではなく、identityを保存できないという性質を持つ、ギリギリのサイズなのです。
改善点の考察
では、512x512でFaceSwapを実現するには、どうすればよいのか?
- Bottleneckを3x3に固定する?
- より強力な正則化を導入する?
- アーキテクチャ自体を変更する?
続きます。
参考:
- 手探りしてみる CV/ ML/ NN: 12日目 auto-encoderで自前のモデルを作る話1:https://qiita.com/masahiroteraoka/items/d19252f2d3f37edfa9e9
- Information Bottleneck: https://arxiv.org/abs/physics/0004057

