为了循序渐进, 先来学习SNE.
SNE
无论是多维数据还是词向量, 都是一个个散落在空间中的点, 点与点之间距离近的, 就可以看作属于同一分类或近义词. 衡量两点距离有很多种手段, 但最常用的还是欧式距离, 所以欧氏距离与相似度的关系可以用某种公式近似表达, 这样就可以把空间信息浓缩在一张N×N的表格上了, 其中N代表空间中分布的样本个数.
如果我们能找到一个低维空间, 它的N×N相似度表格与高维的表格一样, 就可以认为这个低维空间就是高维空间的投影, 也就完成了降维任务.
所以SNE分为两步:
- 根据高维空间, 计算相似度表格.
- 根据相似度表格, 寻找低维空间.
1.计算相似度表格
首先来探讨一下这个距离到相似度的映射函数是什么样子.
- 斜率恒为负, 保证距离和相似度反比的关系.
- 相似度不能为负, 也不能太大.
- 距离不能为负, 从0开始且有无限远.
我们熟知的高斯分布图就很合适. 更详细讲, 是 N ( 0 , I ) N~(0,I) N (0,I)的分布函数很合适. 它的右侧图像斜率恒为负(1), y轴作为相似度恒为正值(2), 均值为0保证x轴距离从0开始且无限远(3). I I I稍后讲解.
接下来我们将分别以每个点为中心点, 计算中心点与其他点的相似度.
首先要解决
I
I
I的取值问题. 实验证明, 当对任何点,
I
I
I都取一个固定值时, 在某些任务中会很不友好.例如
这是市场上货物A和B的样本抽样.可以看出, 空间分布上A和B的形状差不多, 不同的是B的间隔比较大, 而由于采用了高斯分布函数, 在分别以A和B最左侧点为中心点计算其他同类点相似度时, 就会出现畸形, 即使它们的空间排布相同.
红:
P
1
=
0.4
0.4
+
0.16
=
0.714
P1 = \frac {0.4}{0.4+0.16} = 0.714
P1=0.4+0.160.4=0.714
P
2
=
0.16
0.4
+
0.16
=
0.286
P2 = \frac {0.16}{0.4+0.16} = 0.286
P2=0.4+0.160.16=0.286
绿:
P
1
=
0.08
0.08
+
0.04
=
0.667
P1 = \frac {0.08}{0.08+0.04} = 0.667
P1=0.08+0.040.08=0.667
P
2
=
0.04
0.08
+
0.04
=
0.333
P2 = \frac {0.04}{0.08+0.04} = 0.333
P2=0.08+0.040.04=0.333
而理想情况下, 它们应该相同.
解决这个问题的办法就是, 用中心点的方差来设定
I
I
I的值. 对于那些像绿点一样疏松的中心点, 适当增大方差有益于这类问题的改善.
所以如何寻找方差 I I I?
这需要引入困惑度的概念. 困惑度与方差的关系如下:
- 方差决定了高斯分布函数的高矮胖瘦.
- 根据固定的数据点和这个高斯函数可得相似度.
- 相似度是概率, 就必然有交叉熵, 反映了样本点的紧密程度.
- 交叉熵H和困惑度Prep的关系如下:
P
r
e
p
(
x
i
)
=
2
H
(
x
i
)
Prep(x_i)=2^{H(x_i)}
Prep(xi)=2H(xi)
i i i指选中的那个中心点编号, x i x_i xi是中心点, H ( x i ) H(x_i) H(xi)是 x i x_i xi的交叉熵.
困惑度是个很简单的映射函数, 但实验发现用它来做评判指标有很强的鲁棒性.
我们用困惑度来控制方差的选择. 首先令目标困惑度
P
r
e
p
=
30
Prep = 30
Prep=30(困惑度有鲁棒性, 实验经验, 取5-50内任意值对训练结果影响不大), 然后初始化所有的中心点的
I
I
I 都是
1
1
1. 有了初始化的
I
I
I, 就能根据上图的关系求中心点
x
i
x_i
xi的相似度. 依然以红绿两点为例, 假设经计算, 第一个红点的困惑度
P
r
e
p
(
红
1
)
=
30
Prep(红1)=30
Prep(红1)=30, 就不做处理, 而第一个绿点的困惑度
P
r
e
p
(
绿
1
)
=
40
Prep(绿1)=40
Prep(绿1)=40, 就需要增大方差, 以减小交叉熵, 最后减小
P
r
e
p
(
绿
1
)
Prep(绿1)
Prep(绿1).反之如果困惑度小, 就增大方差.
实际操作中, 你是无法从困惑度反推方差的, 所以只能挨个方差地猜, 直到达到拟设立的
P
r
e
p
Prep
Prep. 幸好他们是线性关系, 只要用二分法选择方差
I
I
I, 就可以很快逼近那个达标的
I
I
I.
2. 寻找低维空间
在你想要的维度上随机N个点, 这N个点要与你手中的高维数据样本一一对应. 自然, 这个随机出来的低维空间也有它的相似度矩阵, 不过因为点的位置是随机的, 所以不能求每个点的
I
I
I, 只能固定使用同一个
I
I
I值. SNE中常令
I
=
1
2
I=\frac{1}{\sqrt{2}}
I=21 . 我们的目标是让这两个相似度矩阵相等.
只要有从x到y的公式, 加上损失函数, 就可以反向传播. KL散度是用于计算两概率分布的相似度的函数, 正好可以当作损失函数.
t-SNE
实验证明, 使用正态分布生成低维空间会产生crowding问题, 压缩的越低, crowding问题就越明显.
crowding问题
如果给你一个半径为r的圆, 在其中以一定距离均匀地画点, 你会发现内圈圆与外圈圆的点的比例差不多是面积的比, 即1:3.
如果是一个半径为r的球, 同样均匀画点, 它的内外圈点数比值就是三维球的体积比, 7:1.
随着这个球维度的不断升高, 内外比值会越来越大.
按照我们用距离推算相似度的规则, 因为高维球体外圈的点数特别多, 在计算高维相似度矩阵的时候就会稀释离中心点近的点的相似度, 导致在用低维空间拟合时产生较远的距离.可我们希望它能更近!
解决crowding问题
我们使用固定自由度
n
=
1
n=1
n=1的
t
t
t分布拟合低维空间.
t分布相比于正态分布, 有着更扁平的形状. 对于较高的相似度, t分布的距离比正态分布更近. 对于较低的相似度, t分布的距离比正态分布更远. 这也更合乎常理.
简化计算
t-SNE还使用了对称矩阵. 高维空间的相似度矩阵中
P
(
i
∣
j
)
和
P
(
j
∣
i
)
P(i|j)和P(j|i)
P(i∣j)和P(j∣i)是不相等的, 在梯度下降中还需要考虑到两方面的P都被优化, 就让梯度公式变得麻烦了起来.(具体公式不列)
所以就有了对称SNE的想法, 把
P
(
i
∣
j
)
和
P
(
j
∣
i
)
P(i|j)和P(j|i)
P(i∣j)和P(j∣i)相加除以2就是联合分布
P
(
i
,
j
)
P(i,j)
P(i,j).
会有人问为什么不直接用下半部分或者上半部分的相似度矩阵对称过去?
如果直接对称会出问题. 如果点
i
i
i是离群点, 恰巧数据集还特别大, 就导致分到每个点上的相似度都很小.
如果使用加权取半的方式, 会稍微拔高每个点的相似度, 虽然严格来说它并不是求真正的联合概率分布的方式, 但作为近似值还是可以的, 毕竟能简化梯度公式, 还能减少空间使用, 更是能减轻离群点难以训练的困境.
实验中,这个近似方法能产生同样不错的效果.
优化trick
- 求解过程中容易落入局部最优解, 因为每次训练结果都不一样, 所以可以重复训练取其中最优, 加入模拟退火也是一样的.
- 如果你查看代码, 会发现前100次迭代中, 在计算 P P P Q Q Q差值时, 相似度矩阵 P P P的值会被整体扩大4倍左右, 扩大之后差值会变大, 梯度也会比较大, 有利于改善前期的龟速优化.
- 如果数据分布稀疏, 最好提前压缩一下, 或者引入L2逼迫模型减小各个点的距离.