目录
2.1.softmax_cross_entropy_with_logits
2.2.sigmoid_cross_entropy_with_logits
2.3. sparse_softmax_cross_entropy_with_logits
2.4. weighted_cross_entropy_with_logits
1. 四个交叉熵函数
TensorFlow针对分类问题,实现了四个交叉熵函数,分别是
- tf.nn.sigmoid_cross_entropy_with_logits
- tf.nn.softmax_cross_entropy_with_logits
- tf.nn.sparse_softmax_cross_entropy_with_logits
- tf.nn.weighted_cross_entropy_with_logits
总的计算交叉熵,需要加 tf.reduce_mean!!!tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits
2. 具体tensorflow中实现
2.1.softmax_cross_entropy_with_logits
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
- labels:和logits具有相同type和shape的张量(tensor),,是一个有效的概率,sum(labels)=1, one_hot=True(向量中只有一个值为1.0,其他值为0.0)。
- 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
- 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象。
- output:不是一个数,而是一个batch中每个样本的loss,所以一般配合
tf.reduce_mean(loss)
使用。计算公式:
image.png
- 用例:
import tensorflow as tf import numpy as np def softmax(x): sum_raw = np.sum(np.exp(x),axis=-1) x1 = np.ones(np.shape(x)) for i in range(np.shape(x)[0]): x1[i] = np.exp(x[i])/sum_raw[i] return x1 y = np.array([[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0]])# 每一行只有一个1 logits =np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]]) # 按计算公式计算 y_pred =softmax(logits) E1 = -np.sum(y*np.log(y_pred),-1) print(E1) # 按封装方法计算 sess = tf.Session() y = np.array(y).astype(np.float64) E2 = sess.run(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits)) print(E2) if E1.all() == E2.all(): print("True") else: print("False") # 输出的E1,E2结果相同
2.2.sigmoid_cross_entropy_with_logits
tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels)
output不是一个数,而是一个batch中每个样本的loss,所以一般配合
tf.reduce_mean(loss)
使用。计算方式:对输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得的结果不至于溢出。
适用:每个类别相互独立但互不排斥的情况:例如一幅图可以同时包含一条狗和一只大象
4计算方式
例子
import tensorflow as tf import numpy as np def sigmoid(x): return 1.0/(1+np.exp(-x)) # 5个样本三分类问题,且一个样本可以同时拥有多类 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) # 按 tf 封装方法计算 if E1.all() == E2.all(): print("True") else: print("False") # 输出的E1,E2结果相同
2.3. sparse_softmax_cross_entropy_with_logits
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
- labels:shape为[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一个索引, type为int32或int64
- 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
- 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象 。
- output不是一个数,而是一个batch中每个样本的loss,所以一般配合
tf.reduce_mean(loss)
使用。- 计算公式:和
tf.nn.softmax_cross_entropy_with_logits()
的计算公式一样,只是要将labels转换成tf.nn.softmax_cross_entropy_with_logits()
中labels的形式
2.4. weighted_cross_entropy_with_logits
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None)
- 计算具有权重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
计算公式:
3. 均方平方差
常见的Loss函数还有均方平方差(Mean Squared Error):
tensorflow中tf.losses.mean_squared_error()就是直接计算mse值了。
mse2 = tf.losses.mean_squared_error(a, b) with tf.Session() as sess: print(sess.run(mse2))
reference:
https://www.jianshu.com/p/75f7e60dae95