Pose Guided Person Image Generation

5/25 arXivに投稿された,Pose Guided Person Image Generation という論文を読みました.

[1705.09368] Pose Guided Person Image Generation

 

 

Pose Guided Person Generation Network

 服や人の情報を残して,任意のポーズを取った,人の画像を生成したい.

 

{PG^2} Network は,2つのステージで構成される.

 一つ目のステージ

  同一人物のポーズを変えた,ぼんやりとした画像を生成

 2つ目のステージ

  ぼんやりとした画像を高精度にするためのconditional GAN

 

・ネットワークの構造

 ステージ1:

  Generator1:encoder-decoder U-netに似ている.

  encoderやdecoderの各層はResidual Block になっている.

  encoderとdecoderの間には全結合層がある.

 

 ステージ2:

  GAN

  Generator2:encoder-decoder U-netに似た構造.

        encoderやdecoderの各層はResidual Block になっている.

        encoderとdecoderの間には全結合層がない

  Discriminator: DCGANのDisciminator

 

 

・Loss関数

 

 ステージ1:poseMaskLoss ( L1損失関数+poseMask )

  poseMaskによって,ターゲットにしているポーズの位置の損失を強調する.

 

 ステージ2:

  Generator2の損失関数は,

    Discriminatorが real 画像だと判定したかどうか

    → ラベル1とDの出力値の binary cross-entropy

    さらに,poseMaskLossも加える.

  Discriminatorは,

    real 画像が入力された時には,1

    fake 画像が入力された時には,0が出力されているかどうかで

     binary cross-entropy 

 

 

・データセット

 Market-1501 http://www.liangzheng.org/Project/project_reid.html 

  re-identification のデータセット

DeepFashion http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html 

 服などのデータセット

 

 poseMaskLossは背景変化の影響の低減のため,人物の体に注目するようにするための工夫.

 したがって,DeepFashionのように白背景の場合は大きな効果は得られないようだ.

 

 

・データの前処理

 pose-estimationをして,18点の,関節や頭の位置を示した18 x 1chの白黒画像を作る

 論文中には state of the art な手法で推定したとあり,

GitHub - ZheC/Realtime_Multi-Person_Pose_Estimation: Code repo for realtime multi-person pose estimation in CVPR'17 (Oral)

を使っている.しかし今はもうOpenPoseが state of the art ?

 

 

・実装

 U-net like なネットワーク構造で,https://arxiv.org/pdf/1612.05360 で提案されているU-net 風のものを使っているようだ.

 U-net との違いは,skip-connectionをconcatではなく,要素ごとの和にしている点.

 

 論文中には,ダウンサンプリングやアップサンプリングの手段が載っていなかったので,自分の実装では,

 Conv2d stride=2 でダウンサンプリング.

 ConvTranspose2d stride=2 でアップサンプリング.

 

 また,encoder側のResidual Blockのどの位置からskip connectionを作り,どのいちでdecoder側に足しこむのかに関しては明らかになっていない.

 

 論文中のNetwork architectureの図にはいくつか間違いが含まれているので,その部分のアップデートと共により詳しい構造について述べられるのを期待したい.

 

 

・結果 

(学習中)

 

・コード (ここ)

 DeepFashion用.

 データの前処理として,Pose-estimationが必要.

 変数 dataloader にバッチごとの画像をだすイテレーターを設定しないと動かない.

 

 

infoGANを実装した(い)

infoGANの論文を読み,MNIST用の実装をPyTorchで行った記録です.

論文は2016年6月に出ているので1年ほど前のもの.

[1606.03657] InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets

 

タイトルを日本語訳すると,「情報量を最大化する敵対的生成ネットワークによる解釈可能な表現の学習」でしょうか.

 

infoGANの特徴

・GAN

・明快な表現を獲得する

・教師なし学習

相互情報量の最大化(隠れ符号と生成画像間の)

・DCGANの一部を変えるだけで作れ,訓練も簡単

 

相互情報量は,2つの確率変数のうち1つがわかった時に,もう1つの確率変数に関してどれほど推測できるかを示すので,2つが独立な時には相互情報量は0になります.

今回のinfoGANでは,その相互情報量を最大化するので,隠れ符号と生成画像の相互依存性を高めるように学習させようということになります.

 

実装に関して

・ネットワーク

 DCGANをベースにして,論文のAppendix通りにQネットワークを付け足す.

 隠れ符号cを出力するQnetとDnetは畳み込み層全てを共有する.

 

 出力層に関して,論文中に記載されていなかったように思うので,雑に設定してしまった.

  Dの出力層は,ノード2つ,ソフトマックス関数

  Qの出力層は,ノード12つ,

    うちカテゴリカル符号は10次元分,

    うちコンティニュアス符号は2次元分.

  Gの入力には,62次元のzと,12次元のcを単純につなぎ合わせた74次元のノイズ.

 

・損失関数

 Dの損失関数は,2つのノードをからソフトマックスをへてクロスエントロピーを計算.realの時には1を出力,fakeの時には0を出力できているか.

(F.CrossEntropyLoss でlogSoftMaxが行われるから2回もソフトマックス計算している??)

 

 Gの損失関数は,Gを経由した生成画像がDでrealつまり1と出力されるかでクロスエントロピー

 

 Qの損失関数は,カテゴリカル符号は10次元のone-hotで評価.ターゲットにしている数字を示すラベルが出てきているかでクロスエントロピー誤差.

コンティニュアス符号は,論文中にこのような記述.

For continuous latent codes, we parameterize the approximate posterior through a diagonal Gaussian distribution,

出力された符号は,対角ガウス分布に従うようにパラメタライズするようです.

正直よくわからなかったので,

GitHub - hvy/chainer-infogan: Chainer implementation of InfoGAN

こちらの方のchainerによる実装を参考にさせてもらったところ,gaussian_nllというロス関数を使っていたので,真似してやり過ごしました.

 

・backward

 どこで .detach() するかは重要ですが,DCGANと同じでいいはずで,Dをバックワードする時にGに行かないようにする.GはDごとバックワード.そして,出力されたcはGもDも通って来ていてそのままバックワードすることにしました.

 

 

結果

・カテゴリカル符号(10次元)をone-hotで入力した時の出力

入力[1,0,0,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0,0,0],,,,

 

f:id:akmtn:20170529203241p:plain

順番は揃っていませんが,数字を各カテゴリに分けることができています.

 

コンティニュアス符号(1次元が2つ)

各行ごとにカテゴリ(数字の種類)を固定して,一つのcontinuous cを変化.

f:id:akmtn:20170529203245p:plain

数字の傾きが変化していることから,一つのcはローテーションという表現を獲得していることがわかります.

 

もう一つのcontinuous cを変化.

f:id:akmtn:20170529203249p:plain

1がはっきりしていますが,太いものから細いものへと変化しています.cが太さという表現を獲得しています.

 

 

 

 

ここまで200epochほどで学習が少ないかもしれませんが,DCGANなどでは解釈が難しかったzですが,infoGANによって1つの符号が明快な表現を意味するようになったことを確認できました.

 

改善すべき点は多いですがコードはここにあります.

自己符号化器,AutoEncoderの実装

機械学習プロフェッショナルシリーズの「深層学習」のChapter5を参考に,PyTorchでAutoEncoderの実装を行いました.

 

パラメータとしては,

 入出力層が28x28次元,

 中間層が100次元,

 (28x28 -> 100 -> 28x28)

 中間層の活性化関数はReLU,

 出力層の活性化関数は恒等写像

 重みはガウス分布(σ=0.01)で初期化,

 SGD(重み減衰λ=0.1,モメンタムµ=0.5

 Loss関数は二乗誤差

にしました.

 SGDよりもAdamの方がLossが落ちたのでAdamに変更しました.

 

結果としては,

f:id:akmtn:20170518183029p:plain

このようになり,数字は認識できます.画像全体として(背景が?)白くなっているのは,重み0が濃淡256階層の中央に来るように調整することで治るのかもしれません.

中間層のユニットを100個よりも大きくすると,よりLossも下がり,よりくっきりとした画像が得られました.中間層のユニットの数が特徴の表現力を表していることを実感できます.

 

コードはここにあります.

シンプルなGANの実装

GANの論文を読んだついでにMNIST用に実装しました.

ネットワークには,Convolutionを使わず,多層ニューラルネットです.層の数,活性化関数やバッチ正規化などの設定はてきとうです.なのでGANもどきです.

f:id:akmtn:20170514191216p:plainがんもどき

 

pytorchで実装したかったので,本家のDCGANのコードを参考にしながら書きました.

github.com

また,こちらの方の実装も参考にしました.(keras)

yusuke-ujitoko.hatenablog.com

 

結果として,以下のような出力を得ました.

f:id:akmtn:20170514190525p:plain

それなりに数字には見えますが,1が多い一方,2が少ないという偏りがありました.

 

一応,コードはここにあります.