from:https://blog.csdn.net/diamonjoy_zone/article/details/70904212
環境:Win8.1 TensorFlow1.0.1
軟件:Anaconda3 (集成Python3及開發環境)
TensorFlow安裝:pip install tensorflow (CPU版) pip install tensorflow-gpu (GPU版)
TFLearn安裝:pip install tflearn
參考:
Deep Residual Learning for Image Recognition Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
1. 前言
ResNet(Residual Neural Network)由前微軟研究院的 Kaiming He 等4名華人提出,通過使用 Residual Blocks 成功訓練152層深的神經網絡,在 ILSVRC 2015 比賽中獲得了冠軍,取得 3.57% 的 top-5 錯誤率,同時參數量卻比 VGGNet 低,效果非常突出。ResNet 的結構可以極快地加速超深神經網絡的訓練,模型的准確率也有非常大的提升。上一篇博文講解了 Inception,而 Inception V4 則是將 Inception Module 和 ResNet 相結合。可以看到 ResNet 是一個推廣性非常好的網絡結構,甚至可以直接應用到 Inception Net 中。
在 CVPR16 上何凱明、張祥雨、任少卿和孫劍四人的 Deep Residual Learning for Image Recognition 毫無爭議地獲得了 Best Paper。
關於這篇文章細節可參考:
2. 問題
作者首先提出的問題是,深度神經網絡是不是越深越好?
- 理想情況下,只要網絡不過擬合,應該是越深越好。
- 實際情況是網絡加深,accuracy 卻下降了,稱這種情況為 Degradation。(cnn中文漢字手寫識別構建網絡遇到過!)
LSTM 的提出者 Schmidhuber 早在 Highway Network 里指出神經網絡的深度對其性能非常重要,但是網絡越深其訓練難度越大,Highway Network 的目標就是解決極深的神經網絡難以訓練的問題。Highway Network 相當於修改了每一層的激活函數,此前的激活函數只是對輸入做一個非線性變換,Highway NetWork 則允許保留一定比例的原始輸入 x。(這種思想在inception模型也有,例如卷積是concat並行,而不是串行)這樣前面一層的信息,有一定比例可以不經過矩陣乘法和非線性變換,直接傳輸到下一層,仿佛一條信息高速公路,因此得名Highway Network:

ResNet 最初的靈感出自這個問題: 在不斷加神經網絡的深度時,會出現一個 Degradation 的問題,即准確率會先上升然后達到飽和,再持續增加深度則會導致准確率下降。這並不是過擬合的問題,因為不光在測試集上誤差增大,訓練集本身誤差也會增大。
假設有一個比較淺的網絡(Shallow Net)達到了飽和的准確率,那么后面再加上幾個的全等映射層(Identity mapping),起碼誤差不會增加,即更深的網絡不應該帶來訓練集上誤差上升。而這里提到的使用全等映射直接將前一層輸出傳到后面的思想,就是 ResNet 的靈感來源。
3. 組成
作者提出一個 Deep residual learning 框架來解決這種因為深度增加而導致性能下降問題。
假定某段神經網絡的輸入是 x,期望輸出是 H(x),即 H(x) 是期望的復雜潛在映射,但學習難度大;如果我們直接把輸入 x 傳到輸出作為初始結果,通過下圖“shortcut connections”,那么此時我們需要學習的目標就是 F(x)=H(x)-x,於是 ResNet 相當於將學習目標改變了,不再是學習一個完整的輸出,而是最優解 H(X) 和全等映射 x 的差值,即殘差
Shortcut 原意指捷徑,在這里就表示越層連接,在 Highway Network 在設置了一條從 x 直接到 y 的通路,以 T(x, Wt) 作為 gate 來把握兩者之間的權重;而 ResNet shortcut 沒有權值,傳遞 x 后每個模塊只學習殘差F(x),且網絡穩定易於學習,作者同時證明了隨着網絡深度的增加,性能將逐漸變好。可以推測,當網絡層數夠深時,優化 Residual Function:F(x)=H(x)−x,易於優化一個復雜的非線性映射 H(x)。
4. 網絡結構
下圖所示為 VGGNet-19,以及一個34層深的普通卷積網絡,和34層深的 ResNet 網絡的對比圖。可以看到普通直連的卷積神經網絡和 ResNet 的最大區別在於,ResNet 有很多旁路的支線將輸入直接連到后面的層,使得后面的層可以直接學習殘差,這種結構也被稱為 shortcut connections。傳統的卷積層或全連接層在信息傳遞時,或多或少會存在信息丟失、損耗等問題。ResNet 在某種程度上解決了這個問題,通過直接將輸入信息繞道傳到輸出,保護信息的完整性,整個網絡則只需要學習輸入、輸出差別的那一部分,簡化學習目標和難度。
同時34層 residual network 取消了最后幾層 FC,通過 avg pool 直接接輸出通道為1000的 Softmax,使得 ResNet 比16-19層 VGG 的計算量還低。
在 ResNet 的論文中,除了提出殘差學習單元的兩層殘差學習單元,還有三層的殘差學習單元。兩層的殘差學習單元中包含兩個相同輸出通道數(因為殘差等於目標輸出減去輸入,即,因此輸入、輸出維度需保持一致)的3´3卷積;而3層的殘差網絡則使用了 Network In Network 和 Inception Net 中的1´1卷積,並且是在中間3´3的卷積前后都使用了1´1卷積,先降維再升維的操作,降低計算復雜度。另外,如果有輸入、輸出維度不同的情況,我們可以對 x 做一個線性映射變換,再連接到后面的層。
5. 實驗
在使用了 ResNet 的結構后,可以發現層數不斷加深導致的訓練集上誤差增大的現象被消除了,ResNet 網絡的訓練誤差會隨着層數增大而逐漸減小,並且在測試集上的表現也會變好。最終在 ILSVRC 2015 比賽中獲得了冠軍,取得 3.57% 的 top-5 錯誤率。
tflearn 給出了 ResNet 在 CIFAR-10 上的實例 residual_network_cifar10.py,tflearn 通過 tflearn.residual_block 可以方便定義殘差學習單元:
- # -*- coding: utf-8 -*-
- """ Deep Residual Network.
- Applying a Deep Residual Network to CIFAR-10 Dataset classification task.
- References:
- - K. He, X. Zhang, S. Ren, and J. Sun. Deep Residual Learning for Image
- Recognition, 2015.
- - Learning Multiple Layers of Features from Tiny Images, A. Krizhevsky, 2009.
- Links:
- - [Deep Residual Network](http://arxiv.org/pdf/1512.03385.pdf)
- - [CIFAR-10 Dataset](https://www.cs.toronto.edu/~kriz/cifar.html)
- """
- from __future__ import division, print_function, absolute_import
- import tflearn
- # Residual blocks
- # 32 layers: n=5, 56 layers: n=9, 110 layers: n=18
- n = 5
- # Data loading
- from tflearn.datasets import cifar10
- (X, Y), (testX, testY) = cifar10.load_data()
- Y = tflearn.data_utils.to_categorical(Y, 10)
- testY = tflearn.data_utils.to_categorical(testY, 10)
- # Real-time data preprocessing
- img_prep = tflearn.ImagePreprocessing()
- img_prep.add_featurewise_zero_center(per_channel=True)
- # Real-time data augmentation
- img_aug = tflearn.ImageAugmentation()
- img_aug.add_random_flip_leftright()
- img_aug.add_random_crop([32, 32], padding=4)
- # Building Residual Network
- net = tflearn.input_data(shape=[None, 32, 32, 3],
- data_preprocessing=img_prep,
- data_augmentation=img_aug)
- net = tflearn.conv_2d(net, 16, 3, regularizer='L2', weight_decay=0.0001)
- net = tflearn.residual_block(net, n, 16)
- net = tflearn.residual_block(net, 1, 32, downsample=True)
- net = tflearn.residual_block(net, n-1, 32)
- net = tflearn.residual_block(net, 1, 64, downsample=True)
- net = tflearn.residual_block(net, n-1, 64)
- net = tflearn.batch_normalization(net)
- net = tflearn.activation(net, 'relu')
- net = tflearn.global_avg_pool(net)
- # Regression
- net = tflearn.fully_connected(net, 10, activation='softmax')
- mom = tflearn.Momentum(0.1, lr_decay=0.1, decay_step=32000, staircase=True)
- net = tflearn.regression(net, optimizer=mom,
- loss='categorical_crossentropy')
- # Training
- model = tflearn.DNN(net, checkpoint_path='model_resnet_cifar10',
- max_checkpoints=10, tensorboard_verbose=0,
- clip_gradients=0.)
- model.fit(X, Y, n_epoch=200, validation_set=(testX, testY),
- snapshot_epoch=False, snapshot_step=500,
- show_metric=True, batch_size=128, shuffle=True,
- run_id='resnet_cifar10')
6. 后續
在 ResNet 推出后不久,Google 就借鑒了 ResNet 的精髓,提出了 Inception V4 和 Inception-ResNet-V2,並通過融合這兩個模型,在 ILSVRC 數據集上取得了驚人的 3.08%的錯誤率。可見,ResNet 及其思想對卷積神經網絡研究的貢獻確實非常顯著,具有很強的推廣性。
在 ResNet 的作者的第二篇相關論文 Identity Mappings in Deep Residual Networks中,ResNet V2被提出。ResNet V2 和 ResNet V1 的主要區別在於,作者通過研究 ResNet 殘差學習單元的傳播公式,發現前饋和反饋信號可以直接傳輸,因此shortcut connection 的非線性激活函數(如ReLU)替換為 Identity Mappings。同時,ResNet V2 在每一層中都使用了 Batch Normalization。這樣處理之后,新的殘差學習單元將比以前更容易訓練且泛化性更強。