TF - 代價函數和過擬合

二次代價函數(quadratic cost)

  • 其中,C表示代價函數,x表示樣本,y表示實際值,a表示輸出值,n表示樣本的總數。為簡單起見,同樣一個樣本為例進行說明,此時二次代價函數為:
  • a=σ(z), z=∑Wj*Xj+b
    σ() 是激活函數

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

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

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

  • 案例的調整方案應該為:離目標比較遠,梯度比較大,權值調整比較大;離目標近,梯度比較小,權值調整比較小;

交叉熵代價函數(cross-entropy)

  • 換一個思路,我們不改變激活函數,而是改變代價函數,改用交叉熵代價函數:
  • 其中,C表示代價函數,x表示樣本,y表示實際值,a表示輸出值,n表示樣本的總數。
  • 權值和偏置值的調整與

    無關,另外,梯度公式中的

    表示輸出值與實際值的誤差。所以當誤差越大時,梯度就越大,參數w和b的調整就越快,訓練的速度也就越快。
  • 如果輸出神經元(激活函數)是線性的,那么二次代價函數就是一種合適的選擇。如果輸出神經元是S型函數,那么比較適合用交叉熵代價函數。

對數釋然代價函數(log-likelihood cost)

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

  • 條件概率分布p(y|x)的對數似然函數:


機器學習之Softmax回歸模型

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

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

擬合

回歸問題
分類問題
  • 防止過擬合

① 增加數據集

② 在代價函數后面增加一個 正則化方法(w權值,n訓練集的大小,入是調節(jié)參數)

在優(yōu)化C的過程中,會使W權值較的越來越小,使得他的權值幾乎等于0,就可以認為這個神經元是不存在的

  1. Dropout (在訓練迭代的過程中使用部分神經元工作,在測試時激活全部神經元測試 )
  • 一般網絡過于復雜,數據量較小,容易引起過擬合。(用訓練集測試出來的準確率大于測試集很明顯)下列建立過擬合場景,通過改變keep_prob值進行dropout
import tensorflow as tf
import os
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 載入數據集(放在當前代碼目錄)
mnist = read_data_sets("MNIST_data/", one_hot=True)

# 每個批次的大?。看斡柧殘D片的數量)
batch_size = 100
# 計算一共有多少個批次
n_batch = mnist.train.num_examples // batch_size

# 定義兩個placeholder(輸入圖片和標簽)
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)

# 創(chuàng)建神經網絡

# 用截斷的正態(tài)分布對權值進行初始化,標準差為0.1(這樣初始化效果會比較好)
w1 = tf.Variable(tf.truncated_normal([784, 2000], stddev=0.1))
b1 = tf.Variable(tf.zeros([2000]) + 0.1)
# 定義雙曲正切激活函數
L1 = tf.nn.tanh(tf.matmul(x, w1) + b1)
# keep_prob控制多少神經元在工作
L1_drop = tf.nn.dropout(L1, keep_prob)

# 加隱藏層
w2 = tf.Variable(tf.truncated_normal([2000, 2000], stddev=0.1))
b2 = tf.Variable(tf.zeros([2000]) + 0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop, w2) + b2)
L2_drop = tf.nn.dropout(L2, keep_prob)

w3 = tf.Variable(tf.truncated_normal([2000, 1000], stddev=0.1))
b3 = tf.Variable(tf.zeros([1000]) + 0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop, w3) + b3)
L3_drop = tf.nn.dropout(L3, keep_prob)

w4 = tf.Variable(tf.truncated_normal([1000, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10]) + 0.1)
prediction = tf.nn.softmax(tf.matmul(L3_drop, w4) + b4)

# 換成交叉熵代價函數
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))

# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

# 初始化變量
init = tf.global_variables_initializer()

# 比較真實值和預測值概率最大標簽是否相同,結果存放在一個布爾型列表中
# argmax 返回一維張量中最大的值所在的位置
correct_prediction = tf.equal(tf.argmax(y, 1), tf.arg_max(prediction, 1))
# 求準確率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.Session(config=config) 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_step, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 1.0})

            test_acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
            train_acc = sess.run(accuracy, feed_dict={x: mnist.train.images, y: mnist.train.labels, keep_prob: 1.0})
            print("Iter " + str(epoch) + ",Testing Accuracy " + str(test_acc) + ",Train Accuracy " + str(train_acc))

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容