1. 程式人生 > >神經網絡代價函數與交叉熵

神經網絡代價函數與交叉熵

交叉熵 softmax回歸 flow cast cross softmax .so ade equal

在此我們以MSE作為代價函數:

技術分享圖片

其中, C表示代價 函數 ,x表示樣本, y表示實際值, 表示實際值, 表示實際值, a表示輸出值, 表示輸出值, n表示樣本的總數。為簡單起見 表示樣本的總數。為簡單起見 表示樣本的總數。

a=σ(z), z=∑W j*X j+b
σ() 是激活函數

使用梯度下降法(Gradient descent)來調整權值參數的大小,權值w和偏置b的梯度推導如下:

技術分享圖片

其中,z表示神經元的輸入,σ表示激活函數。w和b的梯度跟激活函數的梯度成正比,激活函數的梯度越大,w和b的大小調整得越快,訓練收斂得就越快。

假設我們的激活函數是sigmoid函數:

技術分享圖片

若我們的預測值為1,A點處的梯度大,能以較快的速度逼近預測值,B點梯度小,逼近速度較慢,這樣效果比較好

若我們的預測值為0,A點出的梯度大,能以較快的速度逼近預測值,B點梯度小,逼近速度慢,效果差

我們希望在與預測值較遠的點能以較快的速度逼近,較近的點一較慢的速度逼近。

接下來我們不改變激活函數,而是改變代價函數:

技術分享圖片

可得到如下結果:

技術分享圖片

這樣在與預測值較遠的情況下能以較快的速度逼近,較近的情況下,以較慢的速度逼近,符合想要的效果。

結論:1.交叉熵代價函數中,權值和偏置值的調整與無關,另外,梯度公式中的表示輸出值與實際值的誤差。所以當誤差越大時,梯度就越大,參數w和b的調整就越快,訓練的速度也就越快。
    2.如果輸出神經元是線性的,那麽二次代價函數就是一種合適的選擇。如果輸出神經元是S型函數,那麽比較適合用交叉熵代價函數。

    3.對數釋然函數常用來作為softmax回歸的代價函數,如果輸出層神經元是sigmoid函數,可以采用交叉熵代價函數。而深度學習中更普遍的做法是將softmax作為最後一層,此時常用的代價函數是
對數釋然代價函數。

    4.對數似然代價函數與softmax的組合和交叉熵與sigmoid函數的組合非常相似。對數釋然代價函數在二分類時可以化簡為交叉熵代價函數的形式。

    5.在Tensorflow中用:
      tf.nn.sigmoid_cross_entropy_with_logits()來表示跟sigmoid搭配使用的交叉熵。
       tf.nn.softmax_cross_entropy_with_logits()來表示跟softmax搭配使用的交叉熵。

另外,可能產生過擬合問題:
技術分享圖片

技術分享圖片

此時我們可以在代價函數中加入正則項:技術分享圖片,右式第二部分即為正則項。正則化的思想就是在代價函數中加入刻畫模型復雜程度的指標。

關於防止過擬合的問題,在下一篇文章中做討論。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

‘‘‘
##簡單版本
##只有兩層網絡,輸入層和輸出層
‘‘‘

mnist = input_data.read_data_sets(MNIST_data,one_hot=True)

batch_size = 100
n_batch = mnist.train.num_examples // batch_size

x_train = tf.placeholder(tf.float32,[None,784])
y_train = tf.placeholder(tf.float32,[None,10])

w = tf.Variable(tf.zeros([784,10]))
bias = tf.Variable(tf.zeros([1,10]))
y = tf.nn.softmax(tf.matmul(x_train,w) + bias)

# loss = tf.reduce_mean(tf.square(y - y_train))   #MSE代價函數
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_train,logits=y)) #交叉熵代價函數
#train = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#train = tf.train.AdadeltaOptimizer(1e-3).minimize(loss)
train = tf.train.MomentumOptimizer(0.1,0.9).minimize(loss)

init = tf.global_variables_initializer()

correct = tf.equal(tf.argmax(y_train,1),tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(31):
        for batch in range(n_batch):
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train,feed_dict={x_train:batch_xs,y_train:batch_ys}) 
    
        acc = sess.run(accuracy,feed_dict={x_train:mnist.test.images,y_train:mnist.test.labels})
        print(iteration , str(epoch), accuracy: ,acc)

神經網絡代價函數與交叉熵