我們首先使用 MNIST 數(shù)據(jù)集泉褐,該數(shù)據(jù)集包含 6 萬個手寫和標記數(shù)字訓練樣本和 10,000 個的測試樣本,0 到 9鸟蜡,因此共有 10 個“分類”膜赃。 我會注意到,這是一個非常小的數(shù)據(jù)集揉忘,就你在任何現(xiàn)實環(huán)境中的工作而言跳座,它也應該足夠小到在每個人的電腦上工作端铛。
MNIST 數(shù)據(jù)集具有圖像,我們將使用純粹的黑色和白色疲眷,閾值禾蚕,圖像,總共 28×28 或 784 像素狂丝。 我們的特征是每個像素的像素值换淆,閾值。 像素是“空白”(沒有什么几颜,0)倍试,或有東西(1)。 這些是我們的特征蛋哭。 我們嘗試使用這個非诚叵埃基本的數(shù)據(jù),并預測我們正在查看的數(shù)字(0 ~ 9)谆趾。 我們希望我們的神經(jīng)網(wǎng)絡躁愿,將以某種方式創(chuàng)建像素之間的關(guān)系的內(nèi)在模型,并且能夠查看數(shù)字的新樣例棺妓,并且高準確度預測攘已。
雖然這里的代碼不會那么長,但如果你不完全了解應該發(fā)生的事情怜跑,那么我們可以嘗試凝結(jié)我們迄今為止所學到的知識样勃,以及我們在這里會做什么。
首先性芬,我們傳入輸入數(shù)據(jù)峡眶,并將其發(fā)送到隱藏層1。因此植锉,我們對輸入數(shù)據(jù)加權(quán)辫樱,并將其發(fā)送到層1。在那里將經(jīng)歷激活函數(shù)俊庇,因此神經(jīng)元可以決定是否觸發(fā)狮暑,并將一些數(shù)據(jù)輸出到輸出層或另一個隱藏層。在這個例子中辉饱,我們有三個隱藏層搬男,使之成為深度神經(jīng)網(wǎng)絡。從我們得到的輸出中彭沼,我們將該輸出與預期輸出進行比較缔逛。我們使用成本函數(shù)(或稱為損失函數(shù))來確定我們的正確率。最后,我們將使用優(yōu)化器函數(shù)褐奴,Adam Optimizer按脚。在這種情況下,最小化損失(我們有多錯誤)敦冬。成本最小化的方法是通過修改權(quán)重辅搬,目的是希望降低損失。我們要降低損失的速度由學習率決定脖旱。學習率越低伞辛,我們學習的速度越慢,我們越有可能獲得更好的結(jié)果夯缺。學習率越高,我們學習越快甘耿,訓練時間更短踊兜,也可能會受到影響。當然佳恬,這里的收益遞減捏境,你不能只是繼續(xù)降低學習率,并且總是做得更好毁葱。
通過我們的網(wǎng)絡直接發(fā)送數(shù)據(jù)的行為垫言,意味著我們正在運行前饋神經(jīng)網(wǎng)絡。 向后調(diào)整權(quán)重是我們的反向傳播倾剿。
我們這樣做是向前和向后傳播筷频,但我們想要多次。 這個周期被稱為一個迭代(epoch)前痘。 我們可以選擇任何數(shù)量的迭代凛捏,但你可能想要避免太多,這會導致過擬合芹缔。
在每個時代之后坯癣,我們希望進一步調(diào)整我們的權(quán)重,降低損失和提高準確性最欠。 當我們完成所有的迭代示罗,我們可以使用測試集進行測試。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot = True)
我們導入 TensorFlow 和我們將要使用的樣本數(shù)據(jù)芝硬。 請注意one_hot
參數(shù)蚜点。 這個術(shù)語來自只有一個元素的點子,在其余元素當中吵取,字面上是“熱”的禽额,或者開啟的。 這對于我們這里的多類分類任務是有用的(0 ~ 9)。 因此脯倒,不是簡單的 0 或者 1实辑,我們擁有:
0 = [1,0,0,0,0,0,0,0,0]
1 = [0,1,0,0,0,0,0,0,0]
2 = [0,0,1,0,0,0,0,0,0]
3 = [0,0,0,1,0,0,0,0,0]
...
好的,所以我們有了數(shù)據(jù)藻丢。 我選擇使用 MNIST 數(shù)據(jù)集剪撬,因為它是一個合適的起始數(shù)據(jù)集,實際上悠反,收集原始數(shù)據(jù)并將其轉(zhuǎn)換為可以使用的東西残黑,比創(chuàng)建機器學習模型本身需要更多的時間,我認為這里大多數(shù)人都想學習 神經(jīng)網(wǎng)絡斋否,而不是網(wǎng)頁抓取和正則表達式梨水。
現(xiàn)在我們要開始構(gòu)建模型:
n_nodes_hl1 = 500
n_nodes_hl2 = 500
n_nodes_hl3 = 500
n_classes = 10
batch_size = 100
我們首先指定每個隱藏層將有多少個節(jié)點,我們的數(shù)據(jù)集有多少份額里茵臭,以及我們的批量大小疫诽。 雖然你理論上可以一次訓練整個網(wǎng)絡,這是不切實際的旦委。 你們中的許多人可能有可以完全處理 MNIST 數(shù)據(jù)集的計算機奇徒,但是大多數(shù)人都沒有或可以訪問這種計算機,它們可以一次完成實際大小的數(shù)據(jù)集缨硝。 因此摩钙,我們進行批量優(yōu)化。 在這種情況下查辩,我們進行 100 個批次胖笛。
x = tf.placeholder('float', [None, 784])
y = tf.placeholder('float')
這些是我們圖中某些值的占位符。 回想一下宜肉,你只需在 TensorFlow 圖中構(gòu)建模型即可匀钧。 在這里,TensorFlow 操縱一切谬返,而你不會之斯。 一旦完成,這將更加明顯遣铝,你嘗試尋找在哪里修改重量佑刷! 請注意,我已經(jīng)使用[None,784]
作為第一個占位符中的第二個參數(shù)酿炸。 這是一個可選參數(shù)瘫絮,然而這樣顯式指定非常有用。 如果你不顯式指定填硕,TensorFlow 會在那里填充任何東西麦萤。 如果你的形狀是顯式的鹿鳖,并且一些不同形狀的東西嘗試放進這個變量的地方,TensorFlow 將拋出一個錯誤壮莹。
我們現(xiàn)在完成了我們的常量以及其實值〕嶂模現(xiàn)在我們可以實際構(gòu)建神經(jīng)網(wǎng)絡模型了:
def neural_network_model(data):
hidden_1_layer = {'weights':tf.Variable(tf.random_normal([784, n_nodes_hl1])),
'biases':tf.Variable(tf.random_normal([n_nodes_hl1]))}
hidden_2_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])),
'biases':tf.Variable(tf.random_normal([n_nodes_hl2]))}
hidden_3_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])),
'biases':tf.Variable(tf.random_normal([n_nodes_hl3]))}
output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl3, n_classes])),
'biases':tf.Variable(tf.random_normal([n_classes]))}
這里,我們開始定義我們的權(quán)重和我們的...等等命满,這些偏差是什么涝滴? 偏差是在通過激活函數(shù)之前,與我們的相加的值胶台,不要與偏差節(jié)點混淆歼疮,偏差節(jié)點只是一個總是存在的節(jié)點。 這里的偏差的目的主要是诈唬,處理所有神經(jīng)元生成 0 的情況韩脏。 偏差使得神經(jīng)元仍然能夠從該層中觸發(fā)。 偏差與權(quán)重一樣獨特铸磅,也需要優(yōu)化骤素。
我們迄今所做的一切都是為我們的權(quán)重和偏差創(chuàng)建一個起始定義。 對于層的矩陣的應有形狀愚屁,這些定義只是隨機值(這是tf.random_normal
為我們做的事情,它為我們輸出符合形狀的隨機值)痕檬。 還沒有發(fā)生任何事情霎槐,沒有發(fā)生流動(前饋)。我們開始流程:
l1 = tf.add(tf.matmul(data,hidden_1_layer['weights']), hidden_1_layer['biases'])
l1 = tf.nn.relu(l1)
l2 = tf.add(tf.matmul(l1,hidden_2_layer['weights']), hidden_2_layer['biases'])
l2 = tf.nn.relu(l2)
l3 = tf.add(tf.matmul(l2,hidden_3_layer['weights']), hidden_3_layer['biases'])
l3 = tf.nn.relu(l3)
output = tf.matmul(l3,output_layer['weights']) + output_layer['biases']
return output
在這里梦谜,我們將值傳入第一層丘跌。 這些值是什么? 它們是原始輸入數(shù)據(jù)乘以其唯一權(quán)重(從隨機開始唁桩,但將被優(yōu)化):tf.matmul(l1,hidden_2_layer['weights'])
闭树。 然后,我們添加了tf.add
的偏差荒澡。 我們對每個隱藏層重復這個過程报辱,直到我們的輸出,我們的最終值仍然是輸入和權(quán)重的乘積单山,加上輸出層的偏差值碍现。
完成后,我們只需返回該輸出層米奸。 所以現(xiàn)在昼接,我們已經(jīng)構(gòu)建了網(wǎng)絡,幾乎完成了整個計算圖形悴晰。 在下一個教程中慢睡,我們將構(gòu)建一個函數(shù)逐工,使用 TensorFlow 實際運行并訓練網(wǎng)絡。