Tensorflow中的损失函数

3. Tensorflow中的损失函数

3.1 简介

损失函数(loss function、cost function)是神经网络搭建之后需要首先考虑的。因为在训练网络,即反向传播过程中,需要有一个监督信号去更新参数。最常用的损失函数有交叉熵(cross_entropy)和均方误差(MSE,mean squared error)。

3.2 loss函数

  • 均方误差(MSE,mean squared error)

在逻辑回归问题中,我们更多的用到MSE。因为在回归问题中的返回值,通常是单个值,并非向量。具体公式如下:

MSE = \frac{1}{N}\sum_{i=1}^N(y_i-\hat{y_i})^2

其中 y_i 是目标值,\hat{y_i}是预测值。

由此衍生了一些其他loss公式。

如均方根误差(RMSE)

RMSE = \sqrt{\frac{1}{N}\sum_{i=1}^N(y_i-\hat{y_i})^2}

平均误差(MAE :Mean Absolute Error)

MAE = \frac{1}{N}\sum_{i=1}^N|\hat{y_i} - y_i|

标准差(SD :standard Deviation)

SD = \frac{1}{N}\sum_{i=1}^N|y_i-\bar{y}|

\bar{y} = \frac{1}{N}\sum_{i=1}^Ny_i

  • 交叉熵(cross_entropy)

交叉熵在很多时候用于分类问题。

交叉熵是信息论中的概念,首先从信息熵开始说起

熵表示单个事件所有信息量的期望,公式如下

H(X)= -\sum_{i=1}^{n}p(x_i)\log(p(x_i))

然后引入到相对熵(KL散度),如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异。

在深度学习中,P往往用来表示样本的真实分布,比如[1,0,0]表示当前样本属于第一类。Q用来表示模型所预测的分布,比如[0.7,0.2,0.1]。

直观的理解就是如果用P来描述样本,那么就非常完美。而用Q来描述样本,虽然可以大致描述,但是不是那么的完美,信息量不足,需要额外的一些“信息增量”才能达到和P一样完美的描述。如果我们的Q通过反复训练,也能完美的描述样本,那么就不再需要额外的“信息增量”,Q等价于P。

公式如下:

D_{KL}(p\|q)= \sum_{i=1}^{n}p(x_i)\log(\frac{p(x_i)}{q(x_i)})

交叉熵是信息熵和相对熵的和。

由相对熵的公式展开可得:

D_{KL}(p\|q)= \sum_{i=1}^{n}p(x_i)\log(p(x_i)) - \sum_{i=1}^{n}p(x_i)\log(q(x_i))  = - H(p(x)) + [- \sum_{i=1}^{n}p(x_i)\log(q(x_i))]

注意正负号。可得交叉熵公式如下:

H(p,q) = - \sum_{i=1}^{n}p(x_i)\log(q(x_i)) = D_{KL}(p\|q) + H(p(x))

等式左边就表示交叉熵,综上所述由此信息熵=交叉熵-相对熵

在深度学习中,我们需要评估label和predicts之间的差距,使用KL散度刚刚好,即,由于KL散度中的前一部分不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中直接用交叉熵做loss,评估模型。

3.2 距离公式

由上面两个常用的loss函数可以知道,loss函数的目的旨在度量两个分布之间的差异,或者可以说为了得到想要的model,必须最小化两个分布之间的距离,在这里距离就是一个关键词。因此下面我们退讨论一下经典的度量距离的公式,有时根据实际情况,可以用作loss函数,也许会有意想不到的效果。

  • 欧氏距离(Euclidean Distance)

欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式。

假设两个n维向量分别是 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots x_{2n}) 。那么欧氏距离公式如下:

D_{ab} = \sqrt{\sum_{i=1}^{i=n}(x_{1i} - x_{2i})^2}

  • 曼哈顿距离(Manhattan Distance)

从名字就可以猜出这种距离的计算方法了。想象你在曼哈顿要从一个十字路口开车到另外一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。实际驾驶距离就是这个“曼哈顿距离”。而这也是曼哈顿距离名称的来源, 曼哈顿距离也称为城市街区距离(City Block distance)。

假设两个n维向量分别是 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots y_{2n}) 。那么曼哈顿距离公式如下:

D_{ab} = \sqrt{\sum_{i=1}^{i=n}|x_{1i} - x_{2i}|}

  • 切比雪夫距离 ( Chebyshev Distance )

国际象棋玩过么?国王走一步能够移动到相邻的8个方格中的任意一个。那么国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?自己走走试试。你会发现最少步数总是max( | x2-x1 | , | y2-y1 | ) 步 。有一种类似的一种距离度量方法叫切比雪夫距离。

假设两个n维向量分别是 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots y_{2n}) 。那么切比雪夫距离公式如下:

D_{ab} = \max_i(|x_{1i}-x_{2i}|)

也有另外一种等价形式:

D_{ab} = \lim_ {k\to \infty} (\sum_{i=1}^{n}|x_{1i} - x_{2i}|^k)^{1/k}

  • 闵式距离 ( Minkowski Distance )

闵氏距离不是一种距离,而是一组距离的定义。

假设两个n维向量分别是 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots y_{2n}) ,闵氏距离的定义为:

D_{ab} =  (\sum_{i=1}^{n}|x_{1i} - x_{2i}|^p)^{1/p}

其中,p是一个变参数,当p为1时,为曼哈顿公式;当p=2时,为欧式距离;当p趋近于无穷的时候,为切比雪夫距离。

但是闵氏距离的缺点也很明显,举个例子:二维样本(身高,体重),其中身高范围是150 ~ 190,体重范围是50 ~ 60,有三个样本:a(180,50),b(190,50),c(180,60)。那么a与b之间的闵氏距离(无论是曼哈顿距离、欧氏距离或切比雪夫距离)等于a与c之间的闵氏距离,但是身高的10cm真的等价于体重的10kg么?因此用闵氏距离来衡量这些样本间的相似度很有问题。

简单说来,闵氏距离的缺点主要有两个:(1)将各个分量的量纲(scale),也就是“单位”当作相同的看待了。(2)没有考虑各个分量的分布(期望,方差等)可能是不同的。

  • 标准化欧氏距离 (Standardized Euclidean distance )

标准化欧氏距离是针对简单欧氏距离的缺点而作的一种改进方案。标准欧氏距离的思路:既然数据各维分量的分布不一样,好吧!那我先将各个分量都“标准化”到均值、方差相等吧。均值和方差标准化到多少呢?这里先复习点统计学知识吧,假设样本集X的均值(mean)为m,标准差(standard deviation)为s,那么X的“标准化变量”表示为:

X^* = \frac{X-m}{s}

经过简单的推导就可以得到两个n维向量 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots y_{2n}) 间的标准化欧氏距离的公式:

D_{ab} = \sqrt{\sum_{i=1}^{i=n}(\frac{x_{1i} - x_{2i}}{s_k})^2}

如果将方差的倒数看成是一个权重,这个公式可以看成是一种加权欧氏距离(Weighted Euclidean distance)。

  • 夹角余弦(Cosine)

也可以叫余弦相似度。 几何中夹角余弦可用来衡量两个向量方向的差异,机器学习中借用这一概念来衡量样本向量之间的差异。

在二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式:

\cos(\theta) = \frac{x_1x_2 + y_1y_2}{\sqrt{x_1^2+y_1^2}\sqrt{x_2^2+y_2^2}}

假设两个n维向量分别是 a(x_{11},x_{12}\dots x_{1n})b(x_{21},x_{22}\dots y_{2n})

\cos(\theta) = \frac{\sum _{k=1}^nx_{1k}x_{2k}}{\sqrt{\sum _{k=1}^nx_{1k}^2}\sqrt{\sum _{k=1}^nx_{2k}^2}}

余弦取值范围为[-1,1]。求得两个向量的夹角,并得出夹角对应的余弦值,此余弦值就可以用来表征这两个向量的相似性。夹角越小,趋近于0度,余弦值越接近于1,它们的方向更加吻合,则越相似。当两个向量的方向完全相反夹角余弦取最小值-1。当余弦值为0时,两向量正交,夹角为90度。因此可以看出,余弦相似度与向量的幅值无关,只与向量的方向相关。

  • 皮尔逊相关系数(Pearson correlation)

皮尔逊相关系数的定义:

\rho_{XY} = \frac{Cov(X,Y)}{\sqrt{D(X)}\sqrt{D(Y)}} = \frac{E((X-EX)(Y-EX))}{\sqrt{D(X)}\sqrt{D(Y)}}

Cov()表示两个分布的协方差,D()表示方差。由公式可知,Pearson 相关系数是用协方差除以两个变量的标准差得到的,虽然协方差能反映两个随机变量的相关程度(协方差大于0的时候表示两者正相关,小于0的时候表示两者负相关),但其数值上受量纲的影响很大,不能简单地从协方差的数值大小给出变量相关程度的判断。为了消除这种量纲的影响,于是就有了相关系数的概念。

皮尔逊相关公式和夹角余弦公式很类似。如果用夹角余弦的表示方式表示皮尔逊相关系数,就如下:

\rho_{XY} =\frac{\sum _{k=1}^n(x_{k}-\bar{x})(y_{k}-\bar{y})}{\sqrt{\sum _{k=1}^n(x_{k}-\bar{x})^2}\sqrt{\sum _{k=1}^n(y_{k}-\bar{y})^2}}

  • 汉明距离(Hamming distance)

两个等长字符串s1与s2之间的汉明距离定义为将其中一个变为另外一个所需要作的最小替换次数。例如字符串“1111”与“1001”之间的汉明距离为2。

应用:信息编码(为了增强容错性,应使得编码间的最小汉明距离尽可能大)。

  • JS散度(Jensen-Shannon)

因为kl散度不具对称性,因此js散度在kl散度的基础上进行了改进:

现有两个分布p1和p2,其JS散度公式为:

D_{JS}(P_1\|P_2) = \frac{1}{2}D_{KL}(P_1\|\frac{P_1+P_2}{2})+\frac{1}{2}D_{KL}(P_2\|\frac{P_1+P_2}{2})

  • Hellinger distance

对于两个离散概率分布 P=(p1,p2,...,pn)和 Q=(q1,q2,...,qn),它们的Hellinger距离可以定义如下:

H(P,Q) = \frac{1}{\sqrt{2}}\sqrt{\sum_{i=1}^{k}(\sqrt{p_i} - \sqrt{q_i})^2}

上式可以看做两个离散概率分布平方根向量的欧式距离,如下:

H(P,Q) = \frac{1}{\sqrt2}\|\sqrt{P} - \sqrt{Q}\|_2

  • 巴氏距离(Bhattacharyya Distance)

在统计中,Bhattacharyya距离测量两个离散或连续概率分布的相似性。它与衡量两个统计样品或种群之间的重叠量的Bhattacharyya系数密切相关。Bhattacharyya距离和Bhattacharyya系数以20世纪30年代曾在印度统计研究所工作的一个统计学家A. Bhattacharya命名。同时,Bhattacharyya系数可以被用来确定两个样本被认为相对接近的,它是用来测量中的类分类的可分离性。

对于离散概率分布p和q在同一域,巴氏距离被定义为如下:

D_B(p,q) = -\mathrm{In}(BC(p,q))

其中BC(p,q)是Bhattacharya系数:

BC(p,q) = \sum_{x\in X}\sqrt{p(x)q(x)}

  • MMD距离(Maximum mean discrepancy)

最大均值差异(Maximum mean discrepancy),度量在再生希尔伯特空间中两个分布的距离,是一种核学习方法。两个随机变量的距离为:

\mathrm{MMD}[\mathcal{F},X,Y] = \sqrt{\frac{1}{m^2}\sum_{i,j=1}^{m}k(x_i,x_j) - \frac{1}{mn}\sum_{i,j=1}^{m,n}k(x_i,y_j)+\frac{1}{n^2}\sum_{i,j=1}^{n}k(y_i,y_j)}

其中k(.)是映射,用于把原变量映射到高维空间中。X,Y表示两种分布的样本,F表示映射函数集。

基于两个分布的样本,通过寻找在样本空间上的映射函数K,求不同分布的样本在K上的函数值的均值,通过把两个均值作差可以得到两个分布对应于K的mean discrepancy。寻找一个K使得这个mean discrepancy有最大值,就得到了MMD。最后取MMD作为检验统计量(test statistic),从而判断两个分布是否相同。如果这个值足够小,就认为两个分布相同,否则就认为它们不相同。更加简单的理解就是:求两堆数据在高维空间中的均值的距离。

近年来,MMD越来越多地应用在迁移学习中。在迁移学习环境下训练集和测试集分别取样自分布p和q,两类样本集不同但相关。我们可以利用深度神经网络的特征变换能力,来做特征空间的变换,直到变换后的特征分布相匹配,这个过程可以是source domain一直变换直到匹配target domain。匹配的度量方式就是MMD。

  • Wasserstein distance

Wasserstein 距离,也叫Earth Mover's Distance,推土机距离,简称EMD,用来表示两个分布的相似程度。

EMD是2000年IJCV期刊文章《The Earth Mover's Distance as a Metric for Image Retrieval》提出的一种直方图相似度量(作者在之前的会议论文中也已经提到,不过鉴于IJCV的权威性和完整性,建议参考这篇文章)。

假设有两个工地P和Q,P工地上有m堆土,Q工地上有n个坑,现在要将P工地上的m堆土全部移动到Q工地上的n个坑中,所做的最小的功。

每堆土我们用一个二元组来表示(p,w),p表示土堆的中心,w表示土的数量。则这两个工地可表示为:

P=\{(p_1,w_{p1}),\dots(p_m,w_{pm})\}

Q=\{(q_1,w_{q1}),\dots(q_n,w_{qn})\}

每个土堆中心 p_i 到每个土坑中心 q_j 都会有一个距离 d_{ij} ,则构成了一个m*n的距离矩阵。

D=[d_{ij}]

那么问题就是我们希望找到一个流(flow),当然也是个矩阵 f_{ij} ,每一项 f_{ij} 代表从 p_iq_j 的流动数量,从而最小化整体的代价函数:

\mathrm{WORK}(P,Q,F) = \sum_{i=1}^m\sum_{j=1}^nd_{ij}f_{ij}

问题描述清楚了:就是把P中的m个坑的土,用最小的代价搬到Q中的n个坑中, p_iq_j 的两个坑的距离由 d_{ij} 来表示。 f_{ij} 是从 p_i 搬到 q_j 的土的量; d_{ij}p_i 位置到 q_j 位置的代价(距离)。要最小化WORK工作量。EMD是把这个工作量归一化以后的表达,即除以对 f_{ij} 的求和。



EMD公式:

\mathrm{EMD}(P,Q) = \frac{\sum_{i=1}^M\sum_{j=1}^Nd_{ij}f_{ij}}{\sum_{i=1}^M\sum_{j=1}^Nf_{ij}}

3.3 简单的推理

在分类问题中,我们经常用到的loss函数有欧氏距离交叉熵。那么这两个到底哪个好呢?有些经验的调包侠可能会说交叉熵,那么到底为什么?

我们以最简单的二分类问题为例,实验采用一个神经元的网络(激活函数采用sigmoid)。输入一个相同的样本x=1(label=0),两次实验各自随机初始化参数,从而产生不同的输出,产生不同的loss。


实验1:第一次输出值为0.82



实验2:第一次输出值为0.98


在实验1中,随机初始化参数,使得第一次输出值为0.82(该样本对应的实际值为0);经过300次迭代训练后,输出值由0.82降到0.09,逼近实际值。而在实验2中,第一次输出值为0.98,同样经过300迭代训练,输出值只降到了0.20。

从两次实验的代价曲线中可以看出:实验1的代价随着训练次数增加而快速降低,但实验2的代价在一开始下降得非常缓慢;直观上看,初始的误差越大,收敛得越缓慢

其实,误差大导致训练缓慢的原因在于使用了二次loss函数。二次loss函数的公式如下:

\mathcal{L} = \frac{1}{2n} \sum_{x}|y(x)-a^\gamma(x)|

其中,C表示代价,x表示样本,y表示实际值,a表示输出值,n表示样本的总数。为简单起见,同样一个样本为例进行说明。

  • 二次loss函数

假设此时二次loss函数为:

\mathcal{L} = \frac{(y-a)^2}{2}

训练网络采用反向传播算法。参数主要有:神经元之间的连接权重w,以及每个神经元本身的偏置b。调参的方式是采用梯度下降算法(Gradient descent),沿着梯度方向调整参数大小。w和b的梯度推导如下:

\frac{\partial\mathcal{L}}{\partial w} = (a-y)\sigma'(z)x

\frac{\partial\mathcal{L}}{\partial b} = (a-y)\sigma'(z)

其中,z表示神经元的输入,表示激活函数。从以上公式可以看出,w和b的梯度跟激活函数的梯度成正比,激活函数的梯度越大,w和b的大小调整得越快,训练收敛得就越快。而神经网络常用的激活函数为sigmoid函数,该函数的曲线如下所示:



如图所示,实验2的初始输出值(0.98)对应的梯度明显小于实验1的输出值(0.82),因此实验2的参数梯度下降得比实验1慢。这就是初始的代价(误差)越大,导致训练越慢的原因。与我们的期望不符,即:不能像人一样,错误越大,改正的幅度越大,从而学习得越快。

  • 交叉熵loss函数

\mathcal{L} = -\frac{1}{n} \sum_x [y\mathrm{In}a+(1-y)\mathrm{In}(1-a)]

其中,x表示样本,n表示样本的总数。那么,重新计算参数w的梯度:

\frac{\partial\mathcal{L}}{\partial w} = -\frac{1}{n} \sum_x(\frac{y}{\sigma(z)} - \frac{1-y}{1-\sigma(z)})\frac{\partial\sigma}{\partial w}

= -\frac{1}{n} \sum_x(\frac{y}{\sigma(z)} - \frac{1-y}{1-\sigma(z)})\sigma'(z)x_j

= \frac{1}{n}\sum_x \frac{\sigma'(z)x_j}{\sigma(z)(1-\sigma(z))}(\sigma(z) - y)

= \frac{1}{n}\sum_xx_j(\sigma(z) - y)

其中 \sigma'(z) = \sigma(z)(1-\sigma(z))

因此,w的梯度公式中原来的 \sigma'(z) 被消掉了,另外,梯度公式中的 \sigma(z)-y 表示输出值与实际值之间的差值。所以,但误差越大,梯度越大,参数w调整的越快。同理得b的梯度为:

\frac{\partial\mathcal{L}}{\partial b } = \frac{1}{n}\sum_x (\sigma(z)-y)

实际情况证明,交叉熵代价函数带来的训练效果往往比二次代价函数要好。

3.4 tensorflow库中的loss函数

  • tf.nn

在tensorflow原生库中,只有最常见的几种loss函数。

tf.nn.softmax\_cross\_entropy\_with\_logits(logits= Network.out, labels= Labels\_onehot)

上面是softmax交叉熵loss,参数为网络最后一层的输出和onehot形式的标签。切记输入一定不要经过softmax,因为在函数中内置了softmax操作,如果再做就是重复使用了。在计算loss的时候,输出Tensor要加上tf.reduce_mean(Tensor)或者tf.reduce_sum(Tensor),作为tensorflow优化器(optimizer)的输入。

tf.nn.sparse\_softmax\_cross\_entropy\_with\_logits (logits=Network.out, labels= Labels)

这个函数和上面的区别就是labels参数应该是没有经过onehot的标签,其余的都是一样的。另外加了sparse的loss还有一个特性就是标签可以出现-1,如果标签是-1代表这个数据不再进行梯度回传。

tf.nn. sigmoid\_cross\_entropy\_with\_logits (logits= Network.out, labels= Labels\_onehot)

sigmoid交叉熵loss,与softmax不同的是,该函数首先进行sigmoid操作之后计算交叉熵的损失函数,其余的特性与 tf.nn.softmax\_cross\_entropy\_with\_logits 一致。

tf.nn.weighted\_cross\_entropy\_with\_logits (logits=Network.out, labels=Labels\_onehot, pos\_weight=decimal\_number)

这个loss与众不同的地方就是加入了一个权重的系数,其余的地方与 tf.nn.softmax\_cross\_entropy\_with\_logits 这个损失函数是一致的,加入的pos_weight函数可以适当的增大或者缩小正样本的loss,可以一定程度上解决正负样本数量差距过大的问题。

  • tf.keras

tf.keras.losses 中是全部的loss函数库,但是也只是非常普通有限的函数。

3.4 总结

简单说来,各种“距离”的应用场景简单概括为,空间:欧氏距离,路径:曼哈顿距离,国际象棋国王:切比雪夫距离,以上三种的统一形式:闵可夫斯基距离,加权:标准化欧氏距离,排除量纲和依存:马氏距离,向量差距:夹角余弦,编码差别:汉明距离,集合近似度:杰卡德类似系数与距离,相关:相关系数与相关距离

综上所述,loss函数的作用是获得一个监督信号,引导模型更新参数,使模型能够将输入的数据映射到一个高维空间,最终完成分类或者回归的任务。而这个监督信号,就是两个样本空间分布之间的差异,我们想要达到的分布就是labels那样的分布,所以loss函数的输出就是两个分布之间的距离(在不同问题中,可以用不同的方式去表征这样一个距离)。

最常见的loss函数可以利用tensorflow中原生的函数得到,但是在实际运用中,最好可以根据实际情况设计合理的loss函数,以达到更好的效果。可以说在各项任务中,loss设计是完全不可忽略的一环。

以上内容部分取自网络,如有侵权,请联系。

发布于 2018-09-23