shimopino / papers-challenge

Paper Reading List I have already read
30 stars 2 forks source link

On Self Modulation for Generative Adversarial Networks #140

Open shimopino opened 4 years ago

shimopino commented 4 years ago

論文へのリンク

[arXiv:1810.01365] On Self Modulation for Generative Adversarial Networks

著者・所属機関

Ting Chen, Mario Lucic, Neil Houlsby, Sylvain Gelly

投稿日時(YYYY-MM-DD)

2018-10-02

1. どんなもの?

Generatorに入力されたノイズベクトルzで、Batch Normalizationのように特徴マップを入力で条件付けるモジュールであるSelf-Modulation層を提案した。ほとんどの条件設定で既存の手法よりも高い性能を示した。

2. 先行研究と比べてどこがすごいの?

既存のGANでSOTAを達成しているモデルでは、CBN (Conditional Batch Normalizatin) が使用されているが、この手法ではラベルなどの外部情報が必要であり常に使用できるとは限らない。

本研究では外部情報を必要とせず、Generatorの出力のみを使用するSelf-Modulation層を提案した。本モジュールはどのGeneratorにも追加できる。

3. 技術や手法の"キモ"はどこにある?

外部情報を使用してGeneratorを改善する手法としては、(1)入力されるノイズベクトルにラベル情報を結合させるやり方と、(2)CBNを使用して隠れ層に直接ラベル情報を送るやり方が存在している。

まずはBNを復習すると、入力された特徴マップhlに対して平均と標準偏差を使用して正規化を行い、追加のパラメータでアフィン変換を行っている。

image

3.1 Self-modulation for unconditional (without side information) generation

本研究で提案しているSelf-Modulationでは、最初に入力されたノイズベクトルzを使用してアフィン変換で使用していたγとβを条件付けを行っている。

image

各パラメータの計算には、入力されるノイズベクトルzに対して1層の次元数の少ないMLP層とReLUを適用し、その後に線形変換を施している。

image

3.2 Self-modulation for conditional (with side information) generation

ラベル情報を使用できる場合にも本手法にその情報を組み込むことが可能である。ラベル情報とノイズベクトルに関して2つのEmbedding層を使用してラベルベクトルに変換した後で、これら2つのベクトルとの相互関係を計算している。

image

以下が各Normalization手法との比較である。

image

4. どうやって有効だと検証した?

以下がBaselineと本手法を適用した際の比較である。

image

5. 議論はあるか?

shimopino commented 4 years ago

以下のモジュールをBatchNormの代わりに使用すればいい。

import torch.nn as nn

class sBN(nn.Module):
    def __init__(self, num_features, nz, hidden_features=32):
        super().__init__()
        self.num_features= num_features

        self.bn = nn.BatchNorm2d(num_features, affine=False)
        self.z_to_h = nn.Linear(nz, hidden_features)
        self.h_to_gamma = nn.Linear(hidden_features, num_features)
        self.h_to_beta = nn.Linear(hidden_features, num_features)
        self.activation = nn.ReLU(inplace=True)

    def forward(self, x, z):
        x_norm = self.bn(x)
        h = self.activation(self.z_to_h(z))
        gamma = self.h_to_gamma(h).view(-1, self.num_features, 1, 1)
        beta = self.h_to_beta(h).view(-1, self.num_features, 1, 1)
        output = gamma * x_norm + beta
        return output