深度學習(四)卷積神經網絡-卷積神經網絡(2) -Andrew Ng

目錄

 

一、基礎知識

1.1 爲什麼要進行實例探究?

1.2 經典網絡

 1.3 殘差網絡

1.4 殘差網絡爲什麼有用

1.5 網絡中的網絡以及 1×1 卷積

1.6 谷歌 Inception 網絡簡介

1.7 Inception 網絡

1.8 使用開源的實現方案

1.9 遷移學習

1.10 數據擴充

1.11 計算機視覺現狀

二、測驗:

三、編程作業

3.1 導包

3.2 用 Keras 創建模型


一、基礎知識

1.1 爲什麼要進行實例探究?

本文將主要介紹幾個典型的CNN案例。通過對具體CNN模型及案例的研究,來幫助我們理解知識並訓練實際的模型。

典型的CNN模型包括:

  • LeNet-5

  • AlexNet

  • VGG

除了這些性能良好的CNN模型之外,我們還會介紹Residual Network(ResNet)。其特點是可以構建很深很深的神經網絡(目前最深的好像有152層)。

另外,還會介紹Inception Neural Network。接下來,我們將一一講解。

1.2 經典網絡

LeNet-5模型是Yann LeCun教授於1998年提出來的,它是第一個成功應用於數字識別問題的卷積神經網絡。在MNIST數據中,它的準確率達到大約99.2%。典型的LeNet-5結構包含CONV layer,POOL layer和FC layer,順序一般是CONV layer->POOL layer->CONV layer->POOL layer->FC layer->FC layer->OUTPUT layer,即y^。下圖所示的是一個數字識別的LeNet-5的模型結構:

                                  

該LeNet模型總共包含了大約6萬個參數。值得一提的是,當時Yann LeCun提出的LeNet-5模型池化層使用的是average pool,而且各層激活函數一般是Sigmoid和tanh。現在,我們可以根據需要,做出改進,使用max pool和激活函數ReLU。

AlexNet模型是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton共同提出的,其結構如下所示

                                  

AlexNet模型與LeNet-5模型類似,只是要複雜一些,總共包含了大約6千萬個參數。同樣可以根據實際情況使用激活函數ReLU。原作者還提到了一種優化技巧,叫做Local Response Normalization(LRN)。 而在實際應用中,LRN的效果並不突出。

VGG-16模型更加複雜一些,一般情況下,其CONV layer和POOL layer設置如下:

  • CONV = 3x3 filters, s = 1, same

  • MAX-POOL = 2x2, s = 2

VGG-16結構如下所示:

                               

VGG-16的參數多達1億3千萬。

 1.3 殘差網絡

我們知道,如果神經網絡層數越多,網絡越深,源於梯度消失梯度爆炸的影響,整個模型難以訓練成功。解決的方法之一是人爲地讓神經網絡某些層跳過下一層神經元的連接,隔層相連,弱化每層之間的強聯繫。這種神經網絡被稱爲Residual Networks(ResNets)。

Residual Networks由許多隔層相連的神經元子模塊組成,我們稱之爲Residual block。單個Residual block的結構如下圖所示:

                                                  

                                                         

                                                       

該模型由Kaiming He, Xiangyu Zhang, Shaoqing Ren和Jian Sun共同提出。由多個Residual block組成的神經網絡就是Residual Network。實驗表明,這種模型結構對於訓練非常深的神經網絡,效果很好。另外,爲了便於區分,我們把非Residual Networks稱爲Plain Network

                               

Residual Network的結構如上圖所示。

與Plain Network相比,Residual Network能夠訓練更深層的神經網絡,有效避免發生發生梯度消失和梯度爆炸。從下面兩張圖的對比中可以看出,隨着神經網絡層數增加,Plain Network實際性能會變差,training error甚至會變大。然而,Residual Network的訓練效果卻很好,training error一直呈下降趨勢。

                                            

1.4 殘差網絡爲什麼有用

 下面用個例子來解釋爲什麼ResNets能夠訓練更深層的神經網絡。

                                               

                                                     

                                                    

                                                     

                                                  

                                                     

當然,如果Residual blocks確實能訓練得到非線性關係,那麼也會忽略short cut,跟Plain Network起到同樣的效果。‘

                                                   

下圖所示的是CNN中ResNets的結構:

                               

ResNets同類型層之間,例如CONV layers,大多使用same類型,保持維度相同。如果是不同類型層之間的連接,例如CONV layer與POOL layer之間,如果維度不同,則引入矩陣Ws。

1.5 網絡中的網絡以及 1×1 卷積

Min Lin, Qiang Chen等人提出了一種新的CNN結構,即1x1 Convolutions,也稱Networks in Networks。這種結構的特點是濾波器算子filter的維度爲1x1。對於單個filter,1x1的維度,意味着卷積操作等同於乘積操作。

                                        

                                      

                                       

1x1 Convolutions可以用來縮減輸入圖片的通道數目。方法如下圖所示:

                                                

1.6 谷歌 Inception 網絡簡介

 之前我們介紹的CNN單層的濾波算子filter尺寸是固定的,1x1或者3x3等。而Inception Network在單層網絡上可以使用多個不同尺寸的filters,進行same convolutions,把各filter下得到的輸出拼接起來。除此之外,還可以將CONV layer與POOL layer混合,同時實現各種效果。但是要注意使用same pool。

                             

Inception Network由Christian Szegedy, Wei Liu等人提出。與其它只選擇單一尺寸和功能的filter不同,Inception Network使用不同尺寸的filters並將CONV和POOL混合起來,將所有功能輸出組合拼接,再由神經網絡本身去學習參數並選擇最好的模塊。

不難發現,我所描述的 Inception 層有一個問題,就是計算成本。例如下面這個例子:

                                        

此CONV layer需要的計算量爲:28x28x32x5x5x192=120m,其中m表示百萬單位。即使在現在, 用計算機執行 1.2 億次乘法運算,成本也是相當高的。爲此,我們可以引入1x1 Convolutions來減少其計算量,結構如下圖所示:

                                  通常我們把該1x1 Convolution稱爲“瓶頸層”(bottleneck layer)。引入bottleneck layer之後,總共需要的計算量爲:28x28x16x192+28x28x32x5x5x16=12.4m。明顯地,雖然多引入了1x1 Convolution層,但是總共的計算量減少了近90%,效果還是非常明顯的。由此可見,1x1 Convolutions還可以有效減少CONV layer的計算量。

總結:

如果你在構建神經網絡層的時候,不想決定池化層是使用 1×1,3×3 還是 5×5 的過濾器,那麼 Inception 模塊就是最好的選擇。我們可以應用各種類型的過濾器,只需要 把輸出連接起來。之後我們講到計算成本問題,我們學習瞭如何通過使用 1×1 卷積來構建瓶 頸層,從而大大降低計算成本。

疑問:

僅僅大幅縮小表示層規模會不會影響神經網絡的性能?事實證明,只要合理構建瓶頸層,你既可以顯著縮小表示層規模,又不會降低網絡性能,從而節省了計算。

1.7 Inception 網絡

上一節我們使用1x1 Convolution來減少Inception Network計算量大的問題。引入1x1 Convolution後的Inception module如下圖所示:

                                             

 多個Inception modules組成Inception Network,效果如下圖所示:

                       

                                 

上述Inception Network除了由許多Inception modules組成之外,值得一提的是網絡中間隱藏層也可以作爲輸出層Softmax,有利於防止發生過擬合。

1.8 使用開源的實現方案

本節主要介紹GitHub的使用,GitHub是一個面向開源及私有軟件項目的託管平臺,上面包含有許多優秀的CNN開源項目。關於GitHub具體內容不再介紹,有興趣的小夥伴自行查閱。

1.9 遷移學習

有關Transfer Learning的相關內容,我們在吳恩達《構建機器學習項目》精煉筆記(2)– 機器學習策略(下)中已經詳細介紹過,這裏就不再贅述了。遷移學習是非常值得你考慮的,除非你有一個極其大的數據集和非常大的計算量預算來從頭訓 練你的網絡。

1.10 數據擴充

常用的數據擴充方法是對已有的樣本集進行垂直鏡像對稱 和 隨機裁剪

                                                       

另一種數據擴充的方法是彩色轉換。彩色轉換就是對圖片的RGB通道數值進行隨意增加或者減少,改變圖片色調。

                                                

除了隨意改變RGB通道數值外,還可以更有針對性地對圖片的RGB通道進行PCA color augmentation,也就是對圖片顏色進行主成分分析,對主要的通道顏色進行增加或減少,可以採用高斯擾動做法。這樣也能增加有效的樣本數量。具體的PCA color augmentation做法可以查閱AlexNet的相關論文。

最後提一下,在構建大型神經網絡的時候, 數據擴充 和 訓練 可以由兩個不同的線程來進行。

1.11 計算機視覺現狀

深度學習已經成功地應用於計算機視覺、自然語言處理、語音識別、在線廣告、物流還 有其他許多問題。在計算機視覺的現狀下,深度學習應用於計算機視覺應用有一些獨特之處。

神經網絡需要數據,不同的網絡模型所需的數據量是不同的。Object dection,Image recognition,Speech recognition所需的數據量依次增加。一般來說,如果data較少,那麼就需要更多的hand-engineering,對已有data進行處理,比如上一節介紹的data augmentation。模型算法也會相對要複雜一些。如果data很多,可以構建深層神經網絡,不需要太多的hand-engineering,模型算法也就相對簡單一些。

                             

值得一提的是hand-engineering是一項非常重要也比較困難的工作。很多時候,hand-engineering對模型訓練效果影響很大,特別是在數據量不多的情況下。

在模型研究或者競賽方面,有一些方法能夠有助於提升神經網絡模型的性能:

  • Ensembling: Train several networks independently and average their outputs.

  • Multi-crop at test time: Run classifier on multiple versions of test images and average results.

                                                 

但是由於這兩種方法計算成本較大,一般不適用於實際項目開發。

最後,我們還要靈活使用開源代碼:

  • Use archittectures of networks published in the literature

  • Use open source implementations if possible

  • Use pretrained models and fine-tune on your dataset

二、測驗:

1. 在典型的卷積神經網絡中,隨着網絡的深度增加,你能看到的現象是?

【 】 nHnH 和 nWnW 增加,同時nCnC 減少。

【 】 nHnH 和 nWnW 減少,同時 nCnC 也減少。

【 】 nHnH 和 nWnW 增加,同時 nCnC 也增加。

【★】 nHnH 和 nWnW 減少,同時 nCnC 增加。
 

2.在典型的卷積神經網絡中,你能看到的是?

  • 】 多個卷積層後面跟着的是一個池化層。

  • 【 】 多個池化層後面跟着的是一個卷積層。

  • 】 全連接層(FC)位於最後的幾層。

  • 【 】 全連接層(FC)位於開始的幾層。

3. 爲了構建一個非常深的網絡,我們經常在卷積層使用“valid”的填充,只使用池化層來縮小激活值的寬/高度,否則的話就會使得輸入迅速的變小。

  • 【 】 True

  • 】 False

博主注:我們經常使用“SAME”的padding方式。

4. 我們使用普通的網絡結構來訓練一個很深的網絡,要使得網絡適應一個很複雜的功能(比如增加層數),總會有更低的訓練誤差。

  • 【 】 True

  • 】 False

博主注:在沒有殘差的普通神經網絡中,理論上是誤差越來越低的,但是實際上是隨着網絡層數的加深,先減小再增加;在有殘差的ResNet中,即使網絡再深,訓練誤差都會隨着網絡層數的加深逐漸減小

5. 下面計算殘差(ResNet)塊的公式中,橫線上應該分別填什麼? 
                                                    

  • 【 】分別是 0 與 z[l+1] 。
  • 】分別是 a[l] 與 0 
  • 【 】分別是 z[l] 與 a[l] 。
  • 【 】分別是 0 與 a[l] 。

6. 關於殘差網絡下面哪個(些)說法是正確的?

【 】 使用跳越連接能夠對反向傳播的梯度下降有益且能夠幫你對更深的網絡進行訓練。

【★】 跳躍連接計算輸入的複雜的非線性函數以傳遞到網絡中的更深層。

【 】 有L層的殘差網絡一共有L2L2種跳躍連接的順序。

【★】 跳躍連接能夠使得網絡輕鬆地學習殘差塊類的輸入輸出間的身份映射。


7.假設你的輸入的維度爲64x64x16,單個1x1的卷積過濾器含有多少個參數(包括偏差)?

  • 【 】 2

  • 】 17

  • 【 】 4097

  • 【 】 1

8. 假設你有一個維度爲nH×nW×nC的卷積輸入,下面哪個說法是正確的(假設卷積層爲1×1,步伐爲1,padding爲0)?

  • 】你能夠使用1×1的卷積層來減少nC,但是不能減少 nHnW
  • 】你可以使用池化層減少 nHnW,但是不能減少 nC
  • 【 】你可以使用一個1×1的卷積層來減少nHnWnC.
  • 【 】你可以使用池化層減少 nH、 nWnC.

9.  關於 Inception 網絡下面哪些說法是正確的

【 】 Inception 網絡包含了各種網絡的體系結構(類似於隨機刪除節點模式,它會在每一步中隨機選擇網絡的結構),因此它具有隨機刪除節點的正則化效應。

【★】 Inception 塊通常使用1x1的卷積來減少輸入卷積的大小,然後再使用3x3和5x5的卷積。

【★】 一個inception 塊允許網絡使用1x1, 3x3, 5x5 的和卷積個池化層的組合。

【 】 通過疊加inception塊的方式讓inception 網絡更深不會損害訓練集的表現。
 

10. 下面哪些是使用卷積網絡的開源實現(包含模型/權值)的常見原因?

【 】 爲一個計算機視覺任務訓練的模型通常可以用來數據擴充,即使對於不同的計算機視覺任務也是如此。

【★】 爲一個計算機視覺任務訓練的參數通常對其他計算機視覺任務的預訓練是有用的。

【★】 使用獲得計算機視覺競賽獎項的相同的技術,廣泛應用於實際部署。

【★】 使用開源實現可以很簡單的來實現複雜的卷積結構。
 

三、編程作業

這一週的作業主要是keras入門和ResNet網絡。

  • 學習使用Keras(高級神經網絡API(編程框架)),該語言用Python編寫,並且能夠在包括TensorFlow和CNTK在內的幾個較低級框架之上運行。
  • 瞭解如何在幾個小時內構建深度學習算法。

首先我們做keras入門,思考如下情緒識別任務:

我們爲什麼要使用Keras? 開發Keras的目的是使深度學習工程師能夠快速構建和試驗不同的模型。 正如TensorFlow是一個比Python更高級的框架一樣,Keras是一個甚至更高層次的框架,並提供其他抽象。 能夠以最小的延遲將想法付諸實踐是找到良好模型的關鍵。 但是,Keras比底層框架更具限制性,因此可以在TensorFlow中實現一些非常複雜的模型,而在Keras中可以(沒有更多困難)實現這些模型。 話雖如此,Keras可以在許多常見模型上正常工作。

在本練習中,您將解決“快樂之家”問題,我們將在下面進行解釋。 讓我們加載所需的軟件包並解決歡樂之家的問題!

3.1 導包

import numpy as np
#import tensorflow as tf
from keras import layers
from keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D
from keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D
from keras.models import Model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from kt_utils import *

import keras.backend as K
K.set_image_data_format('channels_last')
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow

%matplotlib inline

注意:如您所見,我們從Keras導入了很多方法。 您可以直接在 NoteBook 中直接調用它們來輕鬆使用它們。 例如:X = Input(...) or X = ZeroPadding2D(...)

對於下一個假期,您決定與五個放學的朋友一起度過一個星期。 這是一個非常方便的房子,附近有很多事情可以做。 但是最重要的好處是,每個人在家裏時都承諾要快樂。 因此,任何想要進入房屋的人都必須證明自己目前的幸福狀態。

                                        

作爲一名深度學習專家,要確保嚴格執行“快樂”規則,您將要構建一種算法,該算法使用前門攝像頭中的圖片來檢查該人是否快樂。 僅當該人感到高興時,門才應打開。

您已經通過前門攝像頭收集了您的朋友和您自己的照片。 該數據集是標籤化的。

                            

 

運行以下代碼以標準化數據集並瞭解其 shape。

X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

# 標準化圖片向量
X_train = X_train_orig/255.
X_test = X_test_orig/255.

# Reshape
Y_train = Y_train_orig.T
Y_test = Y_test_orig.T

print ("number of training examples = " + str(X_train.shape[0]))
print ("number of test examples = " + str(X_test.shape[0]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))

輸出結果:

number of training examples = 600
number of test examples = 150
X_train shape: (600, 64, 64, 3)
Y_train shape: (600, 1)
X_test shape: (150, 64, 64, 3)
Y_test shape: (150, 1)

3.2 用 Keras 創建模型

Keras非常適合模型的快速創建。 在很短的時間內,您將能夠建立一個能夠獲得出色結果的模型。

這是Keras中的模型示例:

def model(input_shape):
    # 定義輸入的placeholder
    X_input = Input(input_shape)

    # 用0填充
    X = ZeroPadding2D((3, 3))(X_input)

    # CONV -> BN -> RELU
    X = Conv2D(32, (7, 7), strides = (1, 1), name = 'conv0')(X)
    X = BatchNormalization(axis = 3, name = 'bn0')(X)
    X = Activation('relu')(X)

    # 最大池化層
    X = MaxPooling2D((2, 2), name='max_pool')(X)

    # FLATTEN X (means convert it to a vector) + FULLYCONNECTED
    X = Flatten()(X)
    X = Dense(1, activation='sigmoid', name='fc')(X)

    # 創建模型. 這將創建您的Keras模型實例,您將使用該實例來訓練/測試模型。
    model = Model(inputs = X_input, outputs = X, name='HappyModel')

    return model

創建實體、訓練和測試:

    # 創建一個模型實體
    happy_model = model(X_train.shape[1:])
    # 編譯模型
    happy_model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])
    # 訓練模型
    happy_model.fit(X_train, Y_train, epochs=40, batch_size=50)
    # 評估模型
    preds = happy_model.evaluate(X_test, Y_test, batch_size=32, verbose=1, sample_weight=None)  # verbose 日誌級別
    # 保存模型
    happy_model.save('happy_model.h5')
    print("誤差值 = " + str(preds[0]))
    print("準確度 = " + str(preds[1]))

輸出結果:

Loss = 0.0955250579119
Test Accuracy = 0.960000003974

然後我們可以進行簡單的測試:

    img_path = 'images/my_image.jpg'
    img = image.load_img(img_path, target_size=(64, 64))
    imshow(img)
    plt.show()

    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    happy_model = keras.models.load_model('./happy_model.h5')
    print(happy_model.summary())
    print(happy_model.predict(x))

                                        

Total params: 37,633
Trainable params: 37,569
Non-trainable params: 64
_________________________________________________________________
None
[[1.]]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章