前言
上篇筆記我們利用MNIST數(shù)據(jù)集訓(xùn)練了一個(gè)手寫(xiě)數(shù)字識(shí)別的模型爆班,但是準(zhǔn)確率非常的低衷掷,維持在91%左右,我們可以嘗試著將準(zhǔn)確率提高到96%以上柿菩,在實(shí)驗(yàn)之前我們需要先了解一些基本的概念戚嗅,本篇文章可能會(huì)有些枯燥,因?yàn)榇蠖喽际抢碚撝R(shí)枢舶。
本文重點(diǎn)
- 激活函數(shù)
- 代價(jià)函數(shù)
- 擬合
什么是激活函數(shù)懦胞?激活函數(shù)是干嘛的?
想了解什么是激活函數(shù)凉泄,就要先了解神經(jīng)網(wǎng)絡(luò)的基本模型躏尉,下圖所示為一單一人工神經(jīng)網(wǎng)絡(luò)的基本模型圖:
神經(jīng)網(wǎng)絡(luò)中的每個(gè)神經(jīng)元節(jié)點(diǎn)接受上一層神經(jīng)元的輸出值作為本神經(jīng)元的輸入值,并將輸入值傳遞給下一層旧困,輸入層神經(jīng)元節(jié)點(diǎn)會(huì)將輸入屬性值直接傳遞給下一層(隱藏層或輸出層)醇份。在多層神經(jīng)網(wǎng)絡(luò)中,上層節(jié)點(diǎn)的輸出和下層節(jié)點(diǎn)的輸入之間具有一個(gè)函數(shù)關(guān)系吼具,這個(gè)函數(shù)稱為激活函數(shù)(又稱激勵(lì)函數(shù))僚纷。
如果我們不運(yùn)用激活函數(shù)的話,則輸出信號(hào)將僅僅是一個(gè)簡(jiǎn)單的線性函數(shù)拗盒。線性函數(shù)一個(gè)一級(jí)多項(xiàng)式〔澜撸現(xiàn)如今,線性方程是很容易解決的陡蝇,但是它們的復(fù)雜性有限痊臭,并且從數(shù)據(jù)中學(xué)習(xí)復(fù)雜函數(shù)映射的能力更小哮肚。一個(gè)沒(méi)有激活函數(shù)的神經(jīng)網(wǎng)絡(luò)將只不過(guò)是一個(gè)線性回歸模型(Linear regression Model)罷了,它功率有限广匙,并且大多數(shù)情況下執(zhí)行得并不好允趟。我們希望我們的神經(jīng)網(wǎng)絡(luò)不僅僅可以學(xué)習(xí)和計(jì)算線性函數(shù),而且還要比這復(fù)雜得多鸦致。同樣是因?yàn)闆](méi)有激活函數(shù)潮剪,我們的神經(jīng)網(wǎng)絡(luò)將無(wú)法學(xué)習(xí)和模擬其他復(fù)雜類(lèi)型的數(shù)據(jù),例如圖像分唾、視頻抗碰、音頻、語(yǔ)音等绽乔。這就是為什么我們要使用人工神經(jīng)網(wǎng)絡(luò)技術(shù)弧蝇,諸如深度學(xué)習(xí)(Deep learning),來(lái)理解一些復(fù)雜的事情折砸,一些相互之間具有很多隱藏層的非線性問(wèn)題看疗,而這也可以幫助我們了解復(fù)雜的數(shù)據(jù)。
那么為什么我們需要非線性函數(shù)睦授?
非線性函數(shù)是那些一級(jí)以上的函數(shù)鹃觉,而且當(dāng)繪制非線性函數(shù)時(shí)它們具有曲率。現(xiàn)在我們需要一個(gè)可以學(xué)習(xí)和表示幾乎任何東西的神經(jīng)網(wǎng)絡(luò)模型睹逃,以及可以將輸入映射到輸出的任意復(fù)雜函數(shù)。神經(jīng)網(wǎng)絡(luò)被認(rèn)為是通用函數(shù)近似器(Universal Function Approximators)祷肯。這意味著他們可以計(jì)算和學(xué)習(xí)任何函數(shù)沉填。幾乎我們可以想到的任何過(guò)程都可以表示為神經(jīng)網(wǎng)絡(luò)中的函數(shù)計(jì)算。
而這一切都?xì)w結(jié)于這一點(diǎn)佑笋,我們需要應(yīng)用激活函數(shù)f(x)翼闹,以便使網(wǎng)絡(luò)更加強(qiáng)大,增加它的能力蒋纬,使它可以學(xué)習(xí)復(fù)雜的事物猎荠,復(fù)雜的表單數(shù)據(jù),以及表示輸入輸出之間非線性的復(fù)雜的任意函數(shù)映射蜀备。因此关摇,使用非線性激活函數(shù),我們便能夠從輸入輸出之間生成非線性映射碾阁。
激活函數(shù)的另一個(gè)重要特征是:它應(yīng)該是可以區(qū)分的输虱。我們需要這樣做,以便在網(wǎng)絡(luò)中向后推進(jìn)以計(jì)算相對(duì)于權(quán)重的誤差(丟失)梯度時(shí)執(zhí)行反向優(yōu)化策略脂凶,然后相應(yīng)地使用梯度下降或任何其他優(yōu)化技術(shù)優(yōu)化權(quán)重以減少誤差宪睹。
二次代價(jià)函數(shù)
二次代價(jià)函數(shù)的公式如下:
其中愁茁,C表示代價(jià),x表示樣本亭病,y表示實(shí)際值鹅很,a表示輸出值,n表示樣本的總數(shù)罪帖。為簡(jiǎn)單起見(jiàn)促煮,以一個(gè)樣本為例進(jìn)行說(shuō)明,此時(shí)二次代價(jià)函數(shù)為:
其中胸蛛,
是激活函數(shù)
加入我們使用梯度下降法來(lái)調(diào)整權(quán)值參數(shù)的大小污茵,權(quán)值w和偏置b的梯度推導(dǎo)如下:
其中,z表示神經(jīng)元的輸入葬项,表示激活函數(shù)泞当。從以上公式可以看出,w和b的梯度跟激活函數(shù)的梯度成正比民珍,激活函數(shù)的梯度越大襟士,
和
的大小調(diào)整得越快,訓(xùn)練收斂得就越快嚷量。而神經(jīng)網(wǎng)絡(luò)常用的激活函數(shù)為sigmoid函數(shù)陋桂,該函數(shù)的曲線如下所示:
所以在這種情況下,權(quán)值和偏置的變化就會(huì)出現(xiàn)如下異常:
假設(shè)我們目標(biāo)是收斂到 1蝶溶。A 點(diǎn)為 0.82 離目標(biāo)比較遠(yuǎn)嗜历,梯度比較大,權(quán)值調(diào)整比較大抖所。B 點(diǎn)為 0.98 離目標(biāo)比較近梨州,梯度比較小,權(quán)值調(diào)整比較小田轧。調(diào)整方案合理暴匠。
假如我們目標(biāo)是收斂到 0. A 點(diǎn)為 0.82 離目標(biāo)比較近,梯度比較大傻粘,權(quán)值調(diào)整比較大每窖。B 點(diǎn)為 0.98 離目標(biāo)比較遠(yuǎn),梯度比較小弦悉,權(quán)值調(diào)整比較小窒典。調(diào)整方案不合理。
那么可能有人就會(huì)說(shuō)稽莉,如果我們想要解決上述問(wèn)題崇败,選擇一個(gè)梯度不變化或變化不明顯的激活函數(shù)不就解決問(wèn)題了嗎?圖樣圖森破,那樣雖然簡(jiǎn)單粗暴地解決了這個(gè)問(wèn)題后室,但可能會(huì)引起其他更多更麻煩的問(wèn)題缩膝。而且,類(lèi)似sigmoid這樣的函數(shù)(比如tanh函數(shù))有很多優(yōu)點(diǎn)岸霹,非常適合用來(lái)做激活函數(shù)疾层,具體請(qǐng)自行g(shù)oogle之。
在這里我們不改變激活函數(shù)贡避,選擇將代價(jià)函數(shù)改為交叉熵代價(jià)函數(shù)痛黎。
交叉熵代價(jià)函數(shù)
先放公式:
其中,C表示代價(jià)刮吧,x表示樣本湖饱,y表示實(shí)際值,a表示輸出值杀捻,n表示樣本的總數(shù)井厌。那么,重新計(jì)算參數(shù)w的梯度:
其中:
因此致讥,w的梯度公式中原來(lái)的被消掉了仅仆;另外,該梯度公式中的
表示輸出值與實(shí)際值之間的誤差垢袱。所以墓拜,當(dāng)誤差越大,梯度就越大请契,參數(shù)w調(diào)整得越快咳榜,訓(xùn)練速度也就越快。同理可得爽锥,b的梯度為:
實(shí)際情況證明贿衍,交叉熵代價(jià)函數(shù)帶來(lái)的訓(xùn)練效果往往比二次代價(jià)函數(shù)要好。
- 權(quán)值和偏置值的調(diào)整與
無(wú)關(guān)救恨,另外,梯度公式中的
表示輸出值與實(shí)際值的誤差释树。所以當(dāng)誤差越大時(shí)肠槽,梯度就越大,參數(shù) w 和 b 的調(diào)整就越快奢啥,訓(xùn)練的速度也就越快秸仙。
- 如果輸出神經(jīng)元是線性的,那么二次代價(jià)函數(shù)就是一種合適的選擇桩盲。如果輸出神經(jīng)元是 S 型函數(shù)寂纪,那么比較適合用交叉熵代價(jià)函數(shù)。
對(duì)數(shù)釋然代價(jià)函數(shù)(log-likelihood cost)
- 對(duì)數(shù)釋然函數(shù)常用來(lái)作為softmax回歸的代價(jià)函數(shù),然后輸出層神經(jīng)元是sigmoid函數(shù)捞蛋,可以采用交叉熵代價(jià)函數(shù)孝冒。而深度學(xué)習(xí)中更普遍的做法是將softmax作為最后一層,此時(shí)常用的代價(jià)函數(shù)是對(duì)數(shù)釋然代價(jià)函數(shù)拟杉。
- 對(duì)數(shù)似然代價(jià)函數(shù)與softmax的組合和交叉熵與sigmoid函數(shù)的組合非常相似庄涡。對(duì)數(shù)釋然代價(jià)函數(shù)在二分類(lèi)時(shí)可以化簡(jiǎn)為交叉熵代價(jià)函數(shù)的形式。
在tensorflow中用:
tf.nn.sigmoid_cross_entropy_with_logits()來(lái)表示跟sigmoid搭配使用的交叉熵搬设。
tf.nn.softmax_cross_entropy_with_logits()來(lái)表示跟softmax搭配使用的交叉熵穴店。
使用TensorFlow比較兩種代價(jià)函數(shù)的效果
以上一篇文章手寫(xiě)數(shù)字識(shí)別的模型為例子,在這給出采用交叉熵函數(shù)的模型的代碼:
import datetime
# 4.1 交叉熵代價(jià)函數(shù)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
start = datetime.datetime.now()
# 載入數(shù)據(jù)
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
# 每個(gè)批次的大小
batch_size = 50
# 計(jì)算一共有多少個(gè)批次
n_batch = mnist.train.num_examples // batch_size
# 定義兩個(gè)placeholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
# 創(chuàng)建一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x, W)+b)
# 二次代價(jià)函數(shù)
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代價(jià)函數(shù)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 初始化變量
init = tf.global_variables_initializer()
# 結(jié)果存放在一個(gè)布爾型列表中
# argmax返回一維張量中最大的值所在的位置
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
# 求準(zhǔn)確率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(30):
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})
acc = sess.run(accuracy, feed_dict={
x: mnist.test.images, y: mnist.test.labels})
print("Iter "+str(epoch)+",Testing Accuracy "+str(acc))
end = datetime.datetime.now()
print((end-start).seconds)
在這里我們將二次代價(jià)函數(shù)更改為了交叉熵代價(jià)函數(shù):
# 二次代價(jià)函數(shù)
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代價(jià)函數(shù)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
接下來(lái)我們來(lái)對(duì)比下訓(xùn)練的結(jié)果:
由上圖可知拿穴,使用二次代價(jià)函數(shù)訓(xùn)練第10次的精確度為0.9063泣洞,而使用交叉熵代價(jià)函數(shù)訓(xùn)練到第2次的精確度就已經(jīng)超過(guò)0.9了,結(jié)果顯而易見(jiàn)默色。
擬合
擬合分為三種:1.欠擬合(underfitting)球凰;2. 正確擬合(just right);3. 過(guò)擬合(overfitting)该窗;如下圖所示:
其中每個(gè)
x
表示的是樣本弟蚀,每條曲線代表的是模型。下圖是分類(lèi)問(wèn)題中的擬合情況酗失,和上述情況類(lèi)似义钉。
在這里介紹過(guò)擬合,下面是wikipedia對(duì)于overfitting的解釋规肴。
在統(tǒng)計(jì)學(xué)和機(jī)器學(xué)習(xí)中捶闸,overfitting一般在描述統(tǒng)計(jì)學(xué)模型隨機(jī)誤差或噪音時(shí)用到。它通常發(fā)生在模型過(guò)于復(fù)雜的情況下拖刃,如參數(shù)過(guò)多等删壮。overfitting會(huì)使得模型的預(yù)測(cè)性能變?nèi)酰⑶以黾訑?shù)據(jù)的波動(dòng)性兑牡。
發(fā)生overfitting是因?yàn)樵u(píng)判訓(xùn)練模型的標(biāo)準(zhǔn)不適用于作為評(píng)判該模型好壞的標(biāo)準(zhǔn)央碟,模型通常會(huì)增強(qiáng)模型在訓(xùn)練模型的預(yù)測(cè)性能。但是模型的性能并不是由模型在訓(xùn)練集的表現(xiàn)好壞而決定均函,它是由模型在未知數(shù)據(jù)集上的表現(xiàn)確定的亿虽。當(dāng)模型開(kāi)始“memorize”訓(xùn)練數(shù)據(jù)而不是從訓(xùn)練數(shù)據(jù)中“l(fā)earning”時(shí),overfitting就出現(xiàn)了苞也。比如洛勉,如果模型的parameters大于或等于觀測(cè)值的個(gè)數(shù),這種模型會(huì)顯得過(guò)于簡(jiǎn)單如迟,雖然模型在訓(xùn)練時(shí)的效果可以表現(xiàn)的很完美收毫,基本上記住了數(shù)據(jù)的全部特點(diǎn)攻走,但這種模型在未知數(shù)據(jù)的表現(xiàn)能力會(huì)大減折扣,因?yàn)楹?jiǎn)單的模型泛化能力通常都是很弱的此再。
上面這個(gè)圖昔搂,是通過(guò)線性函數(shù)和多項(xiàng)式函數(shù)來(lái)擬合這些數(shù)據(jù)點(diǎn),顯然多項(xiàng)式函數(shù)擬合效果很完美引润,包含了所有的點(diǎn)巩趁,而線性函數(shù)丟失了大部分點(diǎn)。但實(shí)際上淳附,線性函數(shù)有一個(gè)很好的泛化能力议慰,如果用這些點(diǎn)來(lái)做一個(gè)回歸線,多項(xiàng)式函數(shù)過(guò)擬合的情況更糟糕奴曙。
過(guò)擬合不僅和參數(shù)的個(gè)數(shù)以及數(shù)據(jù)有關(guān)别凹,也和數(shù)據(jù)形狀模型結(jié)構(gòu)的一致性有關(guān)。
為了避免過(guò)擬合洽糟,有必要使用一些額外的技術(shù)(如交叉驗(yàn)證炉菲、正則化、early stopping坤溃、貝斯信息量準(zhǔn)則拍霜、赤池信息量準(zhǔn)則或model comparison),以指出何時(shí)會(huì)有更多訓(xùn)練而沒(méi)有導(dǎo)致更好的一般化薪介。
Overfitting的概念在機(jī)器學(xué)習(xí)中很重要祠饺。通常一個(gè)學(xué)習(xí)算法是借由訓(xùn)練樣本來(lái)訓(xùn)練的,在訓(xùn)練時(shí)會(huì)伴隨著訓(xùn)練誤差汁政。當(dāng)把該模型用到未知數(shù)據(jù)的測(cè)試時(shí)道偷,就會(huì)相應(yīng)的帶來(lái)一個(gè)validation error。下面通過(guò)訓(xùn)練誤差和驗(yàn)證誤差來(lái)詳細(xì)分析一下overfitting记劈。如下圖:
在上圖總勺鸦,藍(lán)色表示訓(xùn)練誤差training error,紅色表示validation error目木。當(dāng)訓(xùn)練誤差達(dá)到中間的那條垂直線的點(diǎn)時(shí)换途,模型應(yīng)該是最優(yōu)的,如果繼續(xù)減少模型的訓(xùn)練誤差刽射,這時(shí)就會(huì)發(fā)生過(guò)擬合军拟。
其實(shí)你可以這樣來(lái)理解overfitting:數(shù)據(jù)集中信息分為兩部分,一部分是和預(yù)測(cè)未來(lái)數(shù)據(jù)有關(guān)的數(shù)據(jù)柄冲,另一部分是無(wú)關(guān)的,兩者地位是平等的忠蝗。用來(lái)作為預(yù)測(cè)的評(píng)判標(biāo)準(zhǔn)越不精確现横,表明噪聲數(shù)據(jù)就越多,需要忽略掉的數(shù)據(jù)也就越多,而關(guān)鍵就是究竟那一部分應(yīng)該忽略掉戒祠。所以我們把一個(gè)學(xué)習(xí)算法對(duì)噪聲的削減能力就叫做它的魯棒性骇两。我們需要的就是魯棒性很強(qiáng)的學(xué)習(xí)算法
舉一個(gè)簡(jiǎn)單的例子,一個(gè)零售購(gòu)物的數(shù)據(jù)庫(kù)包括購(gòu)買(mǎi)項(xiàng)姜盈、購(gòu)買(mǎi)人低千、日期、和購(gòu)買(mǎi)時(shí)間馏颂。根據(jù)這個(gè)數(shù)據(jù)可以很容易的建立一個(gè)模型示血,并且在訓(xùn)練集上的擬合效果也會(huì)很好,通過(guò)使用日期救拉、購(gòu)買(mǎi)時(shí)間來(lái)預(yù)測(cè)其它屬性列的值难审,但是這個(gè)模型對(duì)于新數(shù)據(jù)的泛化能力很弱,因?yàn)檫@些過(guò)去的數(shù)據(jù)不會(huì)再次發(fā)生亿絮。
防止過(guò)擬合的幾種方式
這里推薦閱讀機(jī)器學(xué)習(xí)中用來(lái)防止過(guò)擬合的方法有哪些告喊?,說(shuō)的比較詳細(xì)派昧。
- 增加數(shù)據(jù)集
你的模型可以存儲(chǔ)很多很多的信息黔姜,這意味著你輸入模型的訓(xùn)練數(shù)據(jù)越多,模型就越不可能發(fā)生過(guò)擬合蒂萎。原因是隨著你添加更多數(shù)據(jù)秆吵,模型會(huì)無(wú)法過(guò)擬合所有的數(shù)據(jù)樣本,被迫產(chǎn)生泛化以取得進(jìn)步岖是。 收集更多的數(shù)據(jù)樣本應(yīng)該是所有數(shù)據(jù)科學(xué)任務(wù)的第一步帮毁,數(shù)據(jù)越多會(huì)讓模型的準(zhǔn)確率更高,這樣也就能降低發(fā)生過(guò)擬合的概率豺撑。
- 正則化方法
正則化是指約束模型的學(xué)習(xí)以減少過(guò)擬合的過(guò)程烈疚。它可以有多種形式,推薦閱讀機(jī)器學(xué)習(xí)中用來(lái)防止過(guò)擬合的方法有哪些聪轿?爷肝,說(shuō)的比較詳細(xì)。 -
Dropout
由于深度學(xué)習(xí)依賴神經(jīng)網(wǎng)絡(luò)處理從一個(gè)層到下一個(gè)層的信息陆错,因而從這兩方面著手比較有效灯抛。其理念就是在訓(xùn)練中隨機(jī)讓神經(jīng)元無(wú)效(即dropout)或讓網(wǎng)絡(luò)中的連接無(wú)效(即dropconnect)。
droppout
這樣就讓神經(jīng)網(wǎng)絡(luò)變得冗長(zhǎng)和重復(fù)音瓷,因?yàn)樗鼰o(wú)法再依賴具體的神經(jīng)元或連接來(lái)提取具體的特征对嚼。等完成模型訓(xùn)練后,所有的神經(jīng)元和連接會(huì)被保存下來(lái)绳慎。試驗(yàn)顯示這種方法能起到和神經(jīng)網(wǎng)絡(luò)集成方法一樣的效果纵竖,可以幫助模型泛化漠烧,這樣就能減少過(guò)擬合的問(wèn)題。
我們來(lái)用代碼體驗(yàn)下dropout:
import datetime
# 4.2 Dropout
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
start = datetime.datetime.now()
# 載入數(shù)據(jù)
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
# 每個(gè)批次的大小
batch_size = 50
# 計(jì)算一共有多少個(gè)批次
n_batch = mnist.train.num_examples // batch_size
# 定義兩個(gè)placeholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
# 創(chuàng)建一個(gè)神經(jīng)網(wǎng)絡(luò)
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)
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)
# 二次代價(jià)函數(shù)
# loss = tf.reduce_mean(tf.square(y-prediction))
# 交叉熵代價(jià)函數(shù)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
labels=y, logits=prediction))
# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 初始化變量
init = tf.global_variables_initializer()
# 結(jié)果存放在一個(gè)布爾型列表中
# argmax返回一維張量中最大的值所在的位置
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
# 求準(zhǔn)確率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(20):
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))
end = datetime.datetime.now()
print((end-start).seconds)
相較于之前的代碼我們更改了以下一些地方:
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)
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)
我額外的為神經(jīng)網(wǎng)絡(luò)添加了兩個(gè)隱藏層靡砌,為了方便體現(xiàn)出差異已脓,我將每個(gè)隱藏層的神經(jīng)元數(shù)量設(shè)置的比較多。
然后在訓(xùn)練過(guò)程中通殃,
for epoch in range(10):
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))
其中keep_prob
表示啟用神經(jīng)元占神經(jīng)元總數(shù)的百分比(1.0表示全部使用)度液,train_acc
表示用訓(xùn)練樣本來(lái)測(cè)試訓(xùn)練出來(lái)的模型的精確度,test_acc
表示用測(cè)試樣本來(lái)測(cè)試訓(xùn)練出來(lái)的模型的精確度画舌,用這兩個(gè)數(shù)據(jù)來(lái)反映出擬合程度堕担。訓(xùn)練結(jié)果如下圖所示:
在這里我們總共就訓(xùn)練了10次,而且數(shù)據(jù)量并不大骗炉,此時(shí)test_acc和train_acc就已經(jīng)差了兩個(gè)百分點(diǎn)照宝,如果應(yīng)用到其他項(xiàng)目中,數(shù)據(jù)量變大之后就不是2個(gè)百分點(diǎn)的事情了句葵,所以說(shuō)如果神經(jīng)元數(shù)量過(guò)多是會(huì)造成過(guò)度擬合的厕鹃。
總結(jié)
在本文中為了提高精確度,引入了代價(jià)函數(shù)這個(gè)概念乍丈,為了更好的理解代價(jià)函數(shù)因此提前介紹了什么是激活函數(shù)以及為什么需要激活函數(shù)剂碴。在只用一層神經(jīng)網(wǎng)絡(luò)的時(shí)候通過(guò)更改代價(jià)函數(shù),我們可以使精確度達(dá)到93%左右(訓(xùn)練次數(shù)較多時(shí))轻专,但這還是不夠忆矛,所以我們嘗試多添加幾層神經(jīng)元,但是這時(shí)候就會(huì)出現(xiàn)“過(guò)擬合”這個(gè)新的問(wèn)題了请垛,通常有三種方式解決過(guò)擬合的問(wèn)題催训。之后的文章將會(huì)在此基礎(chǔ)上介紹以下優(yōu)化器,并且告知大家如何使用谷歌免費(fèi)的GPU服務(wù)加速深度學(xué)習(xí)的模型訓(xùn)練宗收。