直观理解GAN
- 将任意vector作为生成器generator的输入,用于生成generated sample。其中generator可以是一个函数或一个神经网络
- 将生成器生成的generated sample输入判别器disriminator,由判别器判断该sample是否是生成器生成的。若判断为是生成器生成的数据,判为低分;否则判为高分。其中判别器可以是一个函数或一个神经网络
如何训练GAN(GAN算法流程)
1.初始化生成器G和判别器D
2.每一轮训练包含两个部分
- 固定G的参数,训练优化D的参数
判别器D的优化目标是使判别器对数据集中采集的真实数据判为高分,而对合成数据判为低分。目标函数如下,训练目标为最大化
v
~
\widetilde{v}
v
。其中
x
i
x_i
xi表示从数据集中采集的真实数据,
x
i
~
\widetilde{x_i}
xi
表示生成器合成的数据。故目标函数第一项代表判别器要给真实数据高分,而第二项代表判别器要给合成数据低分。
v
~
=
1
m
∑
i
=
1
m
l
o
g
D
(
x
i
)
+
1
m
∑
i
=
1
m
l
o
g
(
1
−
D
(
x
i
~
)
)
\widetilde{v} = \frac{1}{m}\sum_{i=1}^mlogD(x_i)+\frac{1}{m}\sum_{i=1}^mlog(1-D(\widetilde{x_i}) )
v
=m1i=1∑mlogD(xi)+m1i=1∑mlog(1−D(xi
))
- 固定D的参数,训练优化G的参数
生成器G的优化目标是生成尽可能真实的数据来“骗过”判别器,使判别器给生成的数据高分。目标函数如下,训练目标为最大化
u
~
\widetilde{u}
u
。其中
z
i
z_i
zi表示生成器的输入值vector。
u
~
=
1
m
∑
i
=
1
m
l
o
g
D
(
G
(
z
i
)
)
\widetilde{u} = \frac{1}{m}\sum_{i=1}^mlogD(G(z_i))
u
=m1i=1∑mlogD(G(zi))
以正弦曲线生成的代码为例:
for step in range(10000):
artist_paintings = artist_works() # 真实数据
G_ideas = torch.randn(BATCH_SIZE, N_IDEAS) # 生成器的输入数据
G_paintings = G(G_ideas) # 生成器合成的数据
prob_artist1 = D(G_paintings)
G_loss = torch.mean(torch.log(1. - prob_artist1)) # u
opt_G.zero_grad() # 将模型中的参数梯度清零
G_loss.backward() # 求目标函数的梯度
opt_G.step() # 梯度下降优化,更新G的参数
# ---------------------------------------------------------
prob_artist0 = D(artist_paintings)
prob_artist1 = D(G_paintings.detach()) #锁住G的参数不求导
D_loss = -torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1)) # v
opt_D.zero_grad()
D_loss.backward(retain_graph=True) # 获取parameter.grad()
opt_D.step() # update parameters
拓展拷问
1. 可以只使用生成器完成数据的生成吗?
如果只有生成器,可以通过用(vector, real image)数据集进行有监督学习训练网络,其中vector需要尽可能精准表达图像特征(可以考虑用Auto encoder方法)。但相比较于GAN,这种方式训练学习到的很有可能是不具备整体性意义的图像,主要原因是这种方式无法处理更深的结构特征。相反,利用GAN中的判别器,借助神经网络可以更好的处理图像各component之间的联系。
2. 可以只使用判别器完成数据的生成吗?
可以的。参考穷举法,将所有vector输入判别器判断得分,最高者胜。相当于求解下式,过于复杂,不具备可行性。