简记GAN网络的loss

《简记GAN loss的理解》

  GAN 是一种思想,刚接触的时候极为震撼,后来通过GAN思想也做过模型的优化,写过一篇专利。最近在用 GAN 生成数据,顺手写一写对GAN loss的理解。

Key Words:GAN、SegAN


Beijing, 2021.01

作者:RaySue

Agile Pioneer  


GAN loss

GAN 网络一般形式的 loss 如下:

min ⁡ G max ⁡ D E x ∼ P d a t a [ l o g ( D ( x ) ) ] + E z ∼ P z [ l o g ( 1 − D ( G ( z ) ) ) ] \min_{G}\max_{D} \mathbb{E}_{x \sim P_{data}} [log (D(x))] + \mathbb{E}_{z \sim P_{z}} [log (1 - D(G(z)))] GminDmaxExPdata[log(D(x))]+EzPz[log(1D(G(z)))]

其中:D(x) 是判别器,G(z) 是生成器。判别器的目的是最大化 loss,生成器是为了最小化 loss。 GAN 是一种思想,GAN 可以做很多任务,但万变不离其宗,就是最大,最小化损失,以达到生成对抗的目的。

  • 为什么 D(x) 是期望其最大化 ?

D(x) 对应的损失有两项,第一项 E x ∼ P d a t a [ l o g ( D ( x ) ) ] \mathbb{E}_{x \sim P_{data}} [log (D(x))] ExPdata[log(D(x))],第二项 E z ∼ P z [ l o g ( 1 − D ( G ( z ) ) ) ] \mathbb{E}_{z \sim P_{z}} [log (1 - D(G(z)))] EzPz[log(1D(G(z)))],并且D(x) ∈ \in [0, 1],而 l o g ( x ) log(x) log(x) 在[0, 1] 上单调递增,我们期望真实的数据 D ( x ) D(x) D(x)是趋近于1 的,所以第一项期望增大。第二项中 D ( G ( z ) ) D(G(z)) D(G(z))生成数据期望其趋向于 0,所以整体也是递增的,所以D(x) 对应的整体期望是要更大的,即 max ⁡ D \max_{D} maxD

  • G(x) 最小化的 loss 是什么?

G(x) 生成数据输入生成数据到 D ( x ) D(x) D(x) 得到判别的结果,以标签为1 进行训练,目的是为了让 G ( x ) G(x) G(x) 的结果更真实,来最小化这个loss;也以此来迷惑 D ( x ) D(x) D(x),这样如果生成数据太假就会产生很大的 loss ,注意,这里的loss仅用于优化生成器,所以整个网络才会work。

G(x) 对应的损失为第二项 E z ∼ P z [ l o g ( 1 − D ( G ( z ) ) ) ] \mathbb{E}_{z \sim P_{z}} [log (1 - D(G(z)))] EzPz[log(1D(G(z)))] ,我们想让生成数据更接近 真实数据,所以 D ( G ( z ) ) D(G(z)) D(G(z))就趋向于1,整体就期望更小,即 min ⁡ G \min_G minG

整体的思想就是:

  1. 判别器和生成器各司其职,判别器通过先验知识,知道哪部分数据来自生成器,哪部分是真实数据,所以尽管生成的再像真实数据,也会当成负样本来学习,让判别器越来越强

  2. 而生成器将其生成的结果送入判别器,并将判别器返回的预测结果利用真实数据标签来训练,以此来迷惑判别器,从而产生更接近于真实数据的结果


通过代码理解 GAN

  • 先训练 D(x) 再训练 G(x) 交替进行

  • 判别器 D(x) 和生成器 G(x) 利用两个优化器,每个优化器单独负责优化对应的网络参数。

  • D(x) 训练的过程:将真实数据的标签定义为 1,将生成数据定义标签为 0

  • G(x) 训练的过程:将生成的数据的标签定义为1,和经过 D(x) 的判别结果计算损失来更新参数。

criterion = nn.BCELoss()  # Binary cross entropy: http://pytorch.org/docs/nn.html#bceloss
d_optimizer = optim.SGD(D.parameters(), lr=d_learning_rate, momentum=sgd_momentum)
g_optimizer = optim.SGD(G.parameters(), lr=g_learning_rate, momentum=sgd_momentum)

D.zero_grad()
#  1A: Train D on real
d_real_data = Variable(d_sampler(d_input_size))
d_real_decision = D(preprocess(d_real_data))
d_real_error = criterion(d_real_decision, Variable(torch.ones([1,1])))  # ones = true
d_real_error.backward() # compute/store gradients, but don't change params

#  1B: Train D on fake
d_gen_input = Variable(gi_sampler(minibatch_size, g_input_size))
d_fake_data = G(d_gen_input).detach()  # detach to avoid training G on these labels
d_fake_decision = D(preprocess(d_fake_data.t()))
d_fake_error = criterion(d_fake_decision, Variable(torch.zeros([1,1])))  # zeros = fake
d_fake_error.backward()
d_optimizer.step()     # Only optimizes D's parameters; changes based on stored gradients from backward()


G.zero_grad()

gen_input = Variable(gi_sampler(minibatch_size, g_input_size))
g_fake_data = G(gen_input)
dg_fake_decision = D(preprocess(g_fake_data.t()))
g_error = criterion(dg_fake_decision, Variable(torch.ones([1,1])))  # Train G to pretend it's genuine

g_error.backward()
g_optimizer.step()  # Only optimizes G's parameters

SegAN

投稿于 Neuroinformatics (2018) 的一篇论文

  • 通过GAN加持语义分割,能够让学习到的结果更加精细

  • SegAN 和 GAN 一样的两部分 loss,

  • 通过预测的 01 mask(生成数据)和原图取交然后输入到 D(x) 中得到一个 res_mask

  • 通过真实的 01 mask(真实数据) 和原图取交然后输入到 D(x) 中得到 target_mask

  • 训练D(x) 的时候直接取 -mae (res_mask, target_mask) 让误差向大了学,判别能力越来越强,越来越挑剔

  • 训练G(x) 的时候则 mae(res_mask, target_mask) 让误差减小,让学到的更像target

损失函数:

min ⁡ θ S max ⁡ θ C L ( θ S , θ C ) = 1 N ∑ n = 1 N l m a e ( f C ( x n ⋅ S ( x n ) ) , f C ( x n ⋅ y n ) ) \min_{\theta_S}\max_{\theta_C} L(\theta_S, \theta_C) = \frac{1}{N}\sum_{n=1}^{N}l_{mae}(f_C(x_n \cdot S(x_n)), f_C(x_n \cdot y_n)) θSminθCmaxL(θS,θC)=N1n=1Nlmae(fC(xnS(xn)),fC(xnyn))

  • x n x_n xn 原图
  • y n y_n yn 预测结果

参考

https://www.cnblogs.com/walter-xh/p/10051634.html

https://zhuanlan.zhihu.com/p/78822561?from_voters_page=true

https://blog.csdn.net/sunyao_123/article/details/80288398

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值