メモ

自分に向けて書いたメモを取り扱っています.

Why does the loss function of discriminator use softplus on GAN

GANで使われる Discriminator の損失計算の実装を見てみると,softplus関数を使っていることがあります.
これは,sigmoid関数でcross entropyを計算することと同じことをしています.

Softplus

$$\text{softplus}(x)=\log{(1+\exp{x})}$$

Sigmoid

$$f(x)=\frac{1}{1 + \exp{(-x)} }$$

Binary cross entropy

$$g(y, t)= - t \log{y} - (1-t) \log{(1-y)}$$

t=0とt=1のときのg(f(x), t)の挙動

\begin{align}
g(f(x), t=0)&=\log{(1-f(x))} \\
&= - \log{ \left( 1 - \frac{1}{1 + \exp{(-x)} } \right) } \\
&= - \log{ \left( \frac{ 1 + \exp{(-x)} - 1 }{ 1 + \exp{(-x)} } \right) }\\
&= - \log{ \left( \frac{ \exp{(-x)} }{ 1 + \exp{(-x)} } \right) } \\
&= - \log{ \left( \frac{1}{ \exp{x} + 1} \right) } \\
&= \log{ \left( \frac{1}{ \exp{x} + 1} \right)^{-1}} \\
&= \log{ \left( 1 + \exp{(x)} \right)} = \text{softplus}(x) \\
g(f(x), t=1)&= - \log{(f(x))} \\
&= - \log{ \left( \frac{1}{1 + \exp{(-x)} } \right) } \\
&= \log{ \left( \frac{1}{ 1+ \exp{(-x)} } \right)^{-1}} \\
&= \log{ \left( 1 + \exp{(-x)} \right)} = \text{softplus}(-x)
\end{align}

Discriminatorの学習は X_real に対しては1を, X_fake に対しては0になるようにします.
確かに https://github.com/chainer/chainer/blob/master/examples/dcgan/updater.py#L13-L19
ソースコードを見ると,

    def loss_dis(self, dis, y_fake, y_real):
        batchsize = len(y_fake)
        L1 = F.sum(F.softplus(-y_real)) / batchsize
        L2 = F.sum(F.softplus(y_fake)) / batchsize
        loss = L1 + L2
        chainer.report({'loss': loss}, dis)
        return loss

X_realに対してはsoftplus(-x)を,X_fakeに関してはsoftplus(x)を使用して損失を計算していることが分かります.

Generatorの学習は,生成した画像に対してラベルが1(本物)になるようにしたいので softplus(-x) を使用して学習します.
直感的に考えると生成した画像は活性化関数を通っているとはいえ,ある種の正規化されたピクセルを持っているわけで,各ピクセルが1になるようにするということは,つまり画像を真っ白にすることなのでヤバそうなのですが,Discriminatorの学習もあるので結局良い感じにパラメータが学習されるのかな,と自分は解釈しています. かなり馬鹿なことを書いてました.ちゃんとソースコードを読むと,generatorで生成したxに対してdiscriminatorを通して損失を計算しているので,画像を真っ白にするとかそんなことはやっていないです.)