神经网络模型的效果以及优化的目标是通过损失函数来定义的。
经典损失函数
通过神经网络解决多分类问题最常用的方法是设置n个输出节点,其中n为类别的个数。对于每一个样例,神经网络可以得到一个n维数组作为输出结果。数组中每一个维度(也就是每一个节点)对应一个类别。在理想情况下,如果一个样本术语类别k,那么这个类别所对应的输出节点的输出值应该为1,而其他节点的输出都为0.以识别数字1为例,神经网络模型的输出结果越接近[0,1,0,0,0,0,0,0,0,0]越好。那么如何判断一个输出向量和期望的向量有多接近呢?
交叉熵
交叉熵刻画了两个概率分布之间的距离,它是分类问题中使用比较广泛的一种损失函数。
给定两个概率分布p和q,通过q来标识p的交叉熵为:
$$H(p,q)=-\sum_{x} p(x)log\;q(x)$$
注意交叉熵刻画的是两个概率分布之间的距离,然而神经网络的输出却不一定是一个概率分布。概率分布刻画了不同时间发生的概率。当时间总是有限的情况下,概率分布函数P(X=x)满足:
$$\forall x\; p(X=x) \in[0,1]且\sum_{x}p(X=x)=1$$
也就是说,任意事件发生的概率在0到1之间,且中有某个事件发生(概率和为1)。如果将分类问题中的“一个样例术语某一个类别”看成一个概率事件,那么训练数据的正确答案就符合一个概率分布。因为事件“一个样例属于不正确的类别”概率为0,而“一个样例术语正确的类别”的概率为1。可以使用Softmax回归将神经网络前向传播得到的结果变成概率分布。
Softmax回归
Softmax回归本身可以作为一个学习算法来优化分类结果,但在TensorFlow中,Softmax回归的参数被去掉了,它只是一层额外的处理层,将神经网络的输出变成一个概率分布。
假设神经网络原始输出为$y_1$,$y_2$,$y_3$,…$y_n$,那么经过Softmax回归处理后的输出为:
$$ softmax(y)_ {i}=y_ {i}^{‘}=\frac{e^{y_{i}}}{\sum_{j=1}^{n}e^{y_{j}}} $$
从以上公式可以看出,原始神经网络输出被用作置信度来生成新的输出,而新的输出满足概率分布的所有要求。这个新的输出可以理解为经过神经网络的推导,一个样例为不同类别的概率分布为多大,这样就把神经网络的输出也变成了一个概率分布,从而可以通过交叉熵来计算预测的概率分布和真是答案的概率分布之间的距离了。
假设某个样例的正确答案为(1,0,0)。某模型经过Softmax回归后的预测答案是$Y_1$=(0.5,0.4,0.1),$Y_2$=(0.8,0.1,0.1),它们的交叉熵分别为:
$$ H_{1}((1,0,0),(0.5,0.4,0.1))=-(1 \times log\;0.5 + 0 \times log\;0.4 + 0 \times log\;0.1) \approx 0.3$$
$$ H_{2}((1,0,0),(0.8,0.1,0.1))=-(1 \times log\;0.8 + 0 \times log\;0.1 + 0 \times log\;0.1) \approx 0.1$$
从直观上可以看到第二个预测答案要优于第一个,交叉熵计算的结果是一致的。
TensorFlow交叉熵实现:1
2
3
4
5# y_:正确结果
# y:预测结果
# tf.clip_by_value(y, value1, value2)将张量中的数值限制在value1到value2之间
# 小于value1换成value1,大于value2换成value2
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))