在前幾次筆記中,筆者基本上將卷積神經網絡的基本原理給講完了。從本次筆記開始,筆者在深度學習筆記中會不定期的對 CNN 發展過程中的經典論文進行研讀并推送研讀筆記。今天筆者就和大家一起學習卷積神經網絡和深度學習發展歷史上具有奠基性的經典論文之一的關于 LeNet-5 網絡一文。LeNet-5 是由具有卷積神經網絡之父之美譽的 Yann LeCun 在1998年發表在 IEEE 上面的一篇 Gradient-based learning applied to document recognition 上提出來的,所以直接由 LeCun 大佬名字命名了。論文原文:http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
LeNet-5 網絡結構
該篇論文有 42 頁,但關于 LeNet-5 網絡的核心部分并沒有那么多,我們直接定位第二章的B 小節進行閱讀。LeNet-5 的網絡結構如下:
LeNet-5 共有 7 層,輸入層不計入層數,每層都有一定的訓練參數,其中三個卷積層的訓練參數較多,每層都有多個濾波器,也叫特征圖,每個濾波器都對上一層的輸出提取不同的像素特征。所以 LeNet-5 的簡略結構如下:
輸入-卷積-池化-卷積-池化-卷積(全連接)-全連接-全連接(輸出)
各層的結構和參數如下:C1層是個卷積層,其輸入輸出結構如下:輸入: 32 x 32 x 1 濾波器大小: 5 x 5 x 1 濾波器個數:6輸出: 28 x 28 x 6參數個數: 5 x 5 x 1 x 6 + 6 = 156
P2層是個池化層,其輸入輸出結構如下:輸入: 28 x 28 x 6 濾波器大?。?2 x 2 濾波器個數:6輸出: 14 x 14 x 6參數個數:2 x 6 = 12在原文中,P1池化層采用的是平均池化,鑒于現在普遍都使用最大池化,所以在后面的代碼實現中我們統一采用最大池化。
C3層是個卷積層,其輸入輸出結構如下:輸入: 14 x 14 x 6 濾波器大?。?5 x 5 x 6 濾波器個數:16輸出: 10 x 10 x 16參數個數: 5 x 5 x 6 x 16 + 16 = 2416
P2 池化之后的特征圖組合計算得到C3的濾波器個數。
P4層是個池化層,其輸入輸出結構如下:輸入: 10 x 10 x 16 濾波器大?。?2 x 2 濾波器個數:16輸出: 5 x 5 x 16參數個數: 2 x 16 = 32
C5層在論文中是個卷積層,但濾波器大小為 5 x 5,所以其本質上也是個全連接層。如果將5 x 5 x 16 拉成一個向量,它就是一個全連接層。其輸入輸出結構如下:輸入: 5 x 5 x 16 濾波器大小: 5 x 5 x 16 濾波器個數:120輸出: 1 x 1 x 120參數個數: 5 x 5 x 16 x 120 + 120 = 48120
F6層是個全連接層,全連接的激活函數采用的是tanh函數,其輸入輸出結構如下:輸入:120輸出:84參數個數:120 x 84 + 84 = 10164
F7層即輸出層,也是個全連接層,其輸入輸出結構如下:輸入:84輸出:10參數個數: 84 x 10 + 10 = 850
LeNet-5 的Tensorflow實現
我們前面關于如何使用Tensorflow搭建卷積神經網絡的過程可以定下實現 LeNet-5 的基本思路。如果在python中寫的時候我們需要定義創建輸入輸出的占位符變量模塊、初始化各層參數模塊、創建前向傳播模塊、定義模型優化迭代模型,以及在最后設置輸入數據。
下面筆者用以上思路編寫一個 LeNet-5 的簡單實現代碼。 導入相關庫和創建輸入輸出的占位符變量:
import tensorflow as tfimport numpy as npfrom tensorflow.examples.tutorials.mnist import input_datadef create_placeholder(): X = tf.placeholder(tf.float32, shape=(None, 28 * 28)) Y = tf.placeholder(tf.float32, shape=(None, 10)) keep_prob = tf.placeholder(tf.float32) return X, Y, keep_prob
初始化各層參數:
def initialize_parameters(): W1 = tf.get_variable('W1', [5,5,1,6], initializer=tf.contrib.layers.xavier_initializer()) b1 = tf.get_variable('b1', [6], initializer=tf.zeros_initializer()) W2 = tf.get_variable('W2', [5,5,6,16], initializer=tf.contrib.layers.xavier_initializer()) b2 = tf.get_variable('b2', [16], initializer=tf.zeros_initializer()) W3 = tf.get_variable('W3', [5, 5, 16, 120], initializer=tf.contrib.layers.xavier_initializer()) b3 = tf.get_variable('b3', [120], initializer=tf.zeros_initializer()) W4 = tf.get_variable('W4', [120, 84], initializer=tf.contrib.layers.xavier_initializer()) b4 = tf.get_variable('b4', [84], initializer=tf.zeros_initializer()) W5 = tf.get_variable('W5', [84, 10], initializer=tf.contrib.layers.xavier_initializer()) b5 = tf.get_variable('b5', [10], initializer=tf.zeros_initializer()) para = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2, 'W3': W3, 'b3': b3, 'W4': W4, 'b4': b4, 'W5': W5, 'b5': b5} return para
創建 LeNet-5 的前向計算:
def forward_propagation(X, para, dropout): X = tf.reshape(X, [-1, 28, 28, 1]) X = tf.pad(X, [[0,0],[2,2],[2,2], [0,0]]) c1 = tf.nn.conv2d(X, para['W1'], strides=[1, 1, 1, 1], padding='VALID') + para['b1'] p2 = tf.nn.max_pool(c1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') c3 = tf.nn.conv2d(p2, para['W2'], strides=[1, 1, 1, 1], padding='VALID') + para['b2'] p4 = tf.nn.max_pool(c3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') c5 = tf.nn.conv2d(p4, para['W3'], strides=[1, 1, 1, 1], padding='VALID') + para['b3'] c5 = tf.contrib.layers.flatten(c5) f6 = tf.nn.tanh(tf.add(tf.matmul(c5, para['W4']), para['b4'])) f7 = tf.nn.tanh(tf.add(tf.matmul(f6, para['W5']), para['b5'])) f7 = tf.nn.dropout(f7, dropout) return f7
創建模型優化計算函數:
最后傳入 mnist 數據和相關超參數:
注:本深度學習筆記系作者學習 Andrew NG 的 deeplearningai 五門課程所記筆記,其中代碼為每門課的課后assignments作業整理而成。
-
神經網絡
+關注
關注
42文章
4771瀏覽量
100720 -
深度學習
+關注
關注
73文章
5500瀏覽量
121113 -
cnn
+關注
關注
3文章
352瀏覽量
22204
原文標題:深度學習筆記14:CNN經典論文研讀之Le-Net5及其Tensorflow實現
文章出處:【微信號:AI_shequ,微信公眾號:人工智能愛好者社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論