tf常見的損失函數(LOSS)匯總


  損失函數在機器學習中用於表示預測值與真實值之間的差距。一般而言,大多數機器學習模型都會通過一定的優化器來減小損失函數從而達到優化預測機器學習模型參數的目的。

  哦豁,損失函數這么必要,那都存在什么損失函數呢?

  一般常用的損失函數是均方差函數和交叉熵函數。

  運算公式

  1 均方差函數

  均方差函數主要用於評估回歸模型的使用效果,其概念相對簡單,就是真實值與預測值差值的平方的均值,具體運算公式可以表達如下:

  

均方差函數

 

  其中f(xi)是預測值,yi是真實值。

  其中f(x_{i})是預測值,y_{i}是真實值。

  其中f(xi​)是預測值,yi​是真實值。在二維圖像中,該函數代表每個散點到擬合曲線y軸距離的總和,非常直觀。

  2 交叉熵函數

  出自信息論中的一個概念,原來的含義是用來估算平均編碼長度的。在機器學習領域中,其常常作為分類問題的損失函數。

  

交叉熵函數

 

  其中f(xi)是預測值,yi是真實值。

  其中f(x_{i})是預測值,y_{i}是真實值。

  其中f(xi​)是預測值,yi​是真實值。交叉熵函數是怎么工作的呢?假設在分類問題中,被預測的物體只有是或者不是,預測值常常不是1或者0這樣絕對的預測結果,預測是常用的做法是將預測結果中大於0.5的當作1,小於0.5的當作0。

  此時假設如果存在一個樣本,預測值接近於0,實際值卻是1,那么在交叉熵函數的前半部分:

  

在這里插入圖片描述

 

  其運算結果會遠遠小於0,取符號后會遠遠大於0,導致該模型的損失函數巨大。通過減小交叉熵函數可以使得模型的預測精度大大提升。

  tensorflow中損失函數的表達

  1 均方差函數

  loss = tf.reduce_mean(tf.square(logits-labels))

  loss = tf.reduce_mean(tf.square(tf.sub(logits, labels)))

  loss = tf.losses.mean_squared_error(logits,labels)

  2 交叉熵函數

  loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits)

  #計算方式:對輸入的logits先通過sigmoid函數計算,再計算它們的交叉熵

  #但是它對交叉熵的計算方式進行了優化,使得結果不至於溢出。

  loss = tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits)

  #計算方式:對輸入的logits先通過softmax函數計算,再計算它們的交叉熵,

  #但是它對交叉熵的計算方式進行了優化,使得結果不至於溢出。

  例子

  1 均方差函數

  這是一個一次函數擬合的例子。三個loss的意義相同。

  import numpy as np

  import tensorflow as tf

  x_data = np.random.rand(100).astype(np.float32) #獲取隨機X值

  y_data = x_data * 0.1 + 0.3 #計算對應y值

  Weights = tf.Variable(tf.random_uniform([1],-1.0,1.0)) #random_uniform返回[m,n]大小的矩陣,產生於low和high之間,產生的值是均勻分布的。

  Biaxs = tf.Variable(tf.zeros([1])) #生成0

  y = Weights*x_data + Biaxs

  loss = tf.losses.mean_squared_error(y_data,y) #計算平方差

  #loss = tf.reduce_mean(tf.square(y_data-y))

  #loss = tf.reduce_mean(tf.square(tf.sub(y_data,y)))

  optimizer = tf.train.GradientDescentOptimizer(0.6) #梯度下降法

  train = optimizer.minimize(loss)

  init = tf.initialize_all_variables()

  sess = tf.Session()

  sess.run(init)

  for i in range(200):

  sess.run(train)

  if i % 20 == 0:

  print(sess.run(Weights),sess.run(Biaxs))

  輸出結果為:

  [0.10045234] [0.29975605]

  [0.10010818] [0.2999417]

  [0.10002586] [0.29998606]

  [0.10000619] [0.29999667]

  [0.10000149] [0.2999992]

  2 交叉熵函數

  這是一個Mnist手寫體識別的例子。兩個loss函數都可以進行交叉熵運算,在計算loss函數的時候中間經過的函數不同。

  import tensorflow as tf

  import numpy as np

  from tensorflow.examples.tutorials.mnist import input_data

  mnist = input_data.read_data_sets("MNIST_data",one_hot = "true")

  def add_layer(inputs,in_size,out_size,n_layer,activation_function = None):

  layer_name = 'layer%s'%n_layer

  with tf.name_scope(layer_name):

  with tf.name_scope("Weights"):

  Weights = tf.Variable(tf.random_normal([in_size,out_size]),name = "Weights")

  tf.summary.histogram(layer_name+"/weights",Weights)

  with tf.name_scope("biases"):

  biases = tf.Variable(tf.zeros([1,out_size]) + 0.1,name = "biases")

  tf.summary.histogram(layer_name+"/biases",biases)

  with tf.name_scope("Wx_plus_b"):

  Wx_plus_b = tf.matmul(inputs,Weights) + biases

  tf.summary.histogram(layer_name+"/Wx_plus_b",Wx_plus_b)

  if activation_function == None :

  outputs = Wx_plus_b

  else:無錫人流費用 http://www.xasgfk120.com/

  outputs = activation_function(Wx_plus_b)

  tf.summary.histogram(layer_name+"/outputs",outputs)

  return outputs

  def compute_accuracy(x_data,y_data):

  global prediction

  y_pre = sess.run(prediction,feed_dict={xs:x_data})

  correct_prediction = tf.equal(tf.arg_max(y_data,1),tf.arg_max(y_pre,1)) #判斷是否相等

  accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) #賦予float32數據類型,求平均。

  result = sess.run(accuracy,feed_dict = {xs:batch_xs,ys:batch_ys}) #執行

  return result

  xs = tf.placeholder(tf.float32,[None,784])

  ys = tf.placeholder(tf.float32,[None,10])

  layer1 = add_layer(xs,784,150,"layer1",activation_function = tf.nn.tanh)

  prediction = add_layer(layer1,150,10,"layer2")

  #由於loss函數在運算的時候會自動進行softmax或者sigmoid函數的運算,所以不需要特殊激勵函數。

  with tf.name_scope("loss"):

  loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=ys,logits = prediction),name = 'loss')

  #loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=ys,logits = prediction),name = 'loss')

  #label是標簽,logits是預測值,交叉熵。

  tf.summary.scalar("loss",loss)

  train = tf.train.AdamOptimizer(4e-3).minimize(loss)

  init = tf.initialize_all_variables()

  merged = tf.summary.merge_all()

  with tf.Session() as sess:

  sess.run(init)

  write = tf.summary.FileWriter("logs/",sess.graph)

  for i in range(5001):

  batch_xs,batch_ys = mnist.train.next_batch(100)

  sess.run(train,feed_dict = {xs:batch_xs,ys:batch_ys})

  if i % 1000 == 0:

  print("訓練%d次的識別率為:%f。"%((i+1),compute_accuracy(mnist.test.images,mnist.test.labels)))

  result = sess.run(merged,feed_dict={xs:batch_xs,ys:batch_ys})

  write.add_summary(result,i)

  輸出結果為

  訓練1次的識別率為:0.103100。

  訓練1001次的識別率為:0.900700。

  訓練2001次的識別率為:0.928100。

  訓練3001次的識別率為:0.938900。

  訓練4001次的識別率為:0.945600。

  訓練5001次的識別率為:0.952100。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM