tensorflow入门之损失函数
1. 深層網絡介紹
激活函數實現去線性化
在沒有加入激活函數的時候,一個模型的運算其實就是輸出是輸入的線性加權和,不管中間有多少的隱層,因為每個隱藏層都是在做一個線性變換,后面不管再加上多少隱藏層,都是在做線性變換,因為線性模型的特點就是任意線性模型的組合任然是線性模型。
比如前向傳播的計算公式:a(1)=XW(1),y=a(1)W(2)a(1)=XW(1),y=a(1)W(2)
其中x為輸入,w為參數,整理得:y=X(W(1)W(2))=XW′y=X(W(1)W(2))=XW′
所以可以看出不管中間的隱藏層有多少層,其效果和一層隱藏層是一樣的,都是線性的變換,而現實中的例子都是非線性的,此時的深度網絡只通過加深網絡層是沒有改變線性的本質,這時,通過在神經元中加入激活函數(非線性函數),可以實現非線性變換。
tensorflow提供了7種不同的非線性激活函數,其中常用的是:
- tf.nn.relu
- tf.sigmoid
- tf.tanh
2. 經典損失函數
首先神經網絡模型的效果以及優化的目標是通過損失函數來定義的。
在一般的二分類中,常通過sigmoid函數來把輸出映射到0-1之間,這時一般取0.5作為閾值分割點,大于0.5的被分類到正類,小于0.5的被分類到負類。而在多分類中,理論上可以通過設置多個閾值區間來進行多分類,但在解決實際問題時并不常用,常用的是在輸出層設置n個節點,每個節點代表一類。有了這個思想,我們就可以由此對樣本打標簽,比如:[0,1,0,0,0,1],其中一個節點為1,其他的都為0。那么此時的網絡輸出也應該是類似的形式,但實際的輸出并不具有概率意義,這個時候就有了softmax層的出現,把實際輸出轉換成一個概率分布。有了期望輸出和實際輸出,當然要進行損失函數的確定,一般都是用交叉熵損失函數。
簡單總結就是:原始的神經網絡輸出通過softmax層作用后被用作置信度來生成新的輸出,而新的輸出滿足概率分布的所有要求。這個新的輸出可以理解為經過神經網絡的推到,一個樣例為不同類別的概率分別為多大,這樣就把神經網絡的輸出也變成了一個概率分布,這個時候就可以通過交叉熵來計算預測輸出和真實分類的概率分布之間的差距了。
交叉熵為:H(p,q)=?∑xp(x)logq(x)H(p,q)=?∑xp(x)logq(x)
從交叉熵的公式中可以看到交叉熵函數是不對稱的(H(p,q)≠H(q,p)H(p,q)≠H(q,p),它刻畫的是通過概率分布q來表達概率分布p的困難程度。因為正確分類是希望得到的結果,所以當交叉熵作為損失函數時,p代的是正確分類,而q代表的是預測值。交叉熵刻畫的是兩個概率分布的距離,也就是說交叉熵越小,兩個概率分布越接近。
具體可以參考:https://blog.csdn.net/lilong117194/article/details/81542667
在只有一個正確答案的分類問題中,tensorflow提供了tf.nn.sparse_softamx_cross_entropy_with_logits函數來進一步加速計算。
在預測問題中常用的損失函數是均方誤差損失函數:MSE(y,y′)=∑ni=1(yi?y′i)2nMSE(y,y′)=∑i=1n(yi?yi′)2n
在tensorflow中實現是:mse=tf.reduce_mean(tf.square(y_ - y)),其中的-也是兩個矩陣中對應元素的減法。
3. 自定義損失函數
tensorflow不僅支持經典的損失函數,還可以優化任意的自定義損失函數。
下面的例子是預測商品的銷售量問題。如果預測值比實際值大,則商家損失的是生產商品的成本,而如果預測的值小于實際值,則損失的是商品的利潤。這里由于在大部分情況下商品的成本和商品的利潤是不會嚴格相等的,也就是說如果使用上述的均方誤差損失函數就不能最大化銷售利潤,因為當預測和實際值相等時,這時并不是最大化的利潤,所以這個時候就要換個思路,不能再用均方誤差函數了,需要自定義一個損失函數。
例如:一個商品的成本是1元,但是利潤是10元,那么少預測一個就少掙10元,而多預測一個才少掙1元。
這里要注意的是損失函數是定義的損失,而要最大化利潤就要把損失函數刻畫成成本和代價,下面給出一個損失函數:
得到: loss(y,y′)=∑ni=1f(yi,y′i)loss(y,y′)=∑i=1nf(yi,yi′)
這里 y′y′是預測值, yy是正確值,aa就是上述的10, bb就是1。
從公式可以推導出:
- a(x?y)a(x?y)是預測小于真實值時的損失,這里a是10,權重大于b,就說明在最小化損失函數時,懲罰比較大,即是對于少預測大損失的情況要盡可能少的發生。
- 相反b(y?x)b(y?x)是預測值大于真實值的損失,這里的權重比較小,懲罰也比較小。
此時模型提供的預測值有可能最大化收益。 tensorflow中通過以下實現:
loss = tf.reduce_sum(tf.select(tf.greater(y, y_), (y - y_) * loss_more, (y_ - y) * loss_less))tf.greater:比較輸入兩個輸入張量中的每個元素的大小,當輸入的張量維度不一致時,tensorflow會通過numpy廣播操作的處理。
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()) sess.close()
tf.select:有三個輸入參數,當第一個選擇條件根據,當為true時選擇輸出第二個參數中的值,否則選擇輸出第三個參數的值。
例如:運行結果:
[False False True True] [4. 3. 3. 4.]示例:
import tensorflow as tf from numpy.random import RandomState# 定義神經網絡的相關參數和變量 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)# 定義損失函數使得預測少了的損失大,于是模型應該偏向多的方向預測。 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)rdm = RandomState(1) X = rdm.rand(128,2) # 設置回歸的正確值為兩個輸入和加上一個隨機量,也就是一個不可預測的噪音 Y = [[x1+x2+(rdm.rand()/10.0-0.05)] for (x1, x2) in X]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))運行結果:
After 0 training step(s), w1 is: [[-0.81031823][ 1.4855988 ]] After 1000 training step(s), w1 is: [[0.01247112][2.1385448 ]] After 2000 training step(s), w1 is: [[0.45567414][2.1706066 ]] After 3000 training step(s), w1 is: [[0.69968724][1.8465308 ]] After 4000 training step(s), w1 is: [[0.89886665][1.2973602 ]] Final w1 is: [[1.019347 ][1.0428089]]這里得到的結果會更偏向于預測多一點。
注意:
- 為了使得預測多了的時候損失大,這時模型應該往預測少的方向預測,這里只需要改變loss_less = 1,loss_more = 10
- 當定義損失函數為MSE時,預測會和真實值比較接近,但是不是最大化利潤的損失函數。
參考:《Tensorflow實戰Google深度學習框架》
總結
以上是生活随笔為你收集整理的tensorflow入门之损失函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 相反b(y?x)b(y?x)是預測值大于真實值的損失,這里的權重比較小,懲罰也比較小。
- 上一篇: 借款利息怎么算公式
- 下一篇: tensorflow中学习率、过拟合、滑