zoukankan      html  css  js  c++  java
  • 损失函数是学习的指挥棒—记一次实践经历

    [TOC]

    博客:博客园 | CSDN | blog

    写在前面

    损失函数是学习的指挥棒。

    前段时间有个活,让我对定义损失函数有了新的认识,遂记录一下。

    这里隐去具体的背景,只描述问题。

    给定一个训练集(可视为全集的有效采样)(X),$N$个样本,每个样本$x_i$有$D$维特征,样本已做归一化处理,现希望将$D$维映射成1维,尽量保留样本原有远近关系。

    PCA投影

    一个直接的想法是,最大方差投影,即PCA第一主成分对应的投影向量,

    • 投影(内积),将N维映射成1维
    • 方差最大,保留尽可能多的信息

    投影后,得到的分布如下,

    方差最大方向上的投影分布.png

    分布特点:单峰、偏斜、陡峭、长尾……

    因为一些后处理操作的要求,希望投影得到的分布尽可能对称且均匀,能否找到更好的投影方向?

    基于偏度与峰度 构建损失函数

    如果采用学习的方法,待学习的参数很好定义,1个D维的投影向量,关键是如何构建损失函数。

    我们希望投影后的分布具有如下特点,

    • 对称
    • 均匀
    • 方差尽可能大

    显然这是个无监督问题,令投影向量为$p$,$x_i$投影后为$y_i = pcdot 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} ight)^{3} ight]=frac{mathrm{E}left[(X-mu)^{3} ight]}{left(mathrm{E}left[(X-mu)^{2} ight] ight)^{3 / 2}}=frac{mu_{3}}{sigma^{3}} ]

      其值越接近0表示越对称,负值表示长尾在左,正值表示长尾在右,如下图所示,

      Skewness.png

    • 峰度(Kurtosis),用于衡量随机变量分布的集中程度,计算方式为随机变量的四阶标准中心矩,如下,

      [ operatorname{Kurt}[X]=mathrm{E}left[left(frac{X-mu}{sigma} ight)^{4} ight]=frac{mathrm{E}left[(X-mu)^{4} ight]}{left(mathrm{E}left[(X-mu)^{2} ight] ight)^{2}}=frac{mu_{4}}{sigma^{4}} ]

      其值越大表示越集中,标准正态分布的峰度为3,均匀分布的峰度为1.8。所以可以用$operatorname-3$来衡量分布表与标准正态分布相比是更陡峭还是平坦,如下图所示,

      Kurtosis.png

    **偏度(Skewness)峰度(Kurtosis)**都无量纲,在这个问题中,恰好可以用它们来构建损失函数,同时考虑方差,将损失定义如下,令$||p|| = 1$,移除投影向量模对方差的影响,

    [ L = frac{1}{Std[pX]} + lambda_1(operatorname{Skewness}[pX])^2 + lambda_2operatorname{Kurt}[pX] ]

    自动微分交给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
    

    训练得到投影方向,投影后的分布如下,与之前相比,更符合期望。

    学习得到的投影分布.png

    将训练得到的投影方向,融入整个处理流程,配合相应的后处理操作,获得了不错的性能提升。

    小结

    回到开篇的那句话,损失函数是学习的指挥棒,在构建损失函数时,要

    • 定义清楚你的期望,期望模型达成什么目标、具有什么性质
    • 找到合适的数学表达,来描述你的期望
    • 如果是多目标损失,协调好不同目标间的权重和组合关系

    当然,还要调参(微笑)

    参考

  • 相关阅读:
    Github 简明教程--GitHub这么火,测试员你不学学吗?
    IT行业,尤其是软件测试,怎么才能月薪突破2万?
    linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记
    ffmpeg(2.6) rockplayer android 下编译 小记.
    完成端口
    C++四种强制转换
    方法区(Method Area)基础知识
    逃逸分析
    堆空间参数设置小结
    堆中的线程私有缓存区域TLAB(Thread Local Allocation Buffer)
  • 原文地址:https://www.cnblogs.com/shine-lee/p/13268382.html
Copyright © 2011-2022 走看看