神经网络经典损失函数-交叉熵和均方误差

在神经网络中,如何判断一个输出向量和期望的向量有多接近呢?交叉熵(cross entropy)是常用的方法之一,刻画了两个概率分布之间的距离,是分类问题中使用较多的一种损失函数。
给定两个概率分布p和q,通过q来表示p的交叉熵为:
交叉熵
如何将神经网络前向传播得到的结果也变成概率分布,比较常用的方法为Softmax回归。
Softmax回归本身可以作为一个学习算法来优化分类结果,但在TensorFlow中,Softmax回归的参数被去掉了,因为它只是额外的一层处理层,将神经网络的输出变成一个概率分布。
假设原始的神经网络输出为:y1,y2,…,yn,那么经过Softmax回归处理之后的输出为:
神经网络经典损失函数-交叉熵和均方误差_第1张图片
可以看出,原始神经网络的输出被用作置信度来生成新的输出,从而可以通过交叉熵来计算预测的概率分布和真实答案的概率分布之间的距离。
从交叉熵的公式来看,刻画的是通过概率分布q来表达概率分布p的困难程度,当交叉熵作为神经网络的损失函数时,p代表的是正确答案,q代表的是预测值。交叉熵刻画的是两个概率分布的距离,也就是说交叉熵值越小,两个概率分布越接近。
假设有一个三分类问题,某个样例的正确答案是(1,0,0),某模型经过Softmax回归只有的预测答案是(0.5,0.4,0.1),那么交叉熵为:
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*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代表预测结果。通过tf.clip_by_value函数可以将一个张量的数值限制在一个范围(如1e-10, 1.0)内,可以避免一些错误例如log0。tf.log函数完成了对张两种所有元素依次求对数的功能。*符号为乘法,是元素之间的直接相乘。
通过上面三个运算完成了对于每一个样例中的每一个类别交叉熵p(x)logq(x)的计算,得到了一个n*m的二维矩阵,n为batch中样例的数量,m为分类的类别数。根据交叉熵的公式,应该将每行中的m个结果相加得到所有样例的交叉熵,然后再对这n行取平均得到一个batch的平均交叉熵。但是因为分类问题的类别数量是不变的,所以可以直接对整个矩阵做平均而并不改变计算结果的意义。这使得整个程序更加简洁,tf.reduce_mean就是求所有数的平均数。
因为交叉熵一般会与softmax回归一起使用,所以TensorFlow对这两个功能进行了封装,提供了tf.nn.softmax_cross_entropy_with_logits函数,就可以直接通过下面的代码来下实现softmax回归之后的交叉熵损失函数:

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y, y_)
#y为原始神经网络的输出结果,y_为标准答案

与分类问题不一样,回归主要解决的是对具体数值的预测,解决回归问题的神经网络一般只有一个输出节点,这个节点的输出值就是预测值。对于回归问题,最常用的损失函数是均方误差(MSE),定义为:
神经网络经典损失函数-交叉熵和均方误差_第2张图片
其中yi为一个batch中第i个数据的正确答案,而yi’为神经网络给出的预测值。可使用以下代码实现均方误差损失函数:

mse = tf.reduce_mean(tf.square(y_, y))
#y为神经网络的输出答案,y_为标准答案
#减法-是两个矩阵中对应元素相减

你可能感兴趣的:(TensorFlow,深度学习)