深度學習基礎
神經網絡的數學基礎
初識神經網絡
-
我們來看一個具體的神經網絡示例,使用 Python 的 Keras 庫來學習手寫數字分類。
-
我們這裏要解決的問題是,將手寫數字的灰度圖像(28 像素 × 28像素)劃分到10個類別中(0~9)。
-
我們將使用 MNIST 數據集,它是機器學習領域的一個經典數據集,其歷史幾乎和這
個領域一樣長,而且已被人們深入研究。 -
這個數據集包含60000張訓練圖像和10000張測試圖像,由美國國家標準與技術研究院(National Institute of Standards and Technology,即 MNIST 中的 NIST)在 20 世紀 80 年代收集得到。
-
在機器學習中,分類問題中的某個類別叫作類(class),數據點叫作樣本(sample),某個樣本對應的類叫作標籤(label)。
-
MNIST 數字圖像樣本
-
MNIST 數據集預先加載在 Keras 庫中,其中包括4個 Numpy 數組。
# 加載 Keras 中的 MNIST 數據集 from keras.datasets import mnist (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
- train_images 和 train_labels 組成了訓練集(training set),模型將從這些數據中進行學習。然後在測試集(test set,即 test_images 和 test_labels)上對模型進行測試。
- 圖像被編碼爲 Numpy 數組,而標籤是數字數組,取值範圍爲0~9,圖像和標籤對應。
# 我們來看一下訓練數據: >>> train_images.shape (60000, 28, 28) >>> len(train_labels) 60000 >>> train_labels array([5, 0, 4, ..., 5, 6, 8], dtype=uint8) # 下面是測試數據: >>> test_images.shape (10000, 28, 28) >>> len(test_labels) 10000 >>> test_labels array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
-
接下來的工作流程如下:
- 首先,將訓練數據(train_images 和 train_labels)輸入神經網絡;
- 其次,網絡學習將圖像和標籤關聯在一起;
- 最後,網絡對 test_images 生成預測,而我們將驗證這些預測與 test_labels 中的標籤是否匹配。
# 網絡架構 from keras import models from keras import layers network = models.Sequential() network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, ))) network.add(layers.Dense(10, activation='softmax'))
- 本例中的網絡包含2個 Dense 層,它們是密集連接(也叫全連接)的神經層。第二層(也是最後一層)是一個10路 softmax 層,它將返回一個由10個概率值(總和爲1)組成的數組,每個概率值表示當前數字圖像屬於10個數字類別中某一個的概率。
-
-
神經網絡的核心組件是層(layer)。
- 它是一種數據處理模塊,你可以將它看成數據過濾器。
- 進去一些數據,出來的數據變得更加有用。
- 具體來說,層從輸入數據中提取表示,我們期望這種表示有助於解決手頭的問題。
- 大多數深度學習都是將簡單的層鏈接起來,從而實現漸進式的數據蒸餾(data distillation)。
- 深度學習模型就像是數據處理的篩子,包含一系列越來越精細的數據過濾器(即層)。
-
要想訓練網絡,我們還需要選擇編譯(compile)步驟的三個參數。
- 損失函數(loss function)
- 網絡如何衡量在訓練數據上的性能,即網絡如何朝着正確的方向前進。
- 優化器(optimizer)
- 基於訓練數據和損失函數來更新網絡的機制。
- 在訓練和測試過程中需要監控的指標(metric)
- 本例只關心精度,即正確分類的圖像所佔的比例。
# 編譯步驟 network.compile(optimizer = 'rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
- 損失函數(loss function)
-
數據預處理
-
在開始訓練之前,我們將對數據進行預處理,將其變換爲網絡要求的形狀,並縮放到所有值都在[0, 1]區間。
-
比如,之前訓練圖像保存在一個 uint8 類型的數組中,其形狀爲(60000, 28, 28),取值區間爲[0, 255]。
-
我們需要將其變換爲一個 float32 數組,其形狀爲(60000, 28 * 28),取值範圍爲0~1。
# 準備圖像數據 train_images = train_images.reshape((60000, 28 * 28)) train_images = train_images.astype('float32') / 255 test_images = test_images.reshape(10000, 28 * 28) test_images = test_images.astype('float32') / 255
-
-
對標籤進行分類編碼
# 準備標籤 from keras.utils import to_categorical train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels)
-
現在我們準備開始訓練網絡,在 Keras 中這一步是通過調用網絡的 fit 方法來完成的,我們在訓練數據上擬合(fit)模型。
>>> network.fit(train_images, train_labels, epochs=5, batch_size=128)
-
訓練過程中顯示了兩個數字:一個是網絡在訓練數據上的損失(loss),另一個是網絡在訓練數據上的精度(acc)。
-
現在我們來檢查一下模型在測試集上的性能。
>>> test_loss, test_acc = network.evaluate(test_images, test_labels) >>> print('test_acc:', test_acc)
-
訓練精度和測試精度之間的差距是過擬合(overfit)造成的,過擬合是指機器學習模型在新數據上的性能往往比在訓練數據上要差。