簡單人臉識別二之使用opencv+殘差網絡實現人臉識別

時隔半年,終於想着要把這個人臉識別的系列給補充完了,在家實在是太無聊了啊!!!因爲這個系列也是拿來做畢設的,所以想着比較有回憶,就堅持把他寫完了。

上一篇文章,我是用opencv+簡單的cnn網絡實現了人臉識別,cnn網絡是用來分類的,因爲只有三層,覺得太簡單了,剛好那段時間在學習殘差網絡相關的內容,就想着把殘差網絡給應用到分類網絡裏。針對殘差網絡,一般而言常用的就是三種:ResNet, DenseNet以及RDN. 三個網絡的論文鏈接我也貼出來了,值得一看啊,都是頂會的。

  1. Deep Residual Learning for Image Recognition
  2. Densely Connected Convolutional Networks
  3. Residual Dense Network for Image Super-Resolution

這三種網絡,如果要論效果看的話,那就是ResNet<DenseNet<RDN,在此次試驗中,我用的是DenseNet網絡,因爲對於一般的層數較少的模型來說,DenseNet近似於RDN,具體結構如下:

簡而言之,就是當前Conv卷積層的輸入是之前所有卷積層的輸出,表示爲concat()操作。改進版的模型代碼如下:

# 該網絡爲DenseNet殘差網絡+CNN卷積神經網絡
def build_model(input_data, nb_classes=2):
    x1 = Conv2D(32, (3, 3), activation="relu", padding="same", strides=(1, 1))(input_data)

    x1 = BatchNormalization()(x1)
    x1 = Activation("relu")(x1)
    x2 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x1)
    x2 = Dropout(rate=0.5)(x2)

    x3 = concatenate([x1, x2], axis=3)
    x3 = BatchNormalization()(x3)
    x3 = Activation("relu")(x3)
    x4 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x3)
    x4 = Dropout(rate=0.5)(x4)

    x5 = concatenate([x1, x2], axis=3)
    x5 = BatchNormalization()(x5)
    x5 = Activation("relu")(x5)
    x6 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x5)
    x6 = Dropout(rate=0.5)(x6)
    x6 = MaxPooling2D(pool_size=(2, 2))(x6)

    conv_input = Flatten()(x6)
    dense_result = Dense(256, activation="relu")(conv_input)
    drop_result = Dropout(rate=0.5)(dense_result)
    # 該結果爲[0, 1]類似這樣的矩陣,矩陣中第一個值爲我們的判斷結果
    output = Dense(nb_classes, activation="softmax")(drop_result)
    return output

其他的地方和我上一篇文章介紹的代碼都一樣,就是此處的分類網絡改變了。先說說我訓練的效果吧,由於網絡層數增加了,訓練時間也是增加了,我記得我當時是用了三個人的圖片數據集,每個人有200張照片吧,訓練是花了三個小時左右,沒有用GPU,所以還是要花些時間吧,有GPU條件的在GPU上跑會快很多。

最後,我想再提一提自己對於殘差網絡的理解。我搜到的百度詞條是說:殘差網絡的特點是容易優化,並且能夠通過增加相當的深度來提高準確率。其內部的殘差塊使用了跳躍連接,緩解了在深度神經網絡中增加深度帶來的梯度消失問題。

這一點看上去寫的很對,但如果你做了一些實驗之後,會發現在淺層網絡中,使用了殘差網絡會比沒使用殘差網絡耗時更長,。然而網上很多文章是說殘差網絡縮短了訓練時間,優化了計算量。我覺得要辯證的看,如果是覺得因爲解決了梯度擴散而減少了訓練時間,那麼可能還不足夠說服人。梯度彌散/爆炸問題導致模型訓練難以收斂,但是這個問題很大程度上已經被標準初始化和中間層正規化方法有效控制了,比如:BatchNormalization操作。所以我覺得殘差網絡的優勢應該不是體現在縮短了訓練時間,而是有效緩解了網絡退化問題,網絡退化是由於訓練次數過多,模型效果反而變差了,這其實也就是梯度消失的結果。可以認爲殘差連接使得信息前後向傳播更加順暢。而且殘差網絡展開後的路徑具有一定的獨立性和冗餘性,使得殘差網絡表現得像一個集成模型(ensemble)

關於殘差網絡的思考參考這篇文章,感謝作者!!! 

如果大家有更好的看法,也希望積極留言評論!

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