损失函数(loss/cost)用于描述模型预测值与真实值的差距大小.
一般常见的有两种算法----均值平方差(MSE) 和 交叉熵。
参考:https://blog.csdn.net/qq_42413820/article/details/80936092
在tensorflow中没有独立的MSE函数,不过可以自己组合:
MSE = tf.reduce_mean(tf.pow(tf.sub(logits, labels), 2.))
MSE = tf.reduce_mean(tf.square(tf.sub(logits, labels)))
MSE = tf.reduce_mean(tf.square(logits, labels))
labels代表标签值,logits代表预测值
在 tensorflow 中常见的交叉熵函数有:
1. sigmoid 交叉熵
2. softmax 交叉熵
3. spares 交叉熵
4. 加权sigmoid 交叉熵
tf.nn.weighted_cross_entropy_with_logits(logits, targets,pos_weight,name=None) | 在交叉熵的基础上给第一项乘以一个系数(加权),是增加或减少正样本在计算交叉熵时的损失值 |
tf.nn.sigmoid_cross_entropy_with_logits(logits, targets,name=None) | 计算输入logits与targets的交叉熵 |
tf.nn.softmax_cross_entropy_with_logits(logits, labels,name=None) | 计算输入logits与labels的softmax交叉熵 logits与labels必须是相同shape的数据类型 |
tf.nn.spares_softmax_cross_entropy_with_logits(logits, labels,name=None) | 计算输入logits与labels的softmax交叉熵 与softmax_cross_entropy_with_logits功能一样,区别是spares_softmax_cross_entropy_with_logits的样本真实值与预测值结果不要one_hot编码,但是要求分类的个数一定要从0开始。假如是5类,就是0,1,2,3,4这5个数 |
import tensorflow as tf
'''labels = [[0, 0, 1], [0, 1, 0]] logits = [[2, 0.5, 6], [0.1, 0, 3]] logits_scaled = tf.nn.softmax(logits) logits_scaled2 = tf.nn.softmax(logits_scaled) result1 = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels) result2 = tf.nn.softmax_cross_entropy_with_logits(logits=logits_scaled, labels=labels) result3 = -tf.reduce_sum(labels*tf.log(logits_scaled), 1) with tf.Session() as sess: print('scaled= ', sess.run(logits_scaled)) # scaled= [[0.01791432 0.00399722 0.97808844] [0.04980332 0.04506391 0.90513283]] # 经过第二次的 softmax 后,分布概率会有变化 print('scaled2= ', sess.run(logits_scaled2)) # scaled2 = [[0.21747023 0.21446465 0.56806517] [0.2300214 0.22893383 0.5410447]] # 正确方式 print('result1', sess.run(result1), '\n') # result1 [0.02215516 3.0996735 ] # 如果将 softmax 变换完的值放进去,就相当于第二次 softmax 的loss, 所以会出错 print('result2', sess.run(result2), '\n') # result2 [0.56551915 1.4743223 ] print('result3', sess.run(result3), '\n') # result3 [0.02215518 3.0996735 ]'''
# 标签总概率为1 labels = [[0.4, 0.1, 0.5], [0.3, 0.6, 0.1]] result4 = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels) with tf.Session() as sess: # result4: [2.1721554 2.7696736] 对于正确分类的交叉熵与错误分类的交叉熵,二者差别没有 one_hot 编码那么明显 print('result4: ', sess.run(result4), '\n')
# sparse 标签 labels = [2, 1] # 表明 lables 中一共分为3个类: 0, 1, 2. [2, 1] == one_hot编码中的 001 和 010 result5 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels) with tf.Session() as sess: print('result5: ', sess.run(result5), '\n') # result5: [0.02215516 3.0996735 ] 与 result1 完全一样'''
loss = tf.reduce_mean(result1) labels = [[0, 0, 1], [0, 1, 0]] loss2 = tf.reduce_mean(-tf.reduce_sum(labels*tf.log(logits_scaled), 1)) with tf.Session() as sess: print('loss: ', sess.run(loss)) print('loss2: ', sess.run(loss2))