我是靠谱客的博主 快乐树叶,最近开发中收集的这篇文章主要介绍系列之3-损失函数损失函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

全套教程请点击:微软 AI 开发教程

在这一章,我们将简要介绍一下损失函数~

损失函数

作用

在有监督的学习中,需要衡量神经网络输出和所预期的输出之间的差异大小。这种误差函数需要能够反映出当前网络输出和实际结果之间一种量化之后的不一致程度,也就是说函数值越大,反映出模型预测的结果越不准确。

还是拿练枪的Bob做例子,Bob预期的目标是全部命中靶子的中心,但他现在的命中情况是这个样子的:

700062-20181115132247289-1992782981.png

最外圈是1分,之后越向靶子中心分数是2,3,4分,正中靶心可以得5分。

那Bob每次射击结果和目标之间的差距是多少呢?在这个例子里面,用得分来衡量的话,就是说Bob得到的反馈结果从差4分,到差3分,到差2分,到差1分,到差0分,这就是用一种量化的结果来表示Bob的射击结果和目标之间差距的方式。也就是误差函数的作用。因为是一次只有一个样本,所以这里采用的是误差函数的称呼。如果一次有多个样本,那么就要称呼这样子衡量不一致程度的函数就要叫做损失函数了。

700062-20181115132302340-393603096.png

以做线性回归的实际值和预测值为例,若自变量x是[-2, -1, 0, 1, 2]这样5个值,对应的期望值y是[-3, 0, 0, 3, 4]这样的值,目前预测使用的参数是(w, b) = (2, 1), 那么预测得到的值y_ = [-3, -1, 1, 3, 5], 采用均方误差计算这个预测和实际的损失就是(sum_{i = 0}^{4}(y[i] - y__[i])^{2}), 也就是3。那么如果采用的参量是(0, 0),预测出来的值是[0, 0, 0, 0, 0],这是一个显然错误的预测结果,此时的损失大小就是34,(3 < 34), 那么(2, 1)是一组比(0, 0)要合适的参量。

那么常用的损失函数有哪些呢?
这里先给一些前提,比如神经网络中的一个神经元:

700062-20181115132331574-499049181.png

图中 (z = sumlimits_{i}w_i*x_i+b_i=theta^Tx)(sigma(z))是对应的激活函数,也就是说,在反向传播时梯度的链式法则中,

[frac{partial{z}}{partial{w_i}}=x_i tag{1}]
[frac{partial{z}}{partial{b_i}}=1 tag{2}]
[frac{partial{loss}}{partial{w_i}}=frac{partial{loss}}{partial{sigma(z)}}frac{partial{sigma(z)}}{partial{z}}frac{partial{z}}{partial{w_i}}=frac{partial{loss}}{partial{sigma(z)}}frac{partial{sigma(z)}}{partial{z}}x_i tag{3}]
[frac{partial{loss}}{partial{b_i}}=frac{partial{loss}}{partial{sigma(z)}}frac{partial{sigma(z)}}{partial{z}}frac{partial{z}}{partial{b_i}}=frac{partial{loss}}{partial{sigma(z)}}frac{partial{sigma(z)}}{partial{z}} tag{4}]

从公式((3),(4))可以看出,梯度计算中的公共项是(frac{partial{loss}}{partial{sigma(z)}}frac{partial{sigma(z)}}{partial{z}} = frac{partial{loss}}{partial{z}})

下面我们来探讨(frac{partial{loss}}{partial{z}})的影响。由于梯度的计算和函数的形式是有关系的,所以我们会从常用损失函数入手来逐个说明。

常用损失函数

  1. MSE (均方误差函数)
    该函数就是最直观的一个损失函数了,计算预测值和真实值之间的欧式距离。预测值和真实值越接近,两者的均方差就越小。
  • 想法来源
    在给定一些点去拟合直线的时候(比如上面的例子),常采用最小二乘法,使各个训练点到拟合直线的距离尽量小。这样的距离最小在损失函数中的表现就是预测值和真实值的均方差的和。
  • 函数形式:

    [loss = frac{1}{2}sum_{i}(y[i] - a[i]) ^ 2],
    其中, (a)是网络预测所得到的结果,(y)代表期望得到的结果,也就是数据的标签,(i)是样本的序号。
  • 反向传播:

    [frac{partial{loss}}{partial{z}} = sum_{i}(y[i] - a[i])*frac{partial{a[i]}}{partial{z}}]
  • 缺点:
    (frac{partial{a[i]}}{partial{z}})关系密切,可能会产生收敛速度缓慢的现象,以下图为例(激活函数为sigmoid)

    700062-20181115132357239-2020710586.png

    在激活函数的两端,梯度(黄色)都会趋向于0,采取MSE的方法衡量损失,在(a)趋向于1而(y)是0的情况下,损失loss是1,而梯度会趋近于0,在误差很大时收敛速度也会非常慢。

    在这里我们可以参考activation中关于sigmoid函数求导的例子,假定x保持不变,只有一个输入的一个神经元,权重(w = ln(9)), 偏置(b = 0),也就是这样一个神经元:

    700062-20181115132411258-516844744.png

    保持参数统一不变,也就是学习率(eta = 0.2),目标输出(y = 0.5), 此处输入x固定不变为(x = 1),采用MSE作为损失函数计算,一样先做公式推导,

    第一步,计算当前误差

    [loss = frac{1}{2}(a - y)^2 = frac{1}{2}(0.9 - 0.5)^2 = 0.08]

    第二步,求出当前梯度

    [grad = (a - y) times frac{partial{a}}{partial{z}} frac{partial{z}}{partial{w}} = (a - y) times a times (1 - a) times x = (0.9 - 0.5) times 0.9 times (1-0.9) times 1= 0.036]

    第三步,根据梯度更新当前输入值

    [w = w - eta times grad = ln(9) - 0.2 times 0.036 = 2.161]

    第四步,计算当前误差是否小于阈值(此处设为0.001)

    [a = frac{1}{1 + e^{-wx}} = 0.8967]
    [loss = frac{1}{2}(a - y)^2 = 0.07868]

    第五步,重复步骤2-4直到误差小于阈值

    作出函数图像如图所示:

    700062-20181115132424805-1260423712.png

    可以看到函数迭代了287次从才收敛到接近0.5的程度,这比单独使用sigmoid函数还要慢了很多。

  1. 交叉熵函数

这个损失函数的目的是使得预测得到的概率分布和真实的概率分布尽量的接近。两个分布越接近,那么这个损失函数得到的函数值就越小。怎么去衡量两个分布的接近程度呢?这就要用到香农信息论中的内容了。两个概率分布之间的距离,也叫做KL Divergence,他的定义是这个形式的,给定离散概率分布P(x), Q(x),这两个分布之间的距离是

[ D_{KL}(P || Q) = - sum_{i}P(i)log(frac{Q(i)}{P(i)})]

试想如果两个分布完全相同,那么(log(frac{Q(i)}{P(i)}) = 0), 也就是两个分布之间的距离是零,如果两个分布差异很大,比如一个是(P(0)=0.9, P(1)=0.1),另一个是(Q(0)=0.1,Q(1)=0.9),那么这两个分布之间的距离就是0.763,如果是(Q(0)=0.5,Q(1)=0.5),那么距离就是0.160,直觉上来说两个分布越接近那么他们之间的距离就是越小的,具体的理论证明参看《信息论基础》,不过为什么要选用这个作为损失函数呢?

  • 从最大似然角度开始说
    关于最大似然,请参看:

    https://www.zhihu.com/question/20447622/answer/161722019

    将神经网络的参数作为(theta),数据的真实分布是(P_{data}(y;x)), 输入数据为(x),那么在(theta)固定情况下,神经网络输出(y)的概率就是(P(y;x, theta)),构建似然函数,
    [L = sum_{i}log(P(y_i;x_i, theta))]
    (theta)为参数最大化该似然函数,即(theta^{*} = {argmax}_{theta}L)
    真实分布(P(x_i))对于每一个((i, x_i, y_i))来说均是定值,在确定(x_i)情况下,输出是(y_i)的概率是确定的。在一般的情况下,对于每一个确定的输入,输出某个类别的概率是0或者1,所以可以将真实概率添加到上述式子中而不改变式子本身的意义:

    [theta^{*} = {argmax}_{theta}sum_{i}P_{data}(y_i;x_i)log(P(y_i;x_i, theta))]

    (D_{KL})展开,得到,

    [D_{KL}(P || Q) = - sum_{i}P(i)log(frac{Q(i)}{P(i)}) = sum_{i}P(i)log(P(i)) - sum_{i}P(i)log(Q(i)) ]

    (P(i))代表(P_{data}(y_i;x_i))(Q(i))代表(P(y_i;x_i,theta))

    上述右侧式中第一项是和仅真实分布(P(i))有关的,在最小化(D_{KL})过程中是一个定值,所以最小化(D_{KL})等价于最小化(-sum_{i}P(i)log(Q(i))),也就是在最大化似然函数。
    • 函数形式(以二分类任务为例)

      [loss = sum_{i}y(x_i)log(a(x_i)) + (1 - y(x_i))log(1 - a(x_i))]
      其中,(y(x_i))是真实分布,(a(x_i))是神经网络输出的概率分布
    • 反向传播

      [frac{partial{loss}}{partial{z}} = (-frac{y(z)}{a(z)} + frac{1 - y(z)}{1 - a(z)})*frac{partial{a(z)}}{partial{z}} = frac{a(z) - y(z)}{a(z)(1-y(z))}*frac{partial{a(z)}}{partial{z}}]

      在使用sigmoid作为激活函数情况下,(frac{partial{a(z)}}{partial{z}} = a(z)(1-a(z))),也就是说,sigmoid本身的梯度和分母相互抵消,得到,

      [frac{partial{loss}}{partial{z}} = frac{a(z) - y(z)}{y(z)(1-a(z))}*frac{partial{a(z)}}{partial{z}} = a(z) - y(z)]

      在上述反向传播公式中不再涉及到sigmoid本身的梯度,故不会受到在误差很大时候函数饱和导致的梯度消失的影响。

      总的说来,在使用sigmoid作为激活函数时,使用交叉熵计算损失往往比使用均方误差的结果要好上一些。但是,这个也并不是绝对的,需要具体问题具体分析,针对具体应用,有时需要自行设计损失函数来达成目标。

      参考资料:

      https://www.cnblogs.com/alexanderkun/p/8098781.html

      https://www.zhihu.com/question/20447622/answer/161722019

      《信息论基础》

全套教程请点击:微软 AI 开发教程

最后

以上就是快乐树叶为你收集整理的系列之3-损失函数损失函数的全部内容,希望文章能够帮你解决系列之3-损失函数损失函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部