Few-shot vid2vidでイラストをアニメ風に動かしてみる

はじめに

「Few-shot Video-to-Video Synthesis」(以下、Few-shot vid2vid)は2019年に発表され話題になったGANです。[paper, github]

本記事では、まずFew-shot vid2vidについて簡単に紹介した後、実際に学習と動画生成を試した結果を書いていきます。

※本記事の調査や実験は主に2020年に行ったものです。

 

Few-shot vid2vidとは

簡単に言うと、動画→動画の変換を行うGANであるvid2vid [paper]の進化形です。下図は論文からの引用で、左がvid2vid、右がFew-shot vid2vidを示します。

 

 

vid2vidは一つのドメインで学習を行い、それについての動画生成しかできません。例えば上の図のように骨格画像から全身画像への変換を行う場合、Aさんの画像を集めて学習を行ったとしたらAさんの動画しか生成できません。Bさんの動画を生成したければ、Bさんの画像を集めて学習させる必要があります。
これに対し、Few-shot vid2vidでは複数のドメインで学習を行い、動画生成する際は学習時になかったドメインにも対応できます。例えば学習データに入れていなかったZさんの動画を生成することも可能です。この時Example imageとしてZさんの画像が必要になりますが、これは1~数枚(few shot)で機能します。

 

このようなFew-shot合成は、ネットワークの一部のモジュールの重みをExample imageから抽出した特徴量によって動的に変更することで可能になっています。
※こちらのページの解説が参考になりました。
数枚の画像で動きを転移できるFew shot vid2vid(Few shot video to video Synthesis)

 

また公式の動画では、彫刻を躍らせたり絵画をしゃべらせたりといった応用が紹介されていて面白いです。
Few-Shot Video-to-Video Synthesis (youtube)

 

実験

今回はFew-shot vid2vidを使って、2次元キャラの顔イラストを動かす実験をしてみました。
公式の動画では絵画(モナリザ)を動かしていますが、よりデフォルメされたイラストでも上手く動かせるのか気になったからです。

作業環境

自宅のゲーム用PCにUbuntuとCUDA等を入れて作った環境です。
OS : Ubuntu 18.04.4 LTS
GPU : GeForce RTX 2060 SUPER(8GB) x1

データセット作成

Few-shot vid2vidを学習させるには、元画像と対になるラベル画像のセットが大量に必要です。

元画像については、公開されているアニメ画像データセットをいくつか取得し、スクリプトでキャラの顔部分だけ切り抜いて用意しました。

次にラベル画像の作成方法ですが、調べたところアニメ顔用のlandmark検出ツールが公開されていたため、こちらを使わせて頂きました。

Anime face landmark detection by deep cascaded regression

 

流れとしては以下の通りです。

  1. landmark検出により目や口などのパーツの代表点を取得
  2. 各点の位置を元に顔ラベルを描画
    ここの処理はOpenCVのrectangle()やfillPoly()などを使って作りました。
  3. 元絵と顔ラベルをペアとして、Few-shot vid2vidで使える形式のデータセット作成

landmark検出点をそのまま使わずに顔ラベルを描くことにしたのは、その方が各パーツの大きさや位置を制御しやすいと思ったからです。(以前、pix2pixHD等で遊んでいた時の経験から)
ただ、このラベルの描き方が本当に良いかは分かりません。この描き方の違いで生成結果の質はかなり変わると思います。

また、3. のデータセット作成に際しては拡大・縮小・回転等のaugmentationを行っています。この時、Few-shot vid2vidに適したシーケンスデータ(時系列的に連続して変化)となるよう調整しました。
1シーケンスにつき元画像/顔ラベルをそれぞれ20枚とし、最終的に約3000シーケンスの学習データを用意しました。

学習

作成したデータセットで、Few-shot vid2vidの学習を行いました。
基本的には本家のコード通りですが、以下の点は変更しています。

  • 1回のiterationで使うシーケンス枚数の最大値(seq_len_max)
    これはdata/base_dataset.py内で指定されている。(デフォルト値は30)
    GPUメモリサイズと学習時間の問題のため、30->16に変更。
  • 生成画像の解像度
    学習時のオプションで、生成画像の解像度を288x288に指定。
    GPUメモリサイズによりこの位が限界だった。本当はもっと大きくしたい。

学習に要した時間は3日程度でした。

 結果

学習後のモデルを使い、動画生成の確認を行いました。
ここでは学習時に使っていない画像として、StyleGANで生成したイラストをExample imageに使用しました。

※StyleGANによるイラスト生成は以前別の記事で確認しています。

 

結果を以下に示します。
 静止画: Example image (動かしたいイラスト)
 動画: 一番左が顔ラベルの入力、右側が対応する生成結果
となります。

 

以下、もう一例。

 

全体的に、元絵の特徴をある程度維持しつつ動かせているようでした。

元絵で目を閉じている例が一つありますが、その場合の瞳の色は推測で(確率的に?)自然な色にしてくれていると思われます。

 

ただ、問題点として以下のような傾向がみられました。

  1. 表情や頭の動きが大きくなると、目や口の周囲に期待しない線が出たり、髪の部分がぼやけてしまう。
  2. 顔や目の縦横比、目の離れ方などが入力する顔ラベルのパーツで規定されるため、元絵の個性に影響を与えてしまう。

1. はデータセットの作り方次第で多少改善できる可能性がありますが、2. は今回の方法だと対応が難しいかもしれません。

 

まとめ

Few-shot vid2vidを使って顔イラストを動かせるか試してみました。ある程度期待通りの挙動が見られ、実験結果としては面白かったです。(クオリティが高いとは言えませんが)

今回は顔限定でしたが、これが全身イラストとなると更に相当ハードルが上がると思われます。GANの技術はかなり進歩してきていますが、2次元キャラの場合は実写と比べて少しの粗でも目立ってしまうので、自然な動きを実現するのは難易度が高そうです。

 

今回の記事は以上です。