损失函数是学习的指挥棒—记一次实践经历
写在前面
损失函数是学习的指挥棒。
前段时间有个活,让我对定义损失函数有了新的认识,遂记录一下。
这里隐去具体的背景,只描述问题。
给定一个训练集(可视为全集的有效采样)\(X\),\(N\)个样本,每个样本\(x_i\)有\(D\)维特征,样本已做归一化处理,现希望将\(D\)维映射成1维,尽量保留样本原有远近关系。
PCA投影
一个直接的想法是,最大方差投影,即PCA第一主成分对应的投影向量,
- 投影(内积),将N维映射成1维
- 方差最大,保留尽可能多的信息
投影后,得到的分布如下,
分布特点:单峰、偏斜、陡峭、长尾……
因为一些后处理操作的要求,希望投影得到的分布尽可能对称且均匀,能否找到更好的投影方向?
基于偏度与峰度 构建损失函数
如果采用学习的方法,待学习的参数很好定义,1个D维的投影向量,关键是如何构建损失函数。
我们希望投影后的分布具有如下特点,
- 对称
- 均匀
- 方差尽可能大
显然这是个无监督问题,令投影向量为\(p\),\(x_i\)投影后为\(y_i = p\cdot x_i\),\(y_i\)为标量,我们希望\(y_1, y_2, \dots, y_N\)的分布具有如上特点。
在概率统计中,有两个指标,偏度(Skewness)和峰度(Kurtosis),
-
偏度(Skewness),用于衡量随机变量相对于平均值的对称程度,计算方式为随机变量的三阶标准中心矩,如下,
\[\operatorname{Skewness}[X]=\mathrm{E}\left[\left(\frac{X-\mu}{\sigma}\right)^{3}\right]=\frac{\mathrm{E}\left[(X-\mu)^{3}\right]}{\left(\mathrm{E}\left[(X-\mu)^{2}\right]\right)^{3 / 2}}=\frac{\mu_{3}}{\sigma^{3}} \]其值越接近0表示越对称,负值表示长尾在左,正值表示长尾在右,如下图所示,
-
峰度(Kurtosis),用于衡量随机变量分布的集中程度,计算方式为随机变量的四阶标准中心矩,如下,
\[\operatorname{Kurt}[X]=\mathrm{E}\left[\left(\frac{X-\mu}{\sigma}\right)^{4}\right]=\frac{\mathrm{E}\left[(X-\mu)^{4}\right]}{\left(\mathrm{E}\left[(X-\mu)^{2}\right]\right)^{2}}=\frac{\mu_{4}}{\sigma^{4}} \]其值越大表示越集中,标准正态分布的峰度为3,均匀分布的峰度为1.8。所以可以用\(\operatorname{Kurt}[X]-3\)来衡量分布表与标准正态分布相比是更陡峭还是平坦,如下图所示,
偏度(Skewness)和峰度(Kurtosis)都无量纲,在这个问题中,恰好可以用它们来构建损失函数,同时考虑方差,将损失定义如下,令\(||p|| = 1\),移除投影向量模对方差的影响,
自动微分交给pytorch,
class My_loss(nn.Module):
def __init__(self):
super().__init__()
def forward(self, x, y=None):
mu = x.mean()
var = x.var(unbiased=False)
loss = lambda1 * (x - x.mean()).pow(3).mean().pow(2) / (x.var(unbiased=False).pow(3)) + lambda2 / x.std(unbiased=False) \
+ lambda3 * (x - x.mean()).pow(4).mean() / (x.var(unbiased=False).pow(2))
return loss
训练得到投影方向,投影后的分布如下,与之前相比,更符合期望。
将训练得到的投影方向,融入整个处理流程,配合相应的后处理操作,获得了不错的性能提升。
小结
回到开篇的那句话,损失函数是学习的指挥棒,在构建损失函数时,要
- 定义清楚你的期望,期望模型达成什么目标、具有什么性质
- 找到合适的数学表达,来描述你的期望
- 如果是多目标损失,协调好不同目标间的权重和组合关系
当然,还要调参(微笑)