Deep MNIST for Experts解讀(三):deepnn源碼分析與AdamOptimizer

Deep MNIST for Experts解讀(三):deepnn源碼分析與AdamOptimizer
https://www.tensorflow.org/get_started/mnist/pros


mnist_deep.py
上節講了卷積與最大池化,本節來看看deepnn
在概覽中提到,deepnn分了如下幾層:
1.第一卷積層
2.第二卷積層
3.全聯接層
4.dropout層
5.輸出層
結合代碼分別標註下:


第一卷積層:
x_image = tf.reshape(x, [-1, 28, 28, 1])
作爲conv2d的第一個輸入,格式爲[訓練時一個batch的圖片數量, 圖片高度, 圖片寬度, 輸入通道數],上節講過。輸入通道灰色就只有1,RGB是3,RGBA是4.
# First convolutional layer - maps one grayscale image to 32 feature maps.
W_conv1 = weight_variable([5, 5, 1, 32])
初始化一個期望爲0,標準差爲0.1的正態分佈,四維張量,爲作conv2d的第二個輸入,格式爲:[卷積核的高度,卷積核的寬度,輸入通道數,輸出通道數]。
b_conv1 = bias_variable([32])
一個有32個0.1的向量。
解讀下:圖片是28*28,多少張圖片待定,黑白圖片,所以是1個輸入通道,卷積核5*5,32個輸出通道。爲啥是32個輸出通道?32個feature maps。這個其實不太好理解。通俗的講,就是源碼希望在這一卷積層捕獲到32個特徵。具體解釋推薦:https://www.zhihu.com/question/31318081。
一張圖(矩陣)經過卷積核(kernal)卷積運算之後得到的一張新的圖(矩陣),就是feature map。爲什麼是32個feature map,主要靠經驗。深度學習模型有好些超參數的設置都得靠經驗。
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
卷積,加入干擾,再線性修正,上章講過。
h_pool1 = max_pool_2x2(h_conv1)
最大池化,上章講過。


第二卷積層:
 # Second convolutional layer -- maps 32 feature maps to 64.
  W_conv2 = weight_variable([5, 5, 32, 64])
  b_conv2 = bias_variable([64])
  h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
  h_pool2 = max_pool_2x2(h_conv2)
輸入通道32,即第一層的輸出通道數,32個feature maps,第二次希望獲取到更多的特徵,映射到64個feature maps.


全聯接層:
第一卷積層把圖片縮減採樣成14*14,第二卷積層縮爲7*7,每張圖獲取了64個特徵圖(有64個輸出通道),共計3136個特徵圖。
更直觀的理解:二個卷積運算下來,輸出爲64個矩陣,每個7*7,每個點都表示一個feature map,共計3136個元素點。
在全聯接層中,把3136個特徵歸積到1024個特徵中去。
  # Fully connected layer 1 -- after 2 round of downsampling, our 28x28 image
  # is down to 7x7x64 feature maps -- maps this to 1024 features.
  W_fc1 = weight_variable([7 * 7 * 64, 1024])
  b_fc1 = bias_variable([1024])
  h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
  h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
代碼本身不難,就是一個標準矩陣乘法,加法和線性修正。
簡單的講,學習輸出要經歷:原始數據--》隱層特徵空間和分佈式特徵表示--》樣本標記空間。
得到3136個特徵圖完成了第一步,還必須有一個全聯接層完成第二步轉換。


dropout層:
  # Dropout - controls the complexity of the model, prevents co-adaptation of
  # features.
  keep_prob = tf.placeholder(tf.float32)
  h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
控制模型複雜度,阻止功能同化。這句話說得很隱晦。
keep_prob指keep probability,保持概率,保有概率。keep_prob在main中做訓練時使用了0.5,即每次訓練,每個神經元有一半的機會參加。
主要理解dropout的作用。dropout,漢語翻譯爲剪枝,類似於對花草分枝的修剪,就是在訓練過程中剪掉某些神經元,不讓它參與本次訓練,這樣做的目標是爲了防止過擬合,增加模型的健壯性,同時減少訓練的計算量。參考閱讀:http://blog.csdn.net/huahuazhu/article/details/73649389


輸出層:
  # Map the 1024 features to 10 classes, one for each digit
  W_fc2 = weight_variable([1024, 10])
  b_fc2 = bias_variable([10])


  y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
把1024個特徵映射到10個分類中去(0-9)。


小結一下:
1.第一卷積層:讀圖片,每個圖片學習32個特徵圖,輸出一個14*14的卷積,14*14*32=6272。
2.第二卷積層:根據上層,每個卷積學習64個特徵圖,輸出一個7*7的卷積,7*7*64=3136。
3.全聯接層:根據上層,把7*7*64個feature maps映射到1024個feature。
4.dropout層:剪枝式的強化訓練。
5.輸出層:把1024個feature映射到0-9共計10類分類中。
有了前面的理解,這裏讀代碼並不難,主要是理解feature map, feature,dropout和 classes.


這裏說完了第二個遺留問題。下面說一下第三個遺留問題。
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
對比之前在softmax中的代碼:
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
這裏選用了AdamOptimizer優化器。
使用的是Adam算法。
源碼推薦文檔:http://arxiv.org/pdf/1412.6980.pdf。
簡單瞭解的話,看看http://blog.csdn.net/muyu709287760/article/details/62531509#7-adam


Deep MNIST for Experts解讀就說完了,結合前面的兩篇博客,再讀讀mnist_deep.py,你能看懂嗎。
發佈了30 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章