TensorFlow:分类问题的损失函数

2022-07-29,,,

交叉熵损失函数

分类问题中最常用的方法是设置n个输出节点,其中n为类别的个数。对于每一个样例,神经网络可以得到一个n维数组作为输出结果。例如在识别数字中一共有10个可能的结果,对于识别数字1,神经网络的输出结果应该越接近[0,1,0,0,0,0,0,0,0,0]越好,所以我们需要构建一个评价输出向量和期望向量距离的指标。交叉熵是常用的评判方法之一。
给定两个概率分布p和q,通过q来表示p的交叉熵为:
H
(
p
,
q
)
=


x
p
(
x
)
l
o
g
q
(
x
)
H(p,q)=-\displaystyle\sum_{x}p(x)log q(x)
H(p,q)=xp(x)logq(x)

  • List item

交叉熵刻画了两个概率分布的距离,然而神经网络输出却不一定是概率分布。概率分布刻画了不同事件发生的概率。在分类问题中,“一个样本属于某个类别”看作一个概率事件,那么训练数据的正确答案就符合一个概率分布。例如一个三分类的样本期望输出是(1,0,0),实际输出(x,y,z)中x应为样本是第一类的概率,y应为样本是第二类的概率,z应为样本是第三类的概率,所以理论上x+y+z=1。但是神经网络前向传播的输出结果却不尽人意。这时候需要谈到Softmax回归。
假设原始的神经网络输出为 y
1
,
y
2
,
.
.
.
,
y
n
,
y_1,y_2,...,y_n,
y1,y2,...,yn,
那么经过Softmax回归处理的输出为:
s
o
f
t
m
a
x
(
y
)
i
=
y
i

=
e
y
i

j
=
1
n
e
y
j
softmax(y)_i=y_i'=\frac {e^{y_i}} {\sum_{j=1}^n {e^{y_j}} }
softmax(y)i=yi=j=1neyjeyi

这样就可以将神经网络的输出经过softmax回归用作置信度来生成新的输出。
举个例子:
对于某个三分类问题,某个样本的正确答案为(1,0,0)。其模型经过Softmax回归后的答案是(0.5,0.4,0.1),那么这个预测和正确答案之间的交叉熵为:
H
(
(
1
,
0
,
0
)
,
(
0.5
,
0.4
,
0.1
)
)
=

(
1
×
log

0.5
+
0
×
log

0.4
+
0
×
log

0.1
)

0.3
H((1,0,0),(0.5,0.4,0.1))=-(1\times\log{0.5}+0\times\log0.4+0\times\log0.1)\approx0.3
H((1,0,0),(0.5,0.4,0.1))=(1×log0.5+0×log0.4+0×log0.1)0.3

如果另外一个模型的预测是(0.8,0.1,0.1),那么这个预测和真实值之间的交叉熵是:
H
(
(
1
,
0
,
0
)
,
(
0.8
,
0.1
,
0.1
)
)
=

(
1
×
log

0.8
+
0
×
log

0.1
+
0
×
log

0.1
)

0.1
H((1,0,0),(0.8,0.1,0.1))=-(1\times\log{0.8}+0\times\log0.1+0\times\log0.1)\approx0.1
H((1,0,0),(0.8,0.1,0.1))=(1×log0.8+0×log0.1+0×log0.1)0.1

tensorflow中实现交叉熵的代码是:

cross_entropy=-tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0))) 

其中y_表示正确结果,y是预测结果。这行代码包含了4个不同的tf运算。通过tf.clip_by_value函数可以将一个张量中的数值限制在一个范围之内(比如log0是无效的)。

v=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]]) print tf.clip_by_value(v,2.5,4.5).eval() #输出[[2.5,2.5,3.][4. 4.5 4.5] 

tf.log函数是对张量中所有元素依次求对数。
“*”表示乘法,这不是矩阵乘法,是元素间直接相乘。
矩阵乘法是tf.matmul,下面解释二者区别:

v1=tf.constant([[1.0.2.0],[3.0,4.0]]) v2=tf.constant([[5.0.6.0],[7.0,8.0]]) print (v1*v2).eval() #[[5. 12.][21. 32.]] print tf.matmul(v1,v2).eval() #[[19. 22.][43. 50.]]  

tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值,如下:

import tensorflow as tf
v=tf.constant([[1.,2.,3.],[4.,5.,6.]]) with tf.Session() as sess: print (tf.reduce_mean(v).eval()) #输出3.5 

一般情况下交叉熵要在softmax回归后使用,所以tensorflow对这两个功能进行了封装,提供了tf.nn.softmax_cross_entropy_with_logits函数:

cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y) 

其中y是神经网络输出结果,而y_是标准答案,通过这个函数可以得到Softmax回归之后的交叉熵。

均方误差损失函数

与分类问题不同,回归问题解决的是对具体数值的预测,比如房价预测、销量预测等。这些问题需要输出的预测不是一个事先定义好的类别,而是一个任意实数。所以这些问题的神经网络一般只有一个输出节点,这个节点输出预测值。对于回归问题最常用的损失函数是均方误差(MSE):
M
S
E
(
y
,
y

)
=

i
=
1
n
(
y
i

y
i

)
2
n
MSE(y,y')=\frac{\sum^n_{i=1}(y_i-y_i')^2}{n}
MSE(y,y)=ni=1n(yiyi)2

其中yi为一个batch中第i个数据的正确答案,yi‘为预测值。以下代码实现MSE:

mse=tf.reduce_mean(tf.square(y_-y)) 

本文地址:https://blog.csdn.net/qq_45047020/article/details/108742828

《TensorFlow:分类问题的损失函数.doc》

下载本文的Word格式文档,以方便收藏与打印。