Bài 4: Least Squares Generative Adversarial Networks (LSGAN) | Deep Learning cơ bản
 

Bài 4: Least Squares Generative Adversarial Networks (LSGAN)

| Posted in GAN

Trong series GAN này mình đã giới thiệu về ý tưởng của mạng GAN, cấu trúc mạng GAN với thành phần là Generator và Discriminator, GAN loss function. Tuy nhiên GAN loss function không tốt, nó bị vanishing gradient khi train generator bài này sẽ tìm hiểu hàm LSGAN để giải quyết vấn đề trên.

Vấn đề với GAN loss function

Bổ đề

Xét hàm f(x) = a*log(x) + b*log(1-x). Tìm x sao cho hàm f(x) cực đại

Ta có: \displaystyle f'(x) = \frac{a}{x} - \frac{b}{1-x}

\displaystyle f'(x) = 0 \Leftrightarrow \frac{a}{x} = \frac{b}{1-x} \displaystyle \Leftrightarrow x = \frac{a}{a+b}

Do đó f(x) cực đại khi \displaystyle x = x^* = \frac{a}{a+b}

GAN loss function

x là ảnh thật, \displaystyle p_r(x) là distribution sinh ra ảnh thật, z là noise, \displaystyle p_z(z) là distribution sinh ra noise, G là generator, D là discriminator. GAN loss function:

\displaystyle \min_{G} \max_{D} V(D, G) = \operatorname{\mathbb{E}}_{x\sim p_r(x)}[\log D(x)] + \operatorname{\mathbb{E}}_{z\sim p_z(z)}[\log (1 - D(G((z))] \newline\newline \displaystyle \quad\quad\quad\quad\quad\quad = \operatorname{\mathbb{E}}_{x\sim p_r(x)}[\log D(x)] + \operatorname{\mathbb{E}}_{x\sim p_g(x)}[\log (1 - D(x)] \newline\newline \displaystyle \quad\quad\quad\quad\quad\quad = \int_x (p_r(x)\log D(x) + p_g(x)\log (1 - D(x)))dx

Trong đó \displaystyle p_r(x) là distribution sinh ra ảnh thật, \displaystyle p_g(x) là distribution sinh ra ảnh fake (chính là generator)

Ta thấy \displaystyle \min_{G} \max_{D} V(D, G) có 2 việc tìm D để max V và tìm G để min V. Trước tiên ta tìm D để max V(D, G) với G là hằng số.

Áp dụng bổ đề ta có, V max khi:

\displaystyle D(x) = D^*(x) = \frac{p_r(x)}{p_r(x) + p_g(x)}

Ta thay D(x) vào V để tìm \displaystyle \min_{G} V(D^*, G)

\displaystyle \min_{G} V(D^*, G) = \int_x (p_r(x)\log D^*(x) + p_g(x)\log (1-D^*(x)))dx \newline \displaystyle \quad\quad\quad\quad\quad\quad= \int_x (p_r(x)\log\frac{p_r(x)}{p_r(x) + p_g(x)} + p_g(x)\log(\frac{p_g(x)}{p_r(x) + p_g(x)}))dx

Jensen–Shannon divergence (JS), Kullback–Leibler divergence (KL) dùng để tính độ tương đồng giữa hai distribution, giá trị nhỏ nhất là 0 khi 2 distribution giống nhau.

Ta có:

\displaystyle D_{JS}(p_r \| p_g) = \frac{1}{2} D_{KL}(p_r \| \frac{p_r + p_g}{2}) + \frac{1}{2}D_{KL}(p_g \| \frac{p_r + p_g}{2}) \newline \displaystyle \quad\quad\quad\quad\quad\quad = \frac{1}{2} (\int_x p_r(x)\log \frac{2p_r(x)}{p_r(x) + p_g(x)}dx) + \frac{1}{2}(\int_{x}p_g(x)\log\frac{2p_g(x)}{p_r(x) + p_g(x)}) \newline \displaystyle \quad\quad\quad\quad\quad\quad = \frac{1}{2} (\log 2 + \int_x p_r(x)\log \frac{p_r(x)}{p_r(x) + p_g(x)}dx) + \frac{1}{2}(\log 2 + \int_{x}p_g(x)\log\frac{p_g(x)}{p_r(x) + p_g(x)}) \newline \displaystyle \quad\quad\quad\quad\quad\quad = \frac{1}{2}(\log 4 + \min_G V(D^*, G))

Do đó:

\displaystyle \min_{G} V(D^*, G) = 2D_{JS}(p_r\| p_g) - 2\log 2 , do đó \displaystyle \min_{G} V = -2\log 2 khi \displaystyle p_r =p_g (\displaystyle D_{JS} = 0) )

Trục x là khoảng cách mean giữa distribution p và q, trục y là giá trị JS giữa p và q, nguồn

Nhận xét: khi \displaystyle p_r, p_g xa nhau (không giống nhau) thì đạo hàm của \displaystyle D_{JS}(p_r\| p_g) về 0 dẫn tới vanishing gradient.

Khi mới bắt đầu train thì Generator sinh ra ảnh nhiễu nên rất dễ cho discriminator học để phân biệt ảnh thật và giả, tuy nhiên \displaystyle p_r, p_g rất khác nhau dẫn tới vanishing gradient nên việc học của Generator không tốt.

Do đó loss GAN truyền thống thì Discriminator học rất tốt nhưng thường không tốt cho Generator => Cần hàm loss function tốt hơn để train GAN model.

Least squares GAN (LSGAN)

LSGAN được thiết kế để train generator tốt hơn. LSGAN được định nghĩa như sau:

\displaystyle \min_{D} V_{LSGAN} (D) = \frac{1}{2} \operatorname{\mathbb{E}}_{x\sim p_{data}(x)}[(D(x) - b)^2] + \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)) - a)^2] (1) \newline \displaystyle \min_{G} V_{LSGAN} (G) = \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)) - c)^2] (2)

Trong đó a và b là target label của ảnh từ ảnh sinh ra từ generator (G(z)) và dataset (x) khi train discriminator; c là target label của G(z) khi train Generator. Do \displaystyle \min_{G} V_{LSGAN} (G) không phụ thuộc vào D nên ta có thể viết (2) lại thành:

\displaystyle \min_{G} V_{LSGAN} (G) = \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_{data}(x)}[(D(x) - c)^2] + \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)) - c)^2] (3)

Từ (1) ta thấy \displaystyle \min_{D} V_{LSGAN} (D) nhỏ nhất khi

\displaystyle D = D^*(x) = \frac{bp_{data}(x) + ap_g(x)}{p_{data}(x) + p_g(x)} (4)

Thay (4) vào (3) với b – c = 1 và b – a = 2 ta được:

\displaystyle \min_{G} V_{LSGAN} (G) = \int_{\chi} \frac{(2p_g(x) - (p_d(x) + p_g(x)))^2}{p_d(x) + p_g(x)}dx \newline \displaystyle \quad\quad\quad\quad\quad\quad = \chi_{Pearson}^2(p_d+p_g \| 2p_g)

Trong đó \displaystyle \chi_{Pearson}^2 Pearson χ2 divergence

So sánh giữa JSD và Pearson χ2 divergence

Nhận thấy là khi \displaystyle p_r, p_g xa nhau thì đạo hàm của \displaystyle D_{JS}(p_r\| p_g) về 0 dẫn tới vanishing gradient, tuy nhiên Pearson χ2 divergence thì vẫn có đạo hàm và tránh được vanishing gradient => BOOM !!!!!!!!!!!

Vậy là LSGAN giải quyết vấn đề vaninshing gradient khi train Generator. Thực nghiệm cho thấy LSGAN có thể sinh ra ảnh chất lượng tốt hơn GAN cũng như ổn định hơn khi train.

Ảnh nhà thờ sinh ra dùng LSGAN

Để thỏa mãn b – c = 1 và b – a = 2, ta chọn b = 1, c = 0, a = -1 do đó LSGAN được viết lại thành:

\displaystyle \min_{D} V_{LSGAN} (D) = \frac{1}{2} \operatorname{\mathbb{E}}_{x\sim p_{data}(x)}[(D(x) - 1)^2] + \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)) + 1)^2] \newline \displaystyle \min_{G} V_{LSGAN} (G) = \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)))^2]

Ngoài ra có thể chọn b = c để ảnh fake sinh ra giống ảnh thật, mình có thể dùng ý tưởng hàm sigmoid ra giá trị (0, 1) sẽ để ảnh fake về 0 và ảnh real về thật, nhưng dùng MSE để tối ưu, chọn b = c = 1, a= 0. Ta có hàm LSGAN thay thế:

\displaystyle \min_{D} V_{LSGAN} (D) = \frac{1}{2} \operatorname{\mathbb{E}}_{x\sim p_{data}(x)}[(D(x) - 1)^2] + \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)))^2] \newline \displaystyle \min_{G} V_{LSGAN} (G) = \frac{1}{2} \operatorname{\mathbb{E}}_{z\sim p_z(z)}[(D(G(z)) - 1)^2]

Thực nghiệm cho thấy 2 cách chọn tham số này cho kết quả tương đương nhau.

Trực quan hóa

Phần trên mình đã dùng toán để chứng minh LSGAN tránh được vanishing gradient so với loss function truyền thống. Phần này sẽ giải thích trực quan hơn tại sao LSGAN lại hoạt động.

Mình dùng hàm sigmoid loss function thì khi z xa với 0 (|z| > 5) thì hàm sigmoid bị vanishing gradient. Do đó khi z xa với 0 thì 10, 100 hay 1000 hầu như như nhau.

Hàm sigmoid

Mình nhớ lại bài logistic regression thì bài toán chính là đi tìm đường phân chia giữa 2 lớp.

Đường phân chia Discriminator

Như mình nói ở trên khi z xa 0 thì Discriminator sẽ không quan tâm lắm việc nó xa bao nhiêu mà chỉ quan tâm đến nằm phía nào của đường phân chia thôi. Rõ ràng như thế là không tốt vì những điểm gần đường phân chia hơn cần tốt hơn những điểm xa hơn.

LSGAN dùng L2 loss, rõ ràng là đánh giá được những điểm gần hơn sẽ tốt hơn. Và không bị hiện tượng vanishing gradient như hàm sigmoid do đó có thể train được Generator tốt hơn.

LSGAN

Code

Lý thuyết thì mọi người thấy nhiều nhưng code chỉ cần thay loss function từ binary_crossentropy sang mse (mean square error)

# dùng mean squared error
d_model.compile(loss='mse', optimizer=Adam(lr=0.0002, beta_1=0.5))
gan_model.compile(loss='mse', optimizer=Adam(lr=0.0002, beta_1=0.5))

# cập nhật discriminator, ảnh thật -> 1, ảnh fake -> 0
d_loss1 = d_model.train_on_batch(X_real, 1)
d_loss2 = d_model.train_on_batch(X_fake, 0)
# cập nhật generator, ảnh fake -> 1
g_loss = gan_model.train_on_batch(z_input, 1)


Deep Learning cơ bản ©2024. All Rights Reserved.
Powered by WordPress. Theme by Phoenix Web Solutions