f-GAN简介:GAN模型的生产车间
By 苏剑林 | 2018-09-29 | 172359位读者 |今天介绍一篇比较经典的工作,作者命名为f-GAN,他在文章中给出了通过一般的f散度来构造一般的GAN的方案。可以毫不夸张地说,这论文就是一个GAN模型的“生产车间”,它一般化的囊括了很多GAN变种,并且可以启发我们快速地构建新的GAN变种(当然有没有价值是另一回事,但理论上是这样)。
局部变分 #
整篇文章对f散度的处理事实上在机器学习中被称为“局部变分方法”,它是一种非常经典且有用的估算技巧。事实上本文将会花大部分篇幅介绍这种估算技巧在f散度中的应用结果。至于GAN,只不过是这个结果的基本应用而已。
f散度 #
首先我们还是对f散度进行基本的介绍。所谓f散度,是KL散度的一般化:
Df(P‖Q)=∫q(x)f(p(x)q(x))dx
注意,按照通用的约定写法,括号内是p/q而不是q/p,大家不要自然而言地根据KL散度的形式以为是q/p。
可以发现,这种形式能覆盖我们见过的很多概率分布之间的度量了,这里直接把论文中的表格搬进来(部分)
距离名称计算公式对应的f总变差12∫|p(x)−q(x)|dx12|u−1|KL散度∫p(x)logp(x)q(x)dxulogu逆KL散度∫q(x)logq(x)p(x)dx−loguPearson χ2∫(q(x)−p(x))2p(x)dx(1−u)2uNeyman χ2∫(p(x)−q(x))2q(x)dx(u−1)2Hellinger距离∫(√p(x)−√q(x))2dx(√u−1)2Jeffrey距离∫(p(x)−q(x))log(p(x)q(x))dx(u−1)loguJS散度12∫p(x)log2p(x)p(x)+q(x)+q(x)log2q(x)p(x)+q(x)dx−u+12log1+u2+u2logu
凸函数 #
上面列举了一堆的分布度量以及对应的f,那么一个很自然的问题是这些f的共同特点是什么呢?
答案是:
1、它们都是非负实数到实数的映射(R∗→R);
2、f(1)=0;
3、它们都是凸函数。
第一点是常规的,第二点f(1)=0保证了Df(P‖P)=0,那第三点凸函数是怎么理解呢?其实它是凸函数性质的一个最基本的应用,因为凸函数有一个非常重要的性质(詹森不等式):
E[f(x)]≥f(E[x])
也就是“函数的平均大于平均的函数”,有些教程会直接将这个性质作为凸函数的定义。而如果f(u)是光滑的函数,我们一般会通过二阶导数f″(u)是否恒大于等于0来判断是否凸函数。
利用(2),我们有
∫q(x)f(p(x)q(x))dx=Ex∼q(x)[f(p(x)q(x))]≥f(Ex∼q(x)[p(x)q(x)])=f(∫q(x)p(x)q(x)dx)=f(∫p(x)dx)=f(1)=0
也就是说,这三个条件保证了f散度是非负,而且当两个分布一模一样时f散度就为0,这使得Df可以用来简单地度量分布之间的差异性。当然,f散度原则上并没有保证P≠Q时Df(P‖Q)>0。但通常我们会选择严格凸的f(即f″(u)恒大于0),那么这时候可以保证P≠Q时Df(P‖Q)>0,也就是说这时候有Df(P‖Q)=0⇔P=Q。(注:即便如此,一般情况下Df(P‖Q)仍然不是满足公理化定义的“距离”,不过这个跟本文主题关系不大,这里只是顺便一提。)
凸共轭 #
现在从比较数学的角度讨论一下凸函数,一般地,记凸函数的定义域为D(对于本文来说,D=R+)。选择任意一个点ξ,我们求y=f(u)在u=ξ处的切线,结果是
y=f(ξ)+f′(ξ)(u−ξ)
考虑两者的差函数
h(u)=f(u)−f(ξ)−f′(ξ)(u−ξ)
所谓凸函数,直观理解,就是它的图像总在它的(任意一条)切线上方,因此对于凸函数来说下式恒成立
f(u)−f(ξ)−f′(ξ)(u−ξ)≥0
整理成
f(u)≥f(ξ)−f′(ξ)ξ+f′(ξ)u
因为不等式是恒成立的,并且等号是有可能取到的,因此可以导出
f(u)=max
换新的记号,记t=f'(\xi),并从中反解出\xi(对于凸函数,这总能做到,读者可以自己尝试证明),然后记
\begin{equation}g(t) = - f(\xi) + f'(\xi) \xi\end{equation}
那么就有
\begin{equation}f(u) = \max_{t\in f'(\mathbb{D})}\big\{t u - g(t)\big\}\end{equation}
这里的g(t)就称为f(u)的共轭函数。留意花括号里边的式子,给定f后,g也确定了,并且整个式子关于u是线性的。所以总的来说,我们做了这样的一件事情:
对一个凸函数给出了线性近似,并且通过最大化里边的参数就可以达到原来的值。
注意给定u,我们都要最大化一次t才能得到尽可能接近f(u)的结果,否则随便代入一个t,只能保证得到下界,而不能确保误差大小。所以它称为“局部变分方法”,因为要在每一个点(局部)处都要进行最大化(变分)。这样一来,我们可以理解为t实际上是u的函数,即
\begin{equation}f(u) = \max_{T\text{是值域为}f'(\mathbb{D})\text{的函数}}\big\{T(u) u - g(T(u))\big\}\label{eq:max-conj}\end{equation}
上述讨论过程实际上已经给出了计算凸共轭的方法,在这里我们直接给出上表对应的凸函数的共轭函数。
\begin{array}{c|c}\hline
f(u) & \textbf{对应的共轭}g(t) & f'(\mathbb{D}) & 激活函数\\
\hline
\frac{1}{2}|u - 1| & t & \left[-\frac{1}{2},\frac{1}{2}\right] & \frac{1}{2}\tanh(x)\\
\hline
u \log u & e^{t-1} & \mathbb{R} & x\\
\hline
- \log u & -1 - \log(-t) & \mathbb{R}_- & -e^{x}\\
\hline
\frac{(1 - u)^{2}}{u} & 2 - 2\sqrt{1-t} & (-\infty, 1) & 1-e^x\\
\hline
(u - 1)^{2} & \frac{1}{4}t^2+t & (-2,+\infty) & e^x-2\\
\hline
(\sqrt{u} - 1)^{2} & \frac{t}{1-t} & (-\infty, 1) & 1-e^x\\
\hline
(u - 1)\log u & W(e^{1-t})+\frac{1}{W(e^{1-t})}+t-2 & \mathbb{R} & x\\
\hline
-\frac{u + 1}{2}\log \frac{1 + u}{2} + \frac{u}{2} \log u & -\frac{1}{2}\log(2-e^{2t}) & \left(-\infty,\frac{\log 2}{2}\right) & \frac{\log 2}{2}-\frac{1}{2}\log(1+e^{-x})\\
\hline
\end{array}
(注:这里的W为朗伯W函数。)
f-GAN #
由上述推导,我们就可以给出f散度的估算公式,并且进一步给出f-GAN的一般框架。
f散度估计 #
计算f散度有什么困难呢?根据定义\eqref{eq:f-div},我们同时需要知道两个概率分布P,Q才可以计算两者的f散度,但事实上在机器学习中很难做到这一点,有时我们最多只知道其中一个概率分布的解析形式,另外一个分布只有采样出来的样本,甚至很多情况下我们两个分布都不知道,只有对应的样本(也就是说要比较两批样本之间的相似性),所以就不能直接根据\eqref{eq:f-div}来计算f散度了。
结合\eqref{eq:f-div}和\eqref{eq:max-conj},我们得到
\begin{equation}\begin{aligned}\mathcal{D}_f(P\Vert Q) =& \max_{T}\int q(x) \left[\frac{p(x)}{q(x)}T\left(\frac{p(x)}{q(x)}\right)-g\left(T\left(\frac{p(x)}{q(x)}\right)\right)\right]dx\\
=& \max_{T}\int\left[p(x)\cdot T\left(\frac{p(x)}{q(x)}\right)-q(x)\cdot g\left(T\left(\frac{p(x)}{q(x)}\right)\right)\right]dx\end{aligned}\end{equation}
将T\left(\frac{p(x)}{q(x)}\right)记为整体T(x),那么就有
\begin{equation}\mathcal{D}_f(P\Vert Q) = \max_{T}\Big(\mathbb{E}_{x\sim p(x)}[T(x)]-\mathbb{E}_{x\sim q(x)}[g(T(x))]\Big)\label{eq:f-div-e}\end{equation}
式\eqref{eq:f-div-e}就是估计f散度的基础公式了。意思就是说:分别从两个分布中采样,然后分别计算T(x)和g(T(x))的平均值,优化T,让它们的差尽可能地大,最终的结果就是f散度的近似值了。显然T(x)可以用足够复杂的神经网络拟合,我们只需要优化神经网络的参数。
注意在对凸函数的讨论中,我们在最大化目标的时候,对T的值域是有限制的。因此,在T的最后一层,我们必须设计适当的激活函数,使得T满足要求的值域。当然激活函数的选择不是唯一的,参考的激活函数已经列举在前表。注意,尽管理论上激活函数的选取是任意的,但是为了优化上的容易,应该遵循几个原则:
1、对应的定义域为\mathbb{R},对应的值域为要求值域(边界点可以忽略);
2、最好选择全局光滑的函数,不要简单地截断,例如要求值域为\mathbb{R}_+的话,不要直接用relu(x),可以考虑的是e^x或者\log(1+e^x);
3、注意式\eqref{eq:f-div-e}的第二项包含了g(T(x)),也就是g和T的复合计算,因此选择激活函数时,最好使得它与g的复合运算比较简单。
GAN批发 #
好了,说了那么久,几乎都已经到文章结尾了,似乎还没有正式说到GAN。事实上,GAN可以算是整篇文章的副产物而已。
GAN希望训练一个生成器,将高斯分布映射到我们所需要的数据集分布,那就需要比较两个分布之间的差异了,经过前面的过程,其实就很简单了,随便找一种f散度都可以了。然后用式\eqref{eq:f-div-e}对f散度进行估计,估计完之后,我们就有f散度的模型了,这时候生成器不是希望缩小分布的差异吗?最小化f散度就行了。所以写成一个表达式就是
\begin{equation}\min_G\max_{T}\Big(\mathbb{E}_{x\sim p(x)}[T(x)]-\mathbb{E}_{x=G(z),z\sim q(z)}[g(T(x))]\Big)\label{eq:f-div-gan}\end{equation}
或者反过来:
\begin{equation}\min_G\max_{T}\Big(\mathbb{E}_{x=G(z),z\sim q(z)}[T(x)]-\mathbb{E}_{x\sim p(x)}[g(T(x))]\Big)\label{eq:f-div-gan-2}\end{equation}
就这样完了~
需要举几个例子?好吧,先用JS散度看看。把所有东西式子一步步代进去,你会发现最终结果是(略去了\log 2的常数项)
\begin{equation}\min_G\max_{D}\Big(\mathbb{E}_{x\sim p(x)}[\log D(x)] + \mathbb{E}_{x=G(z),z\sim q(z)}[\log(1-D(x))]\Big)\end{equation}
其中D用\sigma(x)=1/(1+e^{-x})激活。这就是最原始版本的GAN了。
用Hellinger距离试试?结果是
\begin{equation}\min_G\max_{D}\Big(-\mathbb{E}_{x\sim p(x)}[e^{D(x)}] - \mathbb{E}_{x=G(z),z\sim q(z)}[e^{-D(x)}]\Big)\end{equation}
这里的D(x)是线性激活。这个貌似还没有命名?不过论文中已经对它做过实验了。
那用KL散度呢?因为KL散度是不对称的,所以有两个结果,分别为
\begin{equation}\min_G\max_{D}\Big(\mathbb{E}_{x\sim p(x)}[D(x)] - \mathbb{E}_{x=G(z),z\sim q(z)}[e^{D(x)-1}]\Big)\end{equation}
或
\begin{equation}\min_G\max_{D}\Big(\mathbb{E}_{x=G(z),z\sim q(z)}[D(x)] - \mathbb{E}_{x\sim p(x)}[e^{D(x)-1}]\Big)\end{equation}
这里的D(x)也是线性激活。
好吧,不再举例了。其实这些f散度本质上都差不多,看不到效果差别有多大。不过可以注意到,JS散度和Hellinger距离都是对称的、有界的,这是一个非常好的性质,以后我们会用到。
总结 #
说白了,本文主要目的还是介绍f散度及其局部变分估算而已~所以大部分还是理论文字,GAN只占一小部分。
当然,经过一番折腾,确实可以达到“GAN生产车间”的结果(取决于你有多少种f散度),这些新折腾出来的GAN可能并不像我们想象中的GAN,但它们确实在优化f散度。不过,以往标准GAN(对应JS散度)有的问题,其实f散度照样会有,因此f-GAN这个工作更大的价值在于“统一”,从生成模型的角度,并没有什么突破。
转载到请包括本文地址:https://kexue.fm/archives/6016
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Sep. 29, 2018). 《f-GAN简介:GAN模型的生产车间 》[Blog post]. Retrieved from https://kexue.fm/archives/6016
@online{kexuefm-6016,
title={f-GAN简介:GAN模型的生产车间},
author={苏剑林},
year={2018},
month={Sep},
url={\url{https://kexue.fm/archives/6016}},
}
November 26th, 2019
您好,我怎么无法推出JS散度对应的f是凸函数?
抱歉,请忽视我这条回复。
September 3rd, 2020
对散度的追求,让我想到了 压缩感知。
似乎都是在求解 基追踪?
不了解你说的。
November 16th, 2020
将 T(\frac{p(x)}{q(x)}) 记为整体 T(x) 这里,似乎是放宽了限制。因为k(x)=\frac{p(x)}{q(x)} 不是一个一一映射的函数。
是这么说,但可以反过来从(13)式出发退得原来的f散度,所以就可以证明互为充要条件了。
这个没有影响吧,既然 t 可以表示成关于 \frac{p(x)}{q(x)} 的函数,而 \frac{p(x)}{q(x)} 是关于 x 的函数,那么 t 自然可以写成关于 x 的函数 T(x)。
楼上的这个担忧是有道理的,比如T(x^2)跟T(x)就不等价,因为x^2不是x的单调函数,但是T(x^3)跟T(x)是等价的。
这里似乎没有问题?可能是记法上应该改成 T\left(\frac{p(x)}{q(x)}\right) = T'(x) 的形式,相当于把 \frac{p(x)}{q(x)} 也放到神经网络 T' 去拟合,此时应该也有 T'(\mathbb D_{T'})\subset T(\mathbb D_{T}),所以也不影响激活函数的分析
如果没有反向推导证明充分性的话,是有问题的。因为记T\left(\frac{p(x)}{q(x)}\right) = T'(x),T'(x)往往是带有额外的约束的,我们必须要反过来证明这个约束是可以去掉的,否则如果它应该加上约束,而我们在实现的时候没有加上约束,那么结果必然就不合理。
举个例子,对于WGAN的判别器我们有\Vert D\Vert_L\leq 1的约束,所以必须在训练之前就给D加上这个约束(或者相应的惩罚项),什么都不加直接训的话,那就没法训练出有意义的结果了。
反应过来了,就比如 T'(x)=T(x^2),其实暗含 T'(x)=T'(-x) 的约束,但如果不考虑直接对 T' 这个神经网络开训的话,就没有任何保证说 T' 能自然满足这样的约束,那训好的网络就很可能有问题。感谢苏老师~
是的,你这个例子更直观,我也学习了。
March 16th, 2021
请教苏神:minG maxD 和maxD minG的区别是?
\min和\max的顺序不一样。
就是说先最大化保证f的准确性,才能继续最小化。不然就不知道会是什么结果了?不是很懂,请教一下哈!
是,理论上要先完成\max,两者的顺序不能交换。至于为什么交替训练可以,那其实算是很奇妙的巧合(变成一个动力学问题)/
February 17th, 2022
苏老师您好,想请教一下,第二个表格中,每个共轭函数对应的激活函数是怎么来的?另外激活函数是不是就是T(x)?感谢老师!
1、激活函数取决于f'(\mathbb{D})的范围,即f'(\mathbb{D})=Activation(\mathbb{R})。
2、T(x)是判别器网络,用上述激活函数激活。。
August 29th, 2023
苏老师您好,请问我们在具体实现f-GAN时,例如最原始的GAN即使用JS散度对应代码里的实际的损失函数是交叉熵损失函数(理论上是先确定的交叉熵损失函数再推导出其等价于JS散度)。而现在我们如何根据f-散度族反向推导出代码里具体的损失函数呢?假如我现在要使用f散度族中的KL散度,那代码具体实现时的损失函数是什么呢?
整篇文章都在做你说的事情,式(14)和式(15)就是答案。
November 22nd, 2023
苏神,这里不知道能不能这么理解:
所以GAN的鉴别器并没有想着最大化假样本与真样本之间的f散度,而只是平淡的计算了当前生成的假样本与真样本之间的f散度,然后据此散度来优化生成器。之前,我一直认为鉴别器的作用是最大化假样本和真样本之间的距离。直接看原始GAN的损失函数给我这个感觉,但其实原始GAN最大化D只是在逼近JS散度,而不是最大化JS散度。
是的,就是这个意思。之所以造成“最大化假样本和真样本之间的距离”,是因为单独看了单个样本的loss,而没有考虑到对样本求期望的效果。