上篇文章簡要介紹了「深度學習」例证,接下來迷捧,我們將從最經(jīng)典的例子入手進行實戰(zhàn)漠秋。
一庆锦、背景知識簡介
1 TensorFlow
Tensor:張量(即多維數(shù)組),F(xiàn)low:(數(shù)據(jù))流
TensorFlow艇搀,是一個使用數(shù)據(jù)流圖(data flow graohs)技術來進行科學計算的開源軟件庫焰雕,它由Google Brain 團隊開發(fā)芳杏,被廣泛應用于各種感知和語言理解任務的機器學習爵赵。
點擊訪問:TensorFlow 官網(wǎng)空幻,可以查閱官方文檔、獲取一手資訊和下載最新版本约郁。
或者訪問:GitHub - tensorflow 來達到同樣的效果
英文閱讀有困難的同學參考:TensorFlow 中文文檔
在本次實戰(zhàn)中我們還將使用 Keras棍现,它是一個基于 Theano(另一個開源庫)和 TensorFlow 構建的高級神經(jīng)網(wǎng)絡 API己肮,能夠在 Theano、TensorFlow 或 Microsoft Cognitive Toolkit 上運行娄柳。
點擊訪問:Keras 中文文檔
2 MNIST 數(shù)據(jù)集
在上篇文章中我們已經(jīng)提到過 MNIST 了赤拒,它是一個收錄了許多 28 x 28 像素手寫數(shù)字圖片(以灰度值矩陣存儲)及其對應的數(shù)字的數(shù)據(jù)集挎挖,可以把它理解成下圖這個樣子:
圖片來源:3Blue1Brown 的視頻蕉朵,強烈推薦觀看系列視頻:B 站播放地址
二始衅、Python 實現(xiàn)
這里我們依舊使用 Jupyter Notebook 作為開發(fā)環(huán)境缭保,沒有使用過的同學參考我的文章「機器學習入坑指南(一):Python 環(huán)境搭建」艺骂。
當然彻亲,使用 Pycharm 等 IDE 也沒有問題。
1 安裝并導入 TensorFlow、Keras
在 Anaconda 終端中輸入命令
conda install tf-nightly
或輸入(Python Shell 中也可以使用此命令)
pip install tf-nightly
Keras 已經(jīng)被集成進了 TensorFlow 中宙址。我們可以通過 tensorflow.keras
來訪問它抡砂。
接下來,導入這兩個庫
import tensorflow.keras as keras
import tensorflow as tf
可以通過簡單的代碼測試導入是否成功
print(tf.__version__)
2 導入并測試 MNIST 數(shù)據(jù)集
Keras 默認從 googleapis 下載 MNIST,如果無法訪問厦瓢,可在 GitHub 上下載啤月,點擊這里谎仲,下載到本地后更改 mnist.py
中的引用路徑郑诺。
TensorFlow 中存在多個 mnist.py
,這里我們需要修改的是 Keras 下的辙售,我的路徑為
C:\ProgramData\Anaconda3\Lib\site-packages\tensorflow\python\keras\datasets
打開之后圾亏,把
origin_folder = 'https://storage.googleapis.com/tensorflow/tf-keras-datasets/'
中的路徑修改為你存放數(shù)據(jù)集的位置即可志鹃。進入正題
mnist = tf.keras.datasets.mnist #導入mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data() #分割
print(x_train[0]) # 查看第一個測試數(shù)據(jù)的輸入
然后你就看到了如下的輸出:
讓我們把這個矩陣用圖像表示出來
import matplotlib.pyplot as plt
%matplotlib inline # 加上這句才能顯示圖像
plt.imshow(x_train[0],cmap=plt.cm.binary) # 顯示黑白圖像
plt.show()
可以通過以下代碼對數(shù)據(jù)進行歸一化處理
x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)
再次查看圖像
plt.imshow(x_train[0],cmap=plt.cm.binary)
plt.show()
圖像的像素值被限定在了 [0,1] 捧杉。可以通過
print(x_train[0])
查看矩陣數(shù)據(jù)评甜。
3 構建與訓練模型
終于進入核心環(huán)節(jié)了忍坷。在這里,我們使用 Keras 的 Sequential 模型(順序模型)柑肴。Sequential 模型是最常用的模型晰骑,也就是一個按照順序向前傳遞的神經(jīng)網(wǎng)絡硕舆。
model = tf.keras.models.Sequential()
接下來為模型添加圖層政模。神經(jīng)網(wǎng)絡的輸入層是一個一維向量,所以我們需要把輸入的圖像矩陣展平淋样,從 28 x 28 變?yōu)?1 x 784 趁猴。Keras 為我們提供了如下方法:
model.add(tf.keras.layers.Flatten())
之后,為神經(jīng)網(wǎng)絡添加隱藏層娱挨。這里我們使用最簡單的 Dense 層(即全連接層跷坝,每一個神經(jīng)元與前后兩層的所有神經(jīng)元相連)
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
這個層有 128 個單元柴钻,激活函數(shù)選擇 reLU垢粮,最初人們喜歡用 Sigmoid 函數(shù)蜡吧,但后來發(fā)現(xiàn) reLU 效果更好昔善,所以可以當做一個默認的選擇。
接下來再加入一個相同的層
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
再加入輸出層
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))
輸出層有 10 個結點柬批,代表 10 種不同的數(shù)字氮帐。這里使用 softmax 函數(shù)作為激活函數(shù)上沐,因為我們想要找到預測結果的概率分布参咙。(使用 reLU 得到的數(shù)字并沒有這個意義)
我們構建出的模型大概是這個樣子的(示意圖來自 3Blue1Brown,隱藏層只有 16 個單元硫眯,實際上我們有 128 個)
添加好所有的層后蕴侧,“編譯”這個模型。
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
optimizer 即優(yōu)化器两入,我們一般默認使用 adam
净宵。
loss 指損失函數(shù),這里我們將其指定為 sparse_categorical_crossentropy
裹纳,即計算分類結果的交叉熵損失择葡。
metrics 列表,參數(shù)為評估模型性能的指標剃氧,典型用法即 metrics=['accuracy']
最后,擬合這個模型
model.fit(x_train, y_train, epochs=3)
在訓練的過程中朋鞍,我們會發(fā)現(xiàn)損失值(loss)在降低已添,而準確度(accuracy)在提高,最后達到了一個令人滿意的程度滥酥。
4 測試模型
讓我們利用測試集試試這個模型是不是真的學會了識別數(shù)字
val_loss, val_acc = model.evaluate(x_test, y_test)
print(val_loss)
print(val_acc)
損失和準確度看起來還湊合更舞,嘗試識別訓練集
predictions = model.predict(x_test)
print(predictions)
看不出來這是個啥?別急恨狈,用
argmax
解析一下(就是找出最大數(shù)對應的索引疏哗,即為識別出的數(shù)字)
import numpy as np
print(np.argmax(predictions[0]))
啊哈,來看看
x_test[0]
這個圖像是什么樣的
plt.imshow(x_test[0],cmap=plt.cm.binary)
plt.show()
OK禾怠,妥妥的返奉,相信你也認為這就是個 7,我們的模型已經(jīng)可以識別數(shù)字啦吗氏!當然芽偏,這只是一個簡單的開始,后面的路還有很長弦讽,要多思考多動手污尉,堅持學習膀哲,才能早日成為大牛!
最后附上可以跑起來的完整代碼被碗,來自Deep Learning basics with Python, TensorFlow and Keras p.1
import tensorflow as tf # 深度學習庫某宪,Tensor 就是多維數(shù)組
mnist = tf.keras.datasets.mnist # mnist 是 28x28 的手寫數(shù)字圖片和對應標簽的數(shù)據(jù)集
(x_train, y_train),(x_test, y_test) = mnist.load_data() # 分割數(shù)據(jù)集
x_train = tf.keras.utils.normalize(x_train, axis=1) # 把數(shù)據(jù)值縮放到 0 到 1
x_test = tf.keras.utils.normalize(x_test, axis=1)
model = tf.keras.models.Sequential() # 基礎的前饋神經(jīng)網(wǎng)絡模型
model.add(tf.keras.layers.Flatten()) # 把圖片展平成 1x784
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu)) # 簡單的全連接圖層,,128 個單元锐朴,激活函數(shù)為 relu
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax)) # 輸出層 兴喂,10 個單元, 使用 Softmax 獲得概率分布
model.compile(optimizer='adam', # 默認的較好的優(yōu)化器
loss='sparse_categorical_crossentropy', # 評估“錯誤”的損失函數(shù)焚志,模型應該盡量降低損失
metrics=['accuracy']) # 評價指標
model.fit(x_train, y_train, epochs=3) # 訓練模型
val_loss, val_acc = model.evaluate(x_test, y_test) # 評估模型對樣本數(shù)據(jù)的輸出結果
print(val_loss) # 模型的損失值
print(val_acc) # 模型的準確度
您的認真閱讀就是對我最大的鼓勵衣迷!如果覺得我的文章對您有幫助,想要和我一起不斷學習新的知識酱酬、不斷進步壶谒,歡迎點擊頭像旁邊的「關注」按鈕,讓我好跟基友們吹個牛逼膳沽!
歡迎關注 evan 的博客