參考:
交叉熵
總結:對於回歸問題經常會使用mse均方誤差(l2取平均)計算損失,對於分類問題經常會使用sigmoid交叉熵損失函式。
2.1 l2正則損失函式(回歸場景)
# l2損失
loss_l2_vals=tf.square(y_pred - y_target)
loss_l2_out=sess.run(loss_l2_vals)
# 均方誤差
loss_mse_vals= tf.reduce.mean(tf.square(y_pred - y_target))
loss_mse_out = sess.run(loss_mse_vals)
2.2 tf.nn.sigmoid_cross_entropy_with_logits(分類場景)
由於每個類別互不排斥,輸出結果都不是有效的概率分布(乙個batch內輸出結果經過sigmoid後和不為1),那麼如何計算他們的交叉熵呢(交叉熵要求輸入的是概率分布)。其實loss的計算是element-wise的,方法返回的loss的形狀和labels是相同的,也是[batch_size, num_classes],再呼叫reduce_mean方法計算batch內的平均loss。所以這裡的cross entropy其實是一種class-wise的cross entropy,每乙個class是否存在都是乙個事件,對每乙個事件都求cross entropy loss,再對所有的求平均,作為最終的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(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 封裝方法計算
#交叉熵計算方式 tf.reduce_sum
loss = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits))
#loss 計算方式 tf.reduce_mean
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits))
#歸一化
sigmoid_v = tf.nn.sigmoid(logits, -1)
#類是互斥時,返回多個類別
# **權重
pred_probs = sigmoid_v # 示例,分類是互斥時,這裡返回值不是單個值,是向量
#如果只返回最大可能性的類別
pred_prob = tf.reduce_max(sigmoid_v) #**權重
pred_label = tf.argmax(logits, axis=-1, name='label') # **類別
if e1.all() == e2.all():
print("true")
else:
print("false")
# 輸出的e1,e2結果相同
注意:sigmoid_cross_entropy_with_logits函式的返回值並不是乙個數,而是乙個向量。如果要求交叉熵,需要使用tf.reduce_sum求和,即對向量裡面所有元素求和;如果求loss,使用tf.reduce_mean求均值,對向量求均值!
2.3 tf.nn.softmax_cross_entropy_with_logits(分類場景)
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)
#交叉熵計算方式
loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits))
#loss 計算方式
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits))
# 歸一化
pred_probs = tf.nn.softmax(logits)
#取歸一化後的最大值
max_pred_prob = tf.reduce_max(pred_probs, axis=-1)
# **類別
pred_label = tf.argmax(logits, axis=-1, name='label')
if e1.all() == e2.all():
print("true")
else:
print("false")
# 輸出的e1,e2結果相同
2.4 tf.nn.sparse_softmax_cross_entropy_with_logits(分類場景)
這個版本是tf.nn.softmax_cross_entropy_with_logits的易用版本,其logits的形狀依然是[batch_size, num_classes],但是labels的形狀是[batch_size, ],每個label的取值是從[0, num_classes)的離散值,這也更加符合我們的使用習慣,是哪一類就標哪個類對應的label。
如果已經對label進行了one hot編碼,則可以直接使用tf.nn.softmax_cross_entropy_with_logits。
import tensorflow as tf
labels = [0,2] #labels形式與softmax_cross_entropy_with_logits不同
logits = [[2,0.5,1],
[0.1,1,3]]
e1 = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
with tf.session() as sess:
print sess.run(e1)
>>>[ 0.46436879 0.17425454]
總結:到底是用sigmoid版本的cross entropy還是softmax版本的cross entropy主要取決於我們模型的目的,以及label的組織方式,這個需要大家在使用的時候去揣摩,到底使用哪一種loss比較合理。 損失函式 損失函式 Hinge
本文討論hinge損失函式,該函式是機器學習中常用的損失函式之一。在機器學習中,hinge loss是一種損失函式,它通常用於 maximum margin 的分類任務中,如支援向量機。數學表示式為 其中 表示 輸出,通常都是軟結果 就是說輸出不是0,1這種,可能是0.87。表示正確的類別。其函式影...
損失函式Loss相關總結(精細版)
目錄 loss損失函式的作用 損失函式loss和準確率accuracy的比較 回歸任務中的loss主要包括 tensorflow和keras 體現 mae和l1的區別在於乙個求了均值np.mean 乙個沒有求np.sum 2者的曲線走勢也是完全一致的。mae損失對於局外點更魯棒,但它的導數不連續使得...
常見損失函式 損失函式選擇方法
神經網路的學習通過某個指標表示現在的狀態,然後以這個指標為基準,尋找最優權重引數,這個指標就是損失函式 loss function 如上介紹,神經網路損失函式 loss function 也叫目標函式 objective function 的作用 衡量神經網路的輸出與預期值之間的距離,以便控制 調節...