1. 程式人生 > >Tensorflow 損失函式及學習率的四種改變形式

Tensorflow 損失函式及學習率的四種改變形式

Reference: https://blog.csdn.net/marsjhao/article/details/72630147

分類問題損失函式-交叉熵(crossentropy)

        交叉熵描述的是兩個概率分佈之間的距離,分類中廣泛使用的損失函式,公式如下     

        在網路中可以通過Softmax迴歸將前向傳播得到的結果變為交叉熵要求的概率分數值。Tensorflow中,Softmax迴歸的引數被去掉,通過一層將神經網路的輸出變為一個概率分佈。

程式碼實現

import tensorflow as tf
 
y_ = tf.constant([[1.0, 0, 0]]) # 正確標籤
y1 = tf.constant([[0.9, 0.06, 0.04]]) # 預測結果1
y2 = tf.constant([[0.5, 0.3, 0.2]]) # 預測結果2
# 以下為未經過Softmax處理的類別得分
y3 = tf.constant([[10.0, 3.0, 2.0]])
y4 = tf.constant([[5.0, 3.0, 1.0]])
 
# 自定義交叉熵
cross_entropy1 = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y1, 1e-10, 1.0)))
#tf.clip_by_value 將一個tensor元素數值限制在指定範圍內,防止一些錯誤,起到數值檢查作用。 cross_entropy2 = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y2, 1e-10, 1.0))) # TensorFlow提供的整合交叉熵 # 注:該操作應該施加在未經過Softmax處理的logits上,否則會產生錯誤結果 # labels為期望輸出,且必須採用labels=y_, logits=y的形式將引數傳入 cross_entropy_v2_1 = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y3) cross_entropy_v2_2
= tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y4) sess = tf.InteractiveSession() print('[[0.9, 0.06, 0.04]]:', cross_entropy1.eval()) print('[[0.5, 0.3, 0.2]]:', cross_entropy2.eval()) print('v2_1', cross_entropy_v2_1.eval()) print('v2_2',cross_entropy_v2_2.eval()) sess.close() ''' [[0.9, 0.06, 0.04]]: 0.0351202 [[0.5, 0.3, 0.2]]: 0.231049 v2_1 [ 0.00124651] v2_2 [ 0.1429317] '''

迴歸問題損失函式-均方誤差(MSE,mean squared error)

       均方誤差也可以用於分類問題的損失函式,

           

 

自定義損失函式

        對於如下自定義損失函式的Tensorflow實現

          loss= tf.reduce_sum(tf.where(tf.greater(y, y_), (y-y_)*loss_more,(y_-y)*loss_less))

           tf.greater(x,y),返回x>y判斷結果的bool型tensor。 tf.where(condition,x=None,y=None,name=None)根據condition選擇x或者y。

程式碼實現

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
# tf.select()在1.0以後版本中已刪除,tf.where()替代
loss = tf.reduce_sum(tf.where(tf.greater(y, y_),
                               (y-y_)*loss_more, (y_-y)*loss_less))
train_step = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
 
rdm = RandomState(seed=1) # 定義一個隨機數生成器並設定隨機種子
dataset_size = 128
X = rdm.rand(dataset_size, 2)
Y = [[x1 + x2 +rdm.rand()/10.0 - 0.05] for (x1, x2) in X] # 增加一個-0.05~0.05的噪聲
 
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
for i in range(5000):
    start = (i * batch_size) % dataset_size
    end = min(start+batch_size, dataset_size)
    train_step.run({x: X[start: end], y_: Y[start: end]})
    if i % 500 == 0:
        print('step%d:\n' % i, w1.eval())
print('final w1:\n', w1.eval())
sess.close()
 
'''
loss_less = 10
loss_more = 1
final w1:
 [[ 1.01934695]
 [ 1.04280889]]
loss_less = 1
loss_more = 10
final w1:
 [[ 0.95525807]
 [ 0.9813394 ]]
loss_less = 1
loss_more = 1
final w1:
 [[ 0.9846065 ]
 [ 1.01486754]]
'''

Tensorflow 的Cross_Entropy實現

      1. tf.nn.softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None,dim=-1,name=Node)

          作用:自動計算logits(未經過Softmax)與labels 之間的cross_entropy交叉熵。logits 為神經網路最後一層的輸出,有batch的話,大小為[batchsize,num_classes],單樣本的話就是num_classes。labels:為ground Truth大小同上。labels的每一行為one-hot表示。

     2.tf.nn.sparse_softmax_cross_entropy_with_logits()

         輸入的logits是未經縮放的,函式內部對logits進行一個softmax操作。返回值為一個向量,求交叉熵做一步tf.reduce_sum操作,求loss,進一步做tf.reduce_mean,對向量求均值。

    3.tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None,name=None)

    4.tf.nn.weithted_cross_entropy_with_logits(targets,logits,pos_weith,name=None)

 

學習率的四種改變形式:

       1.fixed:learning rate 固定不變

       2.Step:在每次迭代stepsize次後,減少gmma倍。lr = lr x gamma

       3. polynomial: 呈多項式曲線下降,lr = base_lr x(t/T)^power

       4. Inv:隨著迭代次數的增加而下降。LR = base_lr x(1+gmma x iter)^power