(Tensorflow)手把手CNN入門:手寫數字識別
深度學 習 最令人 興奮 的 領 域之一就是 計 算機 視覺 。通 過 卷 積 神 經 網 絡 ,我 們 已 經 能 夠創 建自 動駕駛 汽 車系統 、面部 檢測 系 統 和自 動 醫學 圖 像分析等等。在本文中,我將向你展示卷 積 神 經 網 絡 的基本原理以及如何自己 創 建一個 對 手寫數字 進 行分 類的系統 。
卷積神經網路的功能似乎是人類大腦中生物功能的複製,早在1959年,David Hubel和Torsten Wiesel對貓和猴進行了研究,這些研究揭示了動物視覺皮層的功能。他們發現的是,許多神經元具有小的區域性接受性,即僅對整個視野的一小塊有限區域起反應。他們發現某些神經元會對某些特定模式做出反應,例如水平線、垂直線和其他圓形。他們還發現其他神經元具有更大的感受野並且被更復雜的模式刺激,這些模式是由較低水平神經元收集的資訊組合。這些發現奠定了我們現在稱之為卷積神經網路的基礎。接下來,我們逐一介紹卷積神經網路的組成。
1 、卷 積層
卷積神經網路中每層卷積層由若干卷積單元組成,每個卷積單元的引數都是通過 ofollow,noindex"> 反向傳播演算法 最佳化得到的。卷積運算的目的是提取輸入的不同特徵,第一層卷積層可能只能提取一些低階的特徵如邊緣、線條和角等層級,更多層的網路能從低階特徵中迭代提取更復雜的特徵。 你可以將每個 過濾 器描 繪 成一個視窗, 該 視窗在 圖 像的尺寸上滑 動 並 檢測 屬性。 濾鏡在影象上滑動的畫素數量稱為步幅 。步幅 為 1 意味著 濾 波器一次移 動 一個畫素,其中 2 的步幅將向前跳 過 2 個畫素。
在上面的例子中,我 們 可以看到一個垂直 線檢測 器。原始 圖 像 為 6x6 ,它使用 3x3 濾鏡進行掃描,步長為 1 ,從而 產 生 4x4 尺寸 輸 出。而 過濾器僅對其視野左右列中的部分感興趣 。通 過對圖 像的 輸 入求和並乘以 3×3 濾波器的配置,我們得到 3+1+2-1-7-5=-7 。然後 濾 波器向右移 動 一步,然後 計 算 1+0+3-2-3-1=-2 。 -2 然後 進 入 -7 右 側 的位置。此 過 程將持 續 到 4x4 網格完成 為 止。之後,下一個特徵圖將使用它自己的唯一 過濾 器 / 核心矩 陣計 算自己的 值 。
2. 池化層
池化層的目標是通過聚合卷積層收集的值或所謂的子取樣來進一步降低維度。除了為模型提供一些正則化的方案以避免過度擬合之外,這還將減少計算量。它們遵循與卷積層相同的滑動視窗思想,但不是計算所有值,而是選擇其輸入的最大值或平均值。這分別稱為最大池化和平均池化。
這兩個元件是卷積層的關鍵構建塊。然後,你通常會重複此方法,進一步減少特徵圖的尺寸,但會增加其深度。每個特徵圖將專門識別它自己獨特的形狀。在卷積結束時,會放置一個完全連線的圖層,其具有啟用功能,例如Relu或Selu,用於將尺寸重新整形為適合的尺寸送入分類器。例如,如果你的最終轉換層為3x3x128矩陣,但你只預測10個不同的類,則需要將其重新整形為1x1152向量,並在輸入分類器之前逐漸減小其大小。完全連線的層也將學習它們自己的特徵,如在典型的深度神經網路中。
現在讓我們看看在 MNIST 手寫數字資料集上的 Tensorflow 中的 實現 。首先,我 們 將加 載 我 們 的 庫 。使用 sklearn 中的 fetch_mldata ,我 們 加 載 mnist 資料集並將 圖 像和 標籤 分配 給 x 和 y 變數 。然後我 們 將 創 建我 們 的訓練 / 測試裝置 。最後,我 們 將 舉 幾個例子來了解任 務 。
接下來,我 們 將 進 行一些資料 增強 , 這 是提高模型效能的可靠方法。通 過創 建 訓練圖 像的 輕 微 變 化,可以 為 模型 創 建正 則 化。我 們 將使用 Scipy 的 ndimage 模 塊 將 圖 像向右、向左、向上和向下移 動 1 個畫素。 這不僅提供了更多種類的例子,而且還會大大增加我們訓練集的大小 。
我將向你展示的最後一種資料增強的方式:使用cv2庫建立影象的水平翻轉。我們還需要為這些翻轉影象建立新標籤,這與複製原始標籤一樣簡單。
設定 “flipCode = 0” 將 產 生垂直翻 轉
接下來,我 們 將 創 建一個 輔 助函式,用於將隨機微型批次提供 給 我 們 的神 經 網 絡輸 入。由於卷 積層 的性 質 ,它 們 在前向和後向 傳 播步 驟 期 間 需要大量的存 儲 器。考 慮 具有 4x4 濾鏡的圖層,輸出 128 步幅 為 1 的特徵 圖 和具有尺寸 299x299 的 RGB 影象輸入的 SAME 填充。引數的數量將相等( 4x4x3+1 ) x128 = 6272. 現在考慮這 128 個特徵 圖 中的每一個都 計 算 299x299 個神 經 元,並且 這 些神 經 元中的每一個都 計 算 4x4x3 輸入的加權和 。 這意味著我們需要 4x4x3x299x299x150=643,687,200 次 計 算, 這隻 是一個 訓練 的例子。
現在我 們 開始 創 建我 們 的網 絡 架構。首先,我 們為 我 們 的培 訓 資料 / 特徵建立佔位符 。我 們 需要將它 們 重新整形 為 ( -1,28,28,1 )矩 陣 ,因 為 tensorflow conv2d 層需要 4 維輸入 。我 們 將第一個 維 度 設 置 為 “ null ” ,以允 許 將任意批量大小提供 給 佔位符。
接著我們設計我們的卷積層 ,我是從 Le-NET5 (由 Yann LeCun 開 創 )網 絡 架構中 獲 取靈感, 該 架構因其在手寫數字分 類 方面成功而 聞 名。我建 議 你研究 Le-NET5 以及其他 經過驗證的模型,這樣就可以瞭解哪種卷積網路適用於不同的任務 。 連結: http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf 。
我們模型卷積層的第一 層 由 12 個特徵 圖組 成,使用 3x3 過濾器,步幅為 1 。 我 們選擇 了 SAME 填充,通 過 在 輸 入周 圍 新增一個零填充來保持 圖 像的尺寸。然後,我 們設定 最大池化 層 使用 3x3 過濾器 ,步幅為1,這將 輸 出 13x13x12 矩 陣 。所以我 們 從一個 28x28x1 的 圖 像開始,然後我 們 將 這 個矩 陣傳遞給 第二個 轉換層 ,第二個轉換層具有 3x3 過濾器的深度, stride=1 和 SAME 填充 。 這將輸出一個 6*6*16 維矩陣 。你可以看到我 們 正在 縮 小特徵圖的 維 度空 間 ,但要更深入。接下來,我 們 使用 Selu 函式 啟用兩個密集 層 來減少每 層輸 入的數量大 約 一半,直到最 終 將它 們輸 入我 們 的 logits 。
接著我們建立我們的損失函式,在這種情況下,它將是softmax交叉熵,它將輸出多類概率。你可以將交叉熵視為各種資料點之間距離的度量。我們選擇AdamOptimizer(自適應矩估計),當梯度下降時自動調整它的學習率。最後,我們建立了一種評估結果的方法。Tensorflow的in_top_k函式將計算我們的logits並選擇最高分。然後我們使用我們的準確度變數輸出0-1%之間的百分比。
現在我們已經為訓練階段做好了準備,讓我們看看我們的模型表現得如何。
在第 19 epoch ,我們的正確率在 0.9907 。 這已經比任何機器學習演算法的結果更好,因此卷積已經取得了領先 。 現在讓我們嘗試使用我們的移位功能 / 翻 轉 功能,並 為 我 們 的網 絡 新增兩個新元素: dropout 和批量標準化 。
我 們 使用 placeholder_with_default 節點修改現有佔位符,這些節點將儲存批量標準化和dropout層 生成的 值 。在 訓練 期 間 ,我 們 將 這 些 值設 置 為 True ,在 測試 期 間 ,我 們 將通 過設 置 為 False 將其關 閉 。
批量 標 準化只是 簡單 地 對 每批次的資料 進 行 標 準化。我 們 指定了 0.9 的 動 量。而dropout和正 則 化指定動量為1才能在 訓練 期 間 完全隨機地關 閉節 點。 這導致其餘節點必須鬆弛,從而提高其有效性 。想象一下,一家公司決定每週隨機 選擇 50 名 員 工留在家裡。其餘的工作人 員 將不得不有效地 處 理 額 外的工作,提高他 們 在其他 領 域的技能。
接著我 們創 建我 們 的 損 失函式, 訓練步驟 和 評 估步 驟 ,然後 對 我 們 的 執 行 階 段 進 行一些修改。通 過 批量 標 準化 執 行的 計 算在每次迭代期 間 儲存 為 更新操作。 為了訪問這些,我們分配一個變數 extra_update_ops = tf.get_collection ( tf.GraphKeys.UPDATE_OPS )。在我 們 的 訓練 操作期 間 ,我 們 將其作 為 列表 項 與 training_op 一起提供 給 sess.run 。最後,在 執 行 驗證 / 測試預測時,我們通過 feed_dict 為佔位符分配 False 值 。我 們 不希望在 預測階 段有任何隨機化。 為了獲得輸出,我們使用我們的測試集執行 logits 操作。 讓我們看看這個模型新增正則化 / 標準化並且正在使用增強資料的方法 後 表現得如何。
在 29 epoch ,我們在 10,000 個數字的 測試 集上達到了 99.5 %的準確率。正如你所看到的那 樣 ,第二個 epoch 時模型精確度達到了 99 %,而之前的模型只有 16% 。 雖然 0.05 %可能不是很多,但在 處 理大量資料 時這 是一個重大改 進 。最後,我將向你展示如何在 logits 輸出上使用 np.argmax 產生的 預測 。
本文由 阿里云云棲社群 組織翻譯。
文章原標題《convolutional-neural-net-in-tensorflow》
作者: Stephen Barter 譯者:虎說八道,審校:。
文章為簡譯,更為詳細的內容,請檢視 原文 。