本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.
损失函数在【机器学习基础】中有所提及,在深度学习中所使用最多的是均值平方差(MSE)和交叉熵(cross entropy)损失,这里着重介绍一下这两个损失函数及其在tensorflow中的实现。
1. 均方差损失
均方差就是预测值与真实值之间的差异,其公式为:
一般对于 标签是实数且无界的值 的时候,损失函数选用均方差损失。
均方差在tensorflow中的实现也比较简单:
MSE = tf.reduce_mean(tf.pow(tf.sub(logits, labels), 2.0))
MSE = tf.reduce_mean(tf.square(tf.sub(logits, labels)))
MSE = tf.reduce_mean(tf.square(logits, labels))
2. 交叉熵损失
交叉熵损失有 sigmoid交叉熵、softmax交叉熵、Sparse交叉熵、加权sigmoid交叉熵 。
2.1 sigmoid 交叉熵损失
对于sigmoid交叉熵,网络的输出值经过sigmoid函数,然后再与真实值计算交叉熵,但是由于sigmoid的映射是相互独立的,相加并不等于1。
因此,sigmoid对于二分类,最后的输出为一维的数值(LR算法),表明属于该类别的概率p,而不属于该类别的概率则为1-p;
而对于 多分类任务,输出的最后一维为m维,也就是m个类别,每一维表示属于该类别的概率,因此这里sigmoid将不再适用 。
对于多标签的分类,相当于多个二分类任务,最后一层输出为m维(m个标签),然后用sigmoid计算属于每个标签的概率,大于0.5则表明属于该标签。
在tensorflow中sigmoid交叉熵损失:
tf.nn.sigmoid_cross_entropy_with_logits(logits, labels, name=None)
logits为输出层的值,该值 没有经过simoid之前 ,labels为标签。
sigmoid交叉熵损失适用于每个类别相互独立但互不排斥的多标签分类问题 ,例如一幅图可以同时包含一条狗和一只大象。
output不是一个数,比如 5个样本三分类问题,且一个样本可以同时拥有多类,一个样本会在每个类别上有一个交叉熵,输出也就是5*3矩阵。
y = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 0], [0, 1, 0]]) logits = np.array([[12, 3, 2], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]]) y_pred = sigmoid(logits) E1 = -y * np.log(y_pred)- (1-y) * np.log(1-y_pred) print(E1) sess = tf.Session() y = np.array(y).astype(np.float64) # labels是float64的数据类型 E2 = sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits)) print(E2) # output:E1 = E2 [[6.14419348e-06 3.04858735e+00 2.12692801e+00] [3.04858735e+00 4.53988992e-05 1.31326169e+00] [1.31326169e+00 2.12692801e+00 6.71534849e-03] [1.81499279e-02 1.50231016e-03 1.46328247e+00] [3.04858735e+00 2.47568514e-03 1.31326169e+00]]
2.2 softmax 交叉熵损失
softmax交叉熵 是最常用的一种损失函数, 适用于多分类的问题 ,在手写数字识别中每个数字只可能属于某一个类别。
经softmax层后输出m维,表示m个类别,这m个值相加等于1,表示属于某一个类别的概率。
softmax交叉熵损失在tensorflow中定义:
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
跟sigmoid交叉熵一样,这里的 logits都是没有经过对应的softmax之前的那一层输出 。
如果经过了softmax层,然后再计算交叉熵也是可以的:
# 最后一层的网络输出result # 经过一层softmax result1 = tf.nn.softmax(result) # 通过result1计算交叉熵 cross_entropy = -tf.reduce_sum(labels * tf.log(result1), 1)
上面的方法与softmax_cross_entropy_with_logits得到的结果是一致的。
对于softmax交叉熵, 一个样本所得到的交叉熵就是一个值 ,一个batch_size的交叉熵就有batch_size个值,因此最后还要 进一步加和求loss :
loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(logits, labels))
等价于:
loss = tf.reduce_sum(-tf.reduce_sum(labels * tf.log(result1), 1))
2.3 Sparse 交叉熵损失
Sparse交叉熵损失是用于非ont_hot编码的标签,也就是标签变成了具体的数值,比如对于多分类ont_hot标签【0,0,1】,那幺Sparse中对应的标签为数值2。
在tensorflow中处理这样的问题使用:
tf.nn.sparse_corss_entropy_with_logits(logits, labels)
这个函数会将传入的非one-hot标签转成one-hot标签,所以它的计算方式与softmax相同,而且适用于多分类的情况,一般情况为了避免不必要的麻烦,不经常使用这个方法,还是直接在处理数据时one-hot。
logits = [[2, 0.5,6], [0.1,0, 3]] labels = [2,1] result = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
2.4 总结
1、对于二分类情况,通常sigmoid交叉熵和softmax交叉熵损失均可使用,只是使用的方式不同,sigmoid是一个一维的值,softmax是二维的;
2、sigmoid交叉熵损失适用于多标签分类问题,如一张图片中既有猫,又有狗;
3、softmax交叉熵损失和Sparse交叉熵损失适用于多分类问题
参考资料:
【深度学习理论】一文搞透sigmoidsoftmax交叉熵/l1/l2/smooth l1 loss
交叉熵和softmax函数和sigmoid函数(在二分类中的比较)
这两种是深度学习中最常用的损失函数,因此这里只对这两种做一个简单的介绍,主要交叉熵在调用的时候容易出错,这里做一个记录。
Be First to Comment