tensorflow中四種不同交叉熵函數tf.nn.softmax_cross_entropy_with_logits()


Tensorflow中的交叉熵函數
tensorflow中自帶四種交叉熵函數,可以輕松的實現交叉熵的計算。

tf.nn.softmax_cross_entropy_with_logits()
tf.nn.sparse_softmax_cross_entropy_with_logits()
tf.nn.sigmoid_cross_entropy_with_logits()
tf.nn.weighted_cross_entropy_with_logits()
注意:tensorflow交叉熵計算函數輸入中的logits都不是softmax或sigmoid的輸出,而是softmax或sigmoid函數的輸入,因為它在函數內部進行sigmoid或softmax操作。而且不能在交叉熵函數前進行softmax或sigmoid,會導致計算會出錯。

一、sigmoid交叉熵
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
argument:   
_sentinel:本質上是不用的參數,不用填
logits:計算的輸出,注意是為使用softmax或sigmoid的,維度一般是[batch_size, num_classes] ,單樣本是[num_classes]。數據類型(type)是float32或float64;
labels:和logits具有相同的type(float)和shape的張量(tensor),即數據類型和張量維度都一致。
name:操作的名字,可填可不填
output:
loss,shape:[batch_size,num_classes]

注意:它對於輸入的logits先通過sigmoid函數計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進行了優化,使得結果不至於溢出。output不是一個數,而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mea(loss)使用。

例子:

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('按計算公式計算的結果:\n',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('tf計算的結果:\n',E2)
# 輸出的E1,E2結果相同

 

 

二、softmax交叉熵
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
argument:
_sentinel:本質上是不用的參數,不用填
logits:計算的輸出,注意是為使用softmax或sigmoid的,維度一般是[batch_size, num_classes] ,單樣本是[num_classes]。數據類型(type)是float32或float64;
labels:和logits具有相同的type(float)和shape的張量(tensor),即數據類型和張量維度都一致。
name:操作的名字,可填可不填
output:
loss,shape:[batch_size]

其他同上

例子:

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)
 
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('按計算公式計算的結果:\n', E1)  # 按計算公式計算的結果
print('tf計算的結果:\n', E2)
# 輸出的E1,E2結果相同

 

 

三、sparse_softmax交叉熵
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
argument:
_sentinel:本質上是不用的參數,不用填
logits:一個數據類型(type)是float32或float64;
shape:[batch_size,num_classes]

labels: shape為[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一個索引, type為int32或int64,說白了就是當使用這個函數時,tf自動將原來的類別索引轉換成one_hot形式,然后與label表示的one_hot向量比較,計算交叉熵。

name: 操作的名字,可填可不填
output:

loss,shape:[batch_size]

例子:

import tensorflow as tf
 
# 假設只有三個類,分別編號0,1,2,labels就可以直接輸入下面的向量,不用轉換與logits一致的維度
labels = [0,1,2]
 
logits = [[2,0.5,1],
          [0.1,1,3],
          [3.1,4,2]]
 
logits_scaled = tf.nn.softmax(logits)
result = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
 
with tf.Session() as sess:
    print(sess.run(result))

 

 

四、weighted交叉熵
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None)
計算具有權重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
argument:
_sentinel:本質上是不用的參數,不用填
logits:一個數據類型(type)是float32或float64;
shape:[batch_size,num_classes],單樣本是[num_classes]
labels:和logits具有相同的type(float)和shape的張量(tensor),
pos_weight:正樣本的一個系數
name:操作的名字,可填可不填
output:
loss,shape:[batch_size,num_classes]



 

 

 

感謝:https://blog.csdn.net/qq_35203425/article/details/7977345


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM