你必須要知道CNN模型:ResNet

2021-02-20 機器學習算法工程師

ResNet網絡是參考了VGG19網絡,在其基礎上進行了修改,並通過短路機制加入了殘差單元,如圖5所示。變化主要體現在ResNet直接使用stride=2的卷積做下採樣,並且用global average pool層替換了全連接層。ResNet的一個重要設計原則是:當feature map大小降低一半時,featuremap的數量增加一倍,這保持了網絡層的複雜度。從圖5中可以看到,ResNet相比普通網絡每兩層間增加了短路機制,這就形成了殘差學習,其中虛線表示featuremap數量發生了改變。圖5展示的34-layer的ResNet,還可以構建更深的網絡如表1所示。從表中可以看到,對於18-layer和34-layer的ResNet,其進行的兩層間的殘差學習,當網絡更深時,其進行的是三層間的殘差學習,三層卷積核分別是1x1,3x3和1x1,一個值得注意的是隱含層的feature map數量是比較小的,並且是輸出feature map數量的1/4。

圖5 ResNet網絡結構圖

 

 

表1 不同深度的ResNet

下面我們再分析一下殘差單元,ResNet使用兩種殘差單元,如圖6所示。左圖對應的是淺層網絡,而右圖對應的是深層網絡。對於短路連接,當輸入和輸出維度一致時,可以直接將輸入加到輸出上。但是當維度不一致時(對應的是維度增加一倍),這就不能直接相加。有兩種策略:(1)採用zero-padding增加維度,此時一般要先做一個downsamp,可以採用strde=2的pooling,這樣不會增加參數;(2)採用新的映射(projection shortcut),一般採用1x1的卷積,這樣會增加參數,也會增加計算量。短路連接除了直接使用恆等映射,當然都可以採用projection shortcut。

圖6 不同的殘差單元

作者對比18-layer和34-layer的網絡效果,如圖7所示。可以看到普通的網絡出現退化現象,但是ResNet很好的解決了退化問題。

圖7 18-layer和34-layer的網絡效果

最後展示一下ResNet網絡與其他網絡在ImageNet上的對比結果,如表2所示。可以看到ResNet-152其誤差降到了4.49%,當採用集成模型後,誤差可以降到3.57%。

 

 

表2 ResNet與其他網絡的對比結果

說一點關於殘差單元題外話,上面我們說到了短路連接的幾種處理方式,其實作者在文獻[2]中又對不同的殘差單元做了細緻的分析與實驗,這裡我們直接拋出最優的殘差結構,如圖8所示。改進前後一個明顯的變化是採用pre-activation,BN和ReLU都提前了。而且作者推薦短路連接採用恆等變換,這樣保證短路連接不會有阻礙。感興趣的可以去讀讀這篇文章。

圖8 改進後的殘差單元及效果

這裡給出ResNet50的TensorFlow實現,模型的實現參考了Caffe版本的實現(https://github.com/KaimingHe/deep-residual-networks),核心代碼如下:

class ResNet50(object):
 def __init__(self, inputs,num_classes=1000, is_training=True,scope="resnet50"):
 self.inputs =inputs
 self.is_training =is_training
 self.num_classes =num_classes
 with tf.variable_scope(scope):
    # construct themodel
  net =conv2d(inputs, 64, 7, 2, scope="conv1")#->
 [batch,112, 112, 64]
  net = tf.nn.relu(batch_norm(net,is_training=self.is_training, scope="bn1"))
  net = max_pool(net, 3, 2, scope="maxpool1")#->
[batch, 56, 56, 64]
  net = self._block(net, 256, 3, init_stride=1, is_training=self.is_training,scope="block2")# ->
[batch, 56,56, 256]
  net = self._block(net, 512, 4, is_training=self.is_training, scope="block3")#->
[batch, 28, 28, 512]
  net = self._block(net, 1024, 6, is_training=self.is_training,scope="block4")#->
[batch, 14, 14, 1024]
  net = self._block(net, 2048, 3, is_training=self.is_training, scope="block5")#->
[batch, 7, 7, 2048]
  net =avg_pool(net, 7, scope="avgpool5")#->
[batch, 1,1, 2048]
  net =tf.squeeze(net, [1, 2],
           name="SpatialSqueeze")#->
[batch,2048]
  self.logits = fc(net, self.num_classes,"fc6")#->
[batch,num_classes]
  self.predictions =tf.nn.softmax(self.logits)
  def _block(self, x, n_out, n,init_stride=2, is_training=True, scope="block"):
   with tf.variable_scope(scope):
   h_out = n_out
   out = self._bottleneck(x,h_out, n_out,      stride=init_stride,is_training=is_training, scope="bottlencek1")
   for i in range(1, n):
     out = self._bottleneck(out,h_out, n_out, is_training=is_training,scope=("bottlencek%s"% (i + 1)))
     return out
   def _bottleneck(self, x, h_out, n_out,stride=None, is_training=True, scope="bottleneck"):
   """A residual bottleneck unit"""
    n_in =x.get_shape()[-1]
    if stride is None:
     stride = 1 if n_in == n_out else 2
    with tf.variable_scope(scope):
      h = conv2d(x, h_out, 1, stride=stride, scope="conv_1")
      h = batch_norm(h, is_training=is_training, scope="bn_1")
      h = tf.nn.relu(h)
      h = conv2d(h, h_out, 3, stride=1, scope="conv_2")
      h = batch_norm(h, is_training=is_training, scope="bn_2")
      h = tf.nn.relu(h)
      h = conv2d(h, n_out, 1, stride=1, scope="conv_3")
      h = batch_norm(h, is_training=is_training, scope="bn_3")
    if n_in != n_out:
      shortcut = conv2d(x,n_out, 1, stride=stride, scope="conv_4")
      shortcut =batch_norm(shortcut, is_training=is_training, scope="bn_4")
     else:
       shortcut = x
       return tf.nn.relu(shortcut+ h)

 

完整實現可以參見GitHub(https://github.com/xiaohu2015/DeepLearning_tutorials/)。

相關焦點

  • ResNet——CNN經典網絡模型詳解(pytorch實現)
    ResNet的結構可以極快的加速神經網絡的訓練,模型的準確率也有比較大的提升。同時ResNet的推廣性非常好,甚至可以直接用到InceptionNet網絡中。下圖是ResNet34層模型的結構簡圖。如下圖所示,該殘差結構的主分支是由兩層3x3的卷積層組成,而殘差結構右側的連接線是shortcut分支也稱捷徑分支(注意為了讓主分支上的輸出矩陣能夠與我們捷徑分支上的輸出矩陣進行相加,必須保證這兩個輸出特徵矩陣有相同的shape)。如果剛剛仔細觀察了ResNet34網絡結構圖的同學,應該能夠發現圖中會有一些虛線的殘差結構。
  • CNN 原理與實踐指南
    特別是在計算機視覺領域,CNN是解決圖像分類、圖像檢索、物體檢測和語義分割的主流模型。1. 卷積如圖1所示,圖中的X和O無論怎麼旋轉或者縮放,人眼其實還是很容易識別出X和O。圖1但是計算機不同,它看到的其實是一個個的像素陣列,如圖2。如何對像素的陣列進行特徵的提取其實就是卷積神經網絡要幹的事情。
  • CNN原理與實踐指南
    特別是在計算機視覺領域,CNN是解決圖像分類、圖像檢索、物體檢測和語義分割的主流模型。1. 卷積如圖1所示,圖中的X和O無論怎麼旋轉或者縮放,人眼其實還是很容易識別出X和O。圖1但是計算機不同,它看到的其實是一個個的像素陣列,如圖2。如何對像素的陣列進行特徵的提取其實就是卷積神經網絡要幹的事情。
  • CNN系列-神經網絡模型結構設計的演變和理解
    思路一:加深加寬想提升網絡精度,最樸素的方法就是加深加寬網絡,提升模型複雜度來增強擬合能力。但會存在兩個問題:一是容易過擬合,測試集不準;二是梯度容易不穩定,模型難訓練。所以早期的alexnet、inception、resnet研究各種方法在模型加寬加深的防止模型過擬合和梯度不穩定等。思路二:網絡優化如果不加寬加深,則需要進一步優化現有網絡的性能。那該怎麼優化呢?
  • 架構模型技巧全都有,大牛LeCun推薦
    /cnn/cnn-allconv.ipynbAlexnet網絡模型在CIFAR-10數據集上的實現:PyTorch版https://github.com/rasbt/deeplearning-models/blob/master/pytorch_ipynb/cnn/cnn-alexnet-cifar10.ipynb關於VGG模型,你可能需要了解VGG-16架構
  • 如果我們想要更好的目標分割,我們最好使用resnet-50的網絡結構
    每次檢測框架都需要fasterr-cnn,需要計算卷積,網絡結構是knet,包括maxpooling,relu和stridedpooling。然後經過全連接層和全連接層到隱藏層。最後經過一個residualnetwork卷積-池化層就產生一個文字框架(基於不同數據集的使用):使用fasterr-cnn和resnet的文字檢測和分割(最後部分全連接)圖像預處理經過上面的方法,基本已經看到結果了。但是,如果我們想要更好的目標分割,我們需要使用resnet-50的網絡結構。我們還可以增加一些尺度不同的錨框(使用全連接層),以獲得更好的精度,但是這個仍然是在全連接層中做的。
  • 你有哪些深度學習(rnn、cnn)調參的經驗?
    你有哪些深度學習(rnn、cnn)調參的經驗?解析:解析一@陳運文:cnn的調參主要是在優化函數、embedding的維度還要殘差網絡的層數幾個方面。優化函數方面有兩個選擇:sgd、adam,相對來說adam要簡單很多,不需要設置參數,效果也還不錯。
  • ResNet告訴我,我是不是世界上最美的人?
    數據集中還包括一些明星。這張Julia Roberts的照片平均得分為3.78:在這篇文章中,我要復現他們的結果,並測一下自己的顏值。原始論文構造了一系列不同的模型,包括使用人工構造特徵的經典ML模型和3種深度學習模型:AlexNet、ResNet18和ResNext50,我希望儘可能簡化我的工作(我不想從頭開始訓練Resnet神經網絡模型),我想對現有的模型進行調優。
  • CNN:我不是你想的那樣
    其實你可能冤枉它了,而本文試圖為它進行辯護。    本文是cvpr2020 oral論文,核心是從數據高低頻分布上探討CNN泛化能力,其注意到CNN具備捕獲人類無法感知的高頻成分能力,而這個現象可以用於解釋多種人類無法理解的假設,例如泛化能力、對抗樣本魯棒性等。
  • 「模型解讀」resnet中的殘差連接,你確定真的看懂了?
    編輯 | 言有三1 殘差連接想必做深度學習的都知道skip connect,也就是殘差連接,那什麼是skip connect呢?如下圖上面是來自於resnet【1】的skip block的示意圖。但為什麼這篇文章沒有resnet火呢?原因自然有很多了,何的文章做了更多的實驗論證,簡化了上面的式子,得了cvpr best paper,以及何的名氣更大等等因素。總之,為我們所知道的就是下面的式子y = H(x,WH) + X,此所謂殘差連接,skip connection。
  • 【專知-PyTorch手把手深度學習教程02】CNN快速理解與PyTorch實現: 圖文+代碼
    CNN>< 快速理解系列(二): 圖文+代碼, 讓你快速理解LSTM>< 快速理解系列(三): 圖文+代碼, 讓你快速理解GAN >< 快速理解系列(四): 圖文+代碼, 讓你快速理解Dropout >
  • 經典CNN網絡(Lenet、Alexnet、GooleNet、VGG、ResNet、DenseNet)
    Alexnet(2012)卷積部分都是畫成上下兩塊,意思是說把這一層計算出來的feature map分開,但是前一層用到的數據要看連接的虛線。圖:inception v1    Googlenet的核心思想是inception,通過不垂直堆砌層的方法得到更深的網絡(我的理解是變寬且視野範圍種類多,vgg及resnet
  • 一文帶你讀懂計算機視覺
    -36d53571365e a comparison of r-cnn, fast r-cnn, faster r-cnn and yolo最近深度學習的迅速發展,可以看到許多新架構取得了很大成功。有關resnet的預訓練模型,請訪問: https://github.com/tensorflow/tensor2tensor#image-classification人臉識別就是要弄清楚誰是一張臉。
  • 視覺工具包torchvision重大更新:支持分割模型、檢測模型
    這些腳本可以當做log:寫著某一個特定的模型要怎樣訓練,並且提供了基線。有了這份快速指引,便於順利展開研究。torchvision算子就像開頭提到的那樣,torchvision這次有了定製的C++/CUDA算子,計算機視覺專用。
  • PyTorch實現TPU版本CNN模型
    本文演示了如何使用PyTorch和TPU實現深度學習模型,以加快訓練過程。在這裡,我們使用PyTorch定義了一個卷積神經網絡(CNN)模型,並在PyTorch/XLA環境中對該模型進行了訓練。你也可以通過列印TPU地址來檢查TPU。TPU_Path = 'grpc://'+os.environ['COLAB_TPU_ADDR']print('TPU Address:', TPU_Path)
  • 小白學CNN以及Keras的速成
    雖然說tensorflow已經是一個封裝好的框架,但是你發現你寫一個簡單的神經網絡也需要很多行才能夠寫完,這個時候,就有很多的第三方插架來幫助你寫網絡,也就是說你用tensorflow要寫10行,第三方插架幫你封裝了一個函數,就是把這10行集合在這個函數裡面,那麼你用1行,傳入相同的參數,就能夠達到10行相同的效果,如此簡便並且節約時間,可以幫助很快的實現我們的想法。
  • VGGNet、ResNet、Inception和Xception圖像分類及對比
    在這種背景下,目標是訓練一個模型,可以將輸入圖像分類為 1000 個獨立的對象類別。本節將使用由超過 120 萬幅訓練圖像、50000 幅驗證圖像和 100000 幅測試圖像預訓練出的模型。由於 Xception 架構具有與 Inception-v3 相同的參數數量,因此性能提升不是由於容量的增加,而是由於更高效地使用了模型參數。圖像分類準備工作本節使用 Keras 因為這個框架有上述模塊的預處理模塊。Keras 在第一次使用時會自動下載每個網絡的權重,並將這些權重存儲在本地磁碟上。換句話說,你不需要重新訓練網絡,而是使用網際網路上已有的訓練參數。
  • 理解並實現 ResNet(Keras)
    為什麼要跳過連接? 這是個有趣的問題。你可以用一行的代碼來加載這個模型:base_model = applications.resnet50.ResNet50(weights= None, include_top=False, input_shape= (img_height,img_width,3))在這裡weights=None,因為我想用隨機權重初始化模型,就像我在