读这篇文章之间欢迎各位先阅读我之前写过的[线性降维的文章]([机器学习]李宏毅——线性降维 - 掘金 (juejin.cn))。这篇文章应该也是属于Unsupervised Learning的内容的。
在实际的数据中,很可能会存在这一种分布:
左边这个分布可以看成原先在二维平面上的分布硬塞到一个三维空间之中。
那么如果我们直接对三维空间的这个分布计算欧氏距离的话,很可能是行不通的!如果是在比较接近的点(例如图中我用黄色箭头标记出来的点)那么计算欧式距离进行比较还是可以表明它们之间的接近程度的。但是如果在我标注出来的红色的点,因此它们在三维空间中将原来的二维平面进行了扭曲,因此很可能比较欧氏距离并不能够象征它们之间的相似度。这个想法可以用地球在类似,如果在地球上很接近的两个点那么计算直线距离当然是可以的;但是如果在很遥远的两个点,由于三维空间内的扭曲性,那么计算直线距离就不行了。
那么我们如果能够将该三维空间下的曲面展开成二维空间中分布(如右图),那么我们可以发现它们的分布就很容易进行划分,计算欧氏距离也就能够象征相似程度了,这也能够为我们的下游任务提供更多的便利。
下面就来介绍几种能够完成非线性降维的方法
当前我们拥有以下样本,那么对于其中的某一个样本 x i x^i xi来说,其各个邻居为 x j x^j xj,那么它和各个邻居之间的“关系”为 w i j w_{ij} wij,如下图所示:
那么这个关系的确定是认为 x i x^i xi可以由各个邻居 x j x^j xj经过线性变换组合而成,即:
w ∗ = a r g m i n w ∑ i ∥ x i − ∑ j w i j x j ∥ 2 w^*=argmin_{w} \sum_i \lVert x^i-\sum_jw_{ij}x^j \rVert_2 w∗=argminwi∑∥xi−j∑wijxj∥2
而假设经过降维之后 x i x^i xi对应为 z i z^i zi,其需要满足的条件为降维后各个z之间的关系要保持不变,即:
Z ∗ = a r g m i n Z ∑ i ∥ z i − ∑ j w i j z j ∥ 2 Z^*=argmin_Z \sum_i \lVert z^i-\sum_jw_{ij}z^j \rVert_2 Z∗=argminZi∑∥zi−j∑wijzj∥2
那么采用这一种类似方法的好处在于即使你不知道原来样本x应该怎么表示,只要你能够知道如何计算它们之间的关系,你就仍然可以完成降维。
而这个方法需要注意的是要调节选择的邻居数目,适合的数目才能够带来够好的效果:
前面提及的各个算法虽然都限制了在原来维度中相接近的点,降维之后也要相接近,但是都没有限制在原来维度中不接近的点,降维之后也要分割开来,因此例如LLE会出现以下情形,即不同类别的点也都挤在了一起:
那么t-SNE的处理方法就较为不同,具体如下:
t-SNE在选择相似度的度量函数的时候有一个很奇妙的地方,其选择为:
S ( x i , x j ) = e x p ( − ∥ x i − x j ∥ 2 ) S ′ ( z i , z j ) = 1 1 + ∥ z i − z j ∥ 2 S(x^i,x^j)=exp(-\lVert x^i-x^j \rVert_2)\\S'(z^i,z^j)=\frac{1}{1+\lVert z^i-z^j \rVert_2} S(xi,xj)=exp(−∥xi−xj∥2)S′(zi,zj)=1+∥zi−zj∥21
因为按照我们正常的逻辑应该是在x中选择什么样的度量指标,在z上就选择一样的度量指标,但t-SNE这样选择的理由,我们需要通过这两个函数的曲线来说明:
因此t-SNE的分类结果大致如下:
费曼曾经说过:What I cannot create, I do not understand.
那么这句话用在当前的机器学习之中也同样适用:因为当前的机器学习虽然可以做到完成分辨的任务,例如分辨出猫和狗,但如果有一天机器可以自己“创造”出一张猫的图像,那么也许机器才能够对猫这个名词的概念有更深的了解。而“创造”就是生成模型的任务。因此本节主要是对当前生成模型的研究进行介绍。
如果对RNN没有了解且有兴趣地可以看我[这篇文章]([机器学习]李宏毅——Recurrent Neural Network(循环神经网络) - 掘金 (juejin.cn)),如果不阅读的话也是可以看得懂接下来PiexlRNN的具体流程的。
假设我们要创造一张 3 × 3 3\times 3 3×3的图像,那么我们可以训练一个神经网络,它可以不断接受已经创造出来的像素点对应的向量,然后输出下一个像素点应该对应的向量,如下图所示:
你可能会好奇为什么每一次输入的个数都不一样,其实这是RNN的特性决定的,它可以处理输入不同个数向量的情况。
那么李宏毅老师也将这个想法用来创造一些神奇宝贝,但是在训练的时候发现了以下需要注意的地方,我觉得这些点能够让我们在以后的某些工作中受到启发:
VAE是在Auto-encoder进行了改进。首先先介绍在结构和训练过程上的改进:
因此训练完成之后就可以将VAE的De取出来做生成任务。
为什么Auto-encoder不够,而需要改进的VAE呢?我们通过下面这个例子来进行解释。
假设Auto-encoder做的事情是下面的,将月亮的图片变成Code,再还原成月亮的图片,那么如果在满月和半月对应的Code之间选择一个点,进行还原的话,是否还原出来的图片也会像是满月和半月之间的月亮呢?不会!因为Auto-encoder只学习了对应的满月和半月两个点的转换,中间的转换并没有学习,因此转换出来很难想象是什么东西。
但对于VAE来说,它不仅仅是对满月和半月这两个点来进行学习,它还加入了一定的噪声,同时学习过程之中还要求加入噪声之后也要还原出原来的图片,因此在满月的Code对应的点的附近就都能够还原出满月。而如果满月的噪声的范围和半月的噪声的范围有交集,在这个交集之中因为VAE既学习了要像满月,也学习了要像半月,因此真的有可能就会在该点Code上还原出一张介于满月和半月之间的图片。
那再让我们回头来看VAE是如何改进Auto-encoder就可以理解中间各个向量的含义了:
其中向量 M M M就可以认为是原始的Code,而向量 E E E可以认为是噪声,那么 e x p ( σ ) exp(\sigma) exp(σ)向量就可以认为是控制原始向量和噪声之间的一个超参数的度量,那么就得到了向量C。
而对于VAE来说训练时仅仅要求输入和输出类似是不够的,因为这样会导致向量 e x p ( σ ) exp(\sigma) exp(σ)取接近于0,从而来导致噪声几乎没有,那这样就可以做到输入输出很接近,因此还需要加上的限制就是下面的式子:
其中前两项可以简单理解为限制它不会让噪声直接失去掉,第三项则是类似于正则化的思想。
我们也可以从另外一个角度来进行分析,假设我们把Code的取值看成具有一定的分布:
其中在一些能够还原出比较像宝可梦图片的Code的取值上就具有较多的概率,而如果还原出来的图像不正常那么就具有较小的概率,那如果我们能够估计出来这个分布就可以通过采样来产生宝可梦了。因此对于分布的概率需要介绍下面的混合高斯分布。
对于一般的混合高斯分布来说,其中具有的高斯分布的数量是固定的,即:
可以看到其表达式是采用求和的形式。那么从这种高斯分布中进行采样的步骤就是先产生一个正整数代表从哪一个高斯分布进行采样,之后再在对应的高斯分布中采样即可。
但有另外一种混合高斯分布其含有的高斯分布的数量可以认为是无限的,且每一个高斯分布都有其对应的均值和方差。那么我们如何来表示这种混合高斯分布,或者说我们如何从这种高斯分布中进行取样呢?
具体做法为:首先先从一个标准正态分布中取样得到一个向量z,再将这个向量z通过计算均值的函数和通过计算方差的函数,算出应该对应的高斯分布的均值和方差,然后再在这个高斯分布中进行采样得到x。那么就有需要注意的点:
那么一般情况并不是我们拥有这样的混合高斯函数让我们从中进行采样,而是我们已经有了样本数据集,我们假设它符合混合高斯的分布,然后我们需要推导出这个混合高斯分布的式子(实际上也就是推导出那个对z产生对应均值和方差的神经网络)。那么计算的方法为:
μ ( z ) ∗ , σ ( z ) ∗ = a r g m a x ( μ ( z ) , σ ( x ) ) ∑ x l o g P ( x ) \mu(z)^*,\sigma(z)^*=argmax_{(\mu(z),\sigma(x))}\sum_xlogP(x) μ(z)∗,σ(z)∗=argmax(μ(z),σ(x))x∑logP(x)
其实也就是微调那个神经网络的参数,通过梯度下降来实现:
那么现在就来进行推导:
注意这里的 q ( z ∣ x ) q(z\mid x) q(z∣x)可以是任何分布是因为后面的积分会将其积分成1,而最下面的这一项我们可以认为是 l o g P ( x ) logP(x) logP(x)的下界,因此我们现在的目标就更换为:
因此我们要最大化上面这两项
就可以认为是从 q ( z ∣ x ) q(z\mid x) q(z∣x)中取样得到一个z,然后我们要让 l o g P ( x ∣ z ) logP(x\mid z) logP(x∣z)最大,那么这也就是Auto-encoder所做的事情:
结合我们前面说到的两个分布都可以用神经网络来描述就可以理解了。那么这两者的结合,就是VAE的loss函数了
VAE有一个很严重的问题就是它永远只是在学习怎么产生一张图片能够和原始数据的图像越来越接近,它始终没有学习如何产生能够以假乱真的图片,或者说它只懂得了尽可能地模仿训练集的图像,例如下面的例子:
假设我们对输入和输出的相似度的计算是使用展开成向量然后计算平方差,那么上图的例子中两个不同的问题虽然都是存在一个像素点的不同,这在我们计算平方差的时候是一样的,但时在实际的图像上是很不一样的。因此如果能够像GAN一样学习如何欺骗过辨别器,那就可以产生很好的效果。
对于GAN的介绍可以看我[这篇文章]([机器学习]李宏毅——生成式对抗网络GAN - 掘金 (juejin.cn))。