二次代價函數(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的組合和交叉熵與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,就可以認為這個神經元是不存在的
- 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))


