TensorFlow损失函数(loss function) 2017-08-14 11:32 125人阅读 评论(0) 收藏 举报 分类: 深度学习及TensorFlow实现(10) 版权声明:
TensorFlow損失函數(loss function)
2017-08-14 11:32?125人閱讀?評論(0)?收藏?舉報 ?分類: 深度學習及TensorFlow實現(10)?版權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[+]
神經網絡模型的效果及優化的目標是通過損失函數來定義的。
1、經典損失函數
分類問題和回歸問題是監督學習的兩大種類。
分類問題
常用方法:交叉熵(cross_entropy),它描述了兩個概率分布之間的距離,當交叉熵越小說明二者之間越接近。它是分類問題中使用比較廣的一種損失函數。?
給定兩個概率分布p和q,通過q來表示p的交叉熵為:?
交叉熵刻畫的是兩個概率分布之間的距離,但是神經網絡的輸出卻不一定是一個概率分布。概率分布刻畫了不同事件發生的概率。當事件總數是有限的情況下,概率分布函數p(X=x)滿足:?
如何將神經網絡前向傳播得到的結果變成概率分布,Softmax回歸就是一個非常常用的辦法。?
Softmax回歸本身可以作為一個學習算法來優化分類結果,但在TensorFlow中,Softmax回歸的參數被去掉了,它只是一層額外的處理層,將神經網絡的輸出變成一個概率分布。下圖展示了加上Softmax回歸的神經網絡結構圖。?
交叉熵作為神經網絡的損失函數時,p代表的是正確答案,q代表的是預測值。交叉熵刻畫的是兩個概率分布的距離,交叉熵值越小,兩個概率分布越接近。
案例:?
有個三分類問題,樣例正確答案(1,0,0)。?
某模型經過Softmax回歸之后的預測答案是(0.5,0.4,0.1),那么這個預測和正確答案之間的交叉熵為:?
另一個模型的預測是(0.8,0.1,0.1),那么這個預測和真實值之間的交叉熵是:?
H((1,0,0),(0.8,0.1,0.1))=?(1×log0.8+0×log0.1+0×log0.1)≈0.1
從直觀上可以很容易地知道第二個預測答案要優于第一個。通過交叉熵計算得到的結果也是一致的(第二個交叉熵的值更小)。
TensorFlow實現交叉熵,代碼如下:
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))- 1
tf.clip_by_value函數可以將一個張量中的數值限制在一個范圍內,這樣就避免了一些運算錯誤(比如log0是無效的)。
y_:正確結果?
y :預測結果
TensorFlow對交叉熵和softmax回歸進行了統一封裝,我們可以直接使用如下代碼實現使用softmax回歸后的交叉熵損失函數:
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y,y_)- 1
回歸問題
回歸問題解決的是對具體數值的預測。比如房價預測、銷量預測等都是回歸問題。這些問題需要預測的不是一個事先定義好的類別,而是一個任意實數。解決回顧問題的神經網絡一般只有一個輸出節點,這個節點的輸出值就是預測值。對于回歸問題,最常用的損失函數是均方誤差(MSE,mean squared error )。它的定義如下:?
其中yi為一個batch中第i個數據的正確答案,而yi′為神經網絡給出的預測值。?
如下代碼展示了如何通過TensorFlow實現均方誤差損失函數:
mse = tf.reduce_sum(tf.square(y_ - y))
- 1
其中y代表了神經網絡的輸出答案,y_代表了標準答案。
2、自定義損失函數
例:如果一個商品的成本是1元,但是利潤是10元,那么少預測一個就少賺10元,而多預測一個少賺1元。?
為了最大化預期利潤,需要將損失函數和利潤直接聯系起來。下面公式給出了一個當預測多于真實值和預測少于真實值時有不同損失系數的損失函數:?
yi為一個batch中第i個數據的正確答案,y′i為神經網絡得到的預測值,
a(x?y)x>y表示正確答案多于預測答案的情況?
b(y?x)x≤y表示正確答案少于預測答案的情況
TensorFlow實現這個損失函數:
a= 10 b= 1 loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * a, (y_ - y) * b))- 1
- 2
- 3
(tf.select已被舍棄,使用tf.where替代)
再看一個tf.where和tf.greater使用的例子
import tensorflow as tfv1 = tf.constant([1.0,2.0,3.0,4.0]) v2 = tf.constant([4.0,3.0,2.0,1.0])sess = tf.InteractiveSession() print(tf.greater(v1,v2).eval()) print(tf.where(tf.greater(v1,v2),v1,v2).eval())- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
輸出:
[False False True True] [ 4. 3. 3. 4.]- 1
- 2
損失函數對訓練結果的影響
下面通過一個簡單的神經網絡程序來講解損失函數對模型訓練結果的影響。下面代碼實現了一個擁有兩個輸入節點、一個輸出節點,沒有隱藏層的神經網絡。
import tensorflow as tf from numpy.random import RandomState- 1
- 2
1.定義神經網絡的相關參數和變量。
batch_size = 8 #兩個輸入節點 x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input") #回歸問題一般只有一個輸出節點 y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input') #定義了一個單層的神經網絡前向傳播過程,這里就是簡單加權和 w1= tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1)) y = tf.matmul(x, w1)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.設置自定義的損失函數。
#定義損失函數使得預測少了的損失大,于是模型應該偏向多的方向預測。 loss_less = 10 loss_more = 1 loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * loss_more, (y_ - y) * loss_less)) train_step = tf.train.AdamOptimizer(0.001).minimize(loss)- 1
- 2
- 3
- 4
- 5
3.生成模擬數據集。
#通過隨機數生成一個模擬數據集 rdm = RandomState(1) X = rdm.rand(128,2) #設置回歸的正確值為兩個輸入的和加上一個隨機量。之所以要加上一個隨機量是為了加入不可預測的噪音,否則不同#損失函數的意義就不大了,因為不同損失函數都會在能完全預測正確的時候最低。一般來說噪音為一個均值為0的小#量,所以這里的噪音設置為-0.05 ~ 0.05的隨機數 Y = [[x1+x2+(rdm.rand()/10.0-0.05)] for (x1, x2) in X]- 1
- 2
- 3
- 4
- 5
4.訓練模型。
with tf.Session() as sess:init_op = tf.global_variables_initializer()sess.run(init_op)STEPS = 5000for i in range(STEPS):start = (i*batch_size) % 128end = (i*batch_size) % 128 + batch_sizesess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})if i % 1000 == 0:print("After %d training step(s), w1 is: " % (i))print(sess.run(w1), "\n")print("Final w1 is: \n", sess.run(w1))- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
輸出:
Final w1 is: [[ 1.01934695][ 1.04280889]]- 1
- 2
- 3
5.重新定義損失函數,使得預測多了的損失大,于是模型應該偏向少的方向預測。
loss_less = 1 loss_more = 10 loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * loss_more, (y_ - y) * loss_less)) train_step = tf.train.AdamOptimizer(0.001).minimize(loss)with tf.Session() as sess:init_op = tf.global_variables_initializer()sess.run(init_op)STEPS = 5000for i in range(STEPS):start = (i*batch_size) % 128end = (i*batch_size) % 128 + batch_sizesess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})if i % 1000 == 0:print("After %d training step(s), w1 is: " % (i))print(sess.run(w1), "\n")print("Final w1 is: \n", sess.run(w1))- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
輸出:
Final w1 is: [[ 0.95525807][ 0.9813394 ]]- 1
- 2
- 3
6.定義損失函數為MSE。
loss = tf.losses.mean_squared_error(y, y_) train_step = tf.train.AdamOptimizer(0.001).minimize(loss)with tf.Session() as sess:init_op = tf.global_variables_initializer()sess.run(init_op)STEPS = 5000for i in range(STEPS):start = (i*batch_size) % 128end = (i*batch_size) % 128 + batch_sizesess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})if i % 1000 == 0:print("After %d training step(s), w1 is: " % (i))print( sess.run(w1), "\n")print ("Final w1 is: \n", sess.run(w1))- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
輸出:
Final w1 is: [[ 0.97437561][ 1.0243336 ]]- 1
- 2
- 3
從上面三種不同的運行結果可看出,對于相同的神經網絡,不同的損失函數會對訓練得到的模型產生重要影響。
總結
以上是生活随笔為你收集整理的TensorFlow损失函数(loss function) 2017-08-14 11:32 125人阅读 评论(0) 收藏 举报 分类: 深度学习及TensorFlow实现(10) 版权声明:的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剑桥加密资产研究的主要发现 金评媒JPM
- 下一篇: TensorFlow学习笔记(二):快速