機器學習-關於自定義損失函數(tensorflow筆記)

對於迴歸問題,最常用的損失函數是均方誤差(MSE,mean squared error),但是對於實際問題,MSE可能是最接近於真實答案,但卻不是能使實際問題利益最大化的選擇。比如對於預測商品銷量的問題,如果預測多了(預測值大於真實銷量),損失的是商品的成本,如果預測少了(預測值小於真實銷量),損失的是商品的利潤。那有可能多預測一個少掙1元,而少預測一個就可能少掙10元。因此需要將損失函數與利潤直接聯繫起來。
於是用這個函數去刻畫損失:

Loss(y,y')=∑f(yi,yi'),f(x,y)=a(x-y)(當x>y時),f(x,y)=b(y-x)(當x<=y時),a等於10,b等於1,符合了實際情況。
因此用tensorflow去訓練神經網絡完成這件事情。
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.0,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)
dataset_size = 128
X = rdm.rand(dataset_size,2)

#   設置迴歸的正確值爲兩個輸入的和加上一個隨機量。之所以要加上一個隨機量是爲了
#   加入不可預測的噪音,因爲不同的損失函數都會在能完全預測正確的時候最低。一般
#   來說噪音爲一個均值爲0的小量,所以這裏設置爲-0.05~0.05的隨機數
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 = 5000
    for i in range(STEPS):
        start = (i*batch_size)%dataset_size
        end = min(start+batch_size,dataset_size)
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        print(sess.run(w1))

此時的w1爲:
也就是說比x1+x2大,因爲預測少了損失更大,這樣確實更符合邏輯。

若用均方誤差作爲損失函數,w1=[0.97437561,1.0243336]顯然接近真實值,但並不是我們期待的更好的預測結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章