這篇將使用 tensorflow 去實踐深度學習,
並做一個數字辨識的入門小專案。
------------------------------------------------------------------------------------------------------------
一、深度學習的工具介紹及安裝
現在我們知道,在架構一個神經網路時,矩陣運算能力是很重要的,
但不要害怕,已經有許多套件可以幫助我們加速架設神經網路的過程,
我大概列一下我知道的幾個。
1. Theano - 有支援 Windows!第二推薦!
2. Keras - 算是在 Theano and Tensorflow 這種基礎之上的 API
3. Tensorflow - 最推薦!
我自己只有用過 Theano 和 Tensorflow,
對我來說呢,Tensorflow 對於深度學習的架構更加完整,學起來更快,
很多複雜的架構只需一行程式碼就可以寫出來,
所以我就決定分享 Tensorflow 給剛進入的大家。
Tensorflow 也是 Google 人工智慧部門釋出的開源碼,
他們自己長期也是使用這一套,所以應該是滿厲害的!
關於安裝 Tensorflow 呢,
Mac / Ubuntu 安裝是非常的迅速的,
Windows 系統就要用 docker 或是 virtualenv 去跑,
##############################################
我自己是在 Windows 上安裝 VirtualBox,再在上面安裝 Ubuntu。
不要覺得為了 tf 安裝一個 OS 很蠢,Ubuntu 到時可以拿來練習 Hadoop/Spark。
##############################################
##############################################
我自己是在 Windows 上安裝 VirtualBox,再在上面安裝 Ubuntu。
不要覺得為了 tf 安裝一個 OS 很蠢,Ubuntu 到時可以拿來練習 Hadoop/Spark。
##############################################
網頁裡面都有很詳盡的介紹,因為我覺得安裝很乏味,就麻煩大家自己安裝了。
如果已經安裝好了!
那恭喜,你離架設第一套自己的深度學習模型只差一百行了!
------------------------------------------------------------------------------------------------------------
二、深度學習數字預測小專案
現在我們進行第一個練習,讓機器學習判讀數字,
給機器一張圖片,讓他告訴我們這 0~9 數字幾。
好,一樣建立一個新的文字檔叫做 dl_neural_network.py
裡面輸入以下
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import numpy as np
mnist = input_data.read_data_sets('/tmp/data', one_hot = True)
train_x = mnist.train.images
train_x_pic = np.reshape(train_x[1], (28, 28))
plt.imshow(train_x_pic)
plt.show()
稍微講一下 mnist 是什麼,
mnist 是 TF 給大家練習的資料庫,有 training data 55000 組,test data 10000 組,
data 內容是一堆 28*28 pixel 的 0 ~ 9 數字圖片,所以執行以上程式碼,我們可以看到這個,
這是數字 3,上面的程式碼只是為了讓大家看一下我們在使用什麼資料,
看完就可以把第七行以下的程式碼 comment out。
現在要開始寫我們的深度學習模型了!
------------------------------------------------------------------------------------------------------------
三、定義神經層
寫之前呢,先構思一下我們寫這神經網路的邏輯,
回顧上一集的重點,
深度學習 = 最佳化 ( Cost )
Cost = Best - ( input * neural * neural * neural )
neural = array * activation function
我們首先定義多個矩陣和矩陣的運算來實現神經網路,
寫完神經網路後,我們要再寫一串程式碼來最佳化這套神經網路,
然後就大功告成了!開始!
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import numpy as np
mnist = input_data.read_data_sets('/tmp/data', one_hot = True)
# 以下三個是我們提前定義三個隱藏層,且每個隱藏層都有 500 個節點。
n_nodes_hl1 = 500
n_nodes_hl2 = 500
n_nodes_hl3 = 500
# n_classes 是指我們最後 output 的維度,那因為我們有 0~9 十個數字,所以是 10。
n_classes = 10
# batch_size 指的是我們訓練資料時,一次要取多少組 Data,這跟上一章講到的隨機最佳化有關。
batch_size = 100
# x 是我們要輸入的矩陣,y 是我們的輸出。這邊提前定義,是 TF 本身的玩法。
# 圖片是 28*28 pixel,我們藉由[None, 784],把他變成 784*1 的一維矩陣,
# 那因為每一個值都還保留,所以這樣的矩陣變形沒有失真問題。(CNN則不然)
x = tf.placeholder('float',[None, 784])
y = tf.placeholder('float')
好,這邊有點複雜,但千萬不要卡在這裡,這只是提前定義神經網路的長相而已,
等看完全部程式碼,再回來細細咀嚼每一解釋,就會更清楚。
再以下繼續加入以下程式碼,
# 這邊我們寫一個方法,把神經網路中每一層定義完整,
# 並且定義出矩陣運算以及每層間是否要 activation function
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]))}
# 這邊定義每一層之間的矩陣運算 (
matmul) l1 = tf.add(tf.matmul(data, hidden_1_layer['weights']), hidden_1_layer['biases'])
# 這邊加上 Relu function -> 大於 0 就線性轉換,小於 0 就等於 0。
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
hidden_1_layer =
{'weights':tf.Variable(tf.random_normal([784,n_nodes_hl1])),
'biases':tf.Variable(tf.random_normal([n_nodes_hl1]))}
為什麼這個東西就是一個神經層呢?
讓我們回顧一個最簡單線性方程式的長相,
y = ax + b ( y, a, x, b 都是純量)
那如果把它變成廣義維度的運算就是,
y = Ax + b ( y, x, b 都是一維向量,A 則是一個二維矩陣)
* 方便理解才這樣假設,y A x b 可以是任意維度任意大小的向量,只要可以運算即可。
hidden layer 中的 weights 就是 A,而 biases 就是 b,
藉由 tf.Variable 定義一個變數,藉由 tf.random_normal 定義變數初始化的數值。
可以發現,下方矩陣運算,
l1 = tf.add(tf.matmul(data, hidden_1_layer['weights']), hidden_1_layer['biases'])
就是 y = Ax + b 這一條式子。
( data * hidden_1_layer['weights'] + hidden_1_layer['biases'] = l1 )
------------------------------------------------------------------------------------------------------------
四、最佳化神經網路
理解完神經網路長相是怎麼實現後,
只差最佳化神經網路的方法了。
在程式碼底下繼續,
def train_neural_network(x):
# 呼叫經過神經網路後的 output 命名為 prediction
prediction = neural_network_model(x)
# 將標準答案與 prediction 比較算出 cost
cost = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(prediction,y))
# 層層修正回去的演算法,除了 AdamOptimizer 以外還是有很多的
optimizer = tf.train.AdamOptimizer().minimize(cost)
# 這個就是我們要走幾次輪迴來學習
hm_epochs = 10
# 這是 TF 特別的地方,把要做的事情放到 session 裡面,在一起開始。
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
# 這邊程式碼比較單純,就是把資料切成 batch 的大小,並將 cost 累計起來。
for epoch in range(hm_epochs):
epoch_loss = 0
for _ in range(int(mnist.train.num_examples/batch_size)):
epoch_x, epoch_y = mnist.train.next_batch(batch_size)
_, c = sess.run([optimizer,cost], feed_dict = {x: epoch_x, y: epoch_y})
epoch_loss += c
print ('Epoch', epoch, 'completed out of', hm_epochs, 'loss:', epoch_loss)
correct = tf.equal(tf.argmax(prediction,1), tf.argmax(y,1))
# 經過 10 個 epochs 後計算出 accuracy
accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print ('Accuracy:' ,accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))
train_neural_network(x)
完成了!!!!
讓我們來跑跑看這短短的幾行程式碼,在判別 0~9 數字時能有多少準確率吧!
在終端機輸入
python dl_neural_network.py
等待個幾分鐘,應該就可以看到以下結果!
在經歷過 10 次 epochs 的訓練後,
機器可以用 0.95 的準確率判定 0~9 的數字,
這代表什麼意思呢?
代表你可以把這套機器包起來,
寫成自動判讀登入頁面上惱人的數字驗證碼,
這樣寫爬蟲的時候,又多克服一個小難關摟~~
這邊附上官方的開源碼 :) Link
和我的有一點不一樣,但想法大同小異!
好!就這樣,基本的神經網路和數字練習,已經完成。
0.95 其實算是中庸表現,在後面 RNN 和 CNN 都可以輕易的達到 0.99 的準確率,
期待一下吧!
------------------------------------------------------------------------------------------------------------
Reference
[1] Practical Machine Learning Problem
[2] 圖解機器學習
[3] Coursera - Machine Leanring
[4] A tour of machine learning algorithms
您好 因為圖片失聯了 很像看看結果如何
回覆刪除可以麻煩您補一下圖片嗎 不好意思
我看沒有失聯啊 你說 每一個 epoch 跑完的結果?
刪除每個隱藏層都有 500 個節點 為何是500?
回覆刪除沒有一定要是 500 哦!這邊只是決定矩陣的大小,也就是神經網路的複雜度或說是要給這套演算法的自由度。
刪除為何不用Keras? 他好像有window version.
回覆刪除想要請教一下
回覆刪除最近在也是在做這個 但是對隱藏層有個疑問
如下網址
https://chtseng.wordpress.com/2017/07/31/neural-networks-%E4%BA%8C-keras-mnist/
輸入層是28*28=784
輸出是0-9有十種,所以是10
那隱藏層256怎麼出來的@@??
有大概要給多少 還是有計算公式呢?
謝謝
我自己的解讀是,一切取決於你要給這個演算法多少自由度, 你要 255 應該也是沒啥差,只要矩陣有辦法運算就可以。
刪除但有時候自由度給太高就會有 overfitting 的可能性。