TensorFlow 卷積 padding 策略詳解

2021-03-02 慢慢學TensorFlow

卷積計算是 CNN 最核心的部分,而隨著網絡結構不斷推陳出新(LeNet-5、AlexNet、GoogLeNet、VGG、ResNet、DenseNet、SENet、Xception、ResNeXt、MobileNet、ShuffleNet、NASNet……),卷積類型越來越豐富(二維卷積、三維卷積、空洞卷積、空間可分離卷積、深度可分離卷積、反卷積、變形卷積……)。設計網絡時需要特別留意 padding 策略。

在 TensorFlow 中,padding 參數可選項有兩種:'SAME' 和 'VALID'。在 TF 1.7 API 中 conv2d 是長這樣的:


我們先看一個例子:假設輸入圖片尺寸為 5x5,卷積核尺寸為 3x3,做二維卷積時動圖如下:

其中虛線格子就表示 padding 的像素(值為 0)。經過 padding,實際輸入圖片尺寸變成了 7x7,卷積核在 7x7 範圍內滑動,分別每個位置產生一個輸出像素,最終輸出結果尺寸為 5x5。我們發現,輸出尺寸與原輸入尺寸相同,也就是所謂 'SAME' 方式 padding 名稱的由來。為了保證輸出與輸入尺寸一致,我們可以推出 'SAME'  padding 計算公式:

SAME PADDING 計算公式

output_h = input_h

output_w = input_w

pad_h = (kernel_h - 1)/2

pad_w = (kernel_w - 1)/2

前面例子中 kernel_h = kernel_w = 3,所以 pad_h = pad_w = (3 - 1)/2 = 1。

如前所述,使用 'SAME' padding 會在輸入圖片邊界處「無中生有」地加入了一些像素,這很可能破壞原始圖片的內容。而 'VALID' padding 則非常守規矩,卷積核只在「有效的」輸入像素點範圍內滑動。用公式表達就是:

VALID PADDING 計算公式

pad_h = 0

pad_w = 0

output_h = input_h - kernel_h + 1

output_w = input_w - kernel_w + 1

下圖為一個 'VALID' padding 例子,輸入圖片尺寸為 4x4,卷積核尺寸為 3x3,輸出尺寸為 2x2。

以上討論都是在 stride == 1 和 dilation == 1 時的情況。

當 dilation > 1 時,先計算擴張卷積核尺寸:

dilation_kernel_h = (kernel_h - 1) * dilation_h + 1

dilation_kernel_w = (kernel_w - 1) * dilation_w + 1

之後再將 dilation_kernel_h、dilation_kernel_w 代入前面不同 padding 公式即可得到對應的 padding 尺寸和輸出尺寸。一個例子如下:

輸入圖片尺寸為 7x7,卷積核尺寸為 3x3,擴張率為 2x2,使用 'VALID' padding 方法。首先得到擴張後卷積核尺寸為 (3 - 1) * 2 + 1 = 5,即等效為 5x5 卷積核。將該值代入 'VALID' padding 公式,得到輸出尺寸為:7 - 5 + 1 = 3,即 3x3,與圖中顯示一致。

當 stride > 1 時,即使使用 'SAME' padding 方式,輸出尺寸依然小於輸入尺寸,只是沿用了 stride == 1 的稱謂。

SAME PADDING 計算公式(stride > 1)

output_h = ceil(input_h / stride_h)

output_w = ceil(input_w / stride_w)

pad_h = ((output_h - 1) * stride_h + kernel_h - input_h) / 2

pad_w = ((output_w - 1) * stride_w + kernel_w - input_w) / 2

如上圖為 stride = 2 的情況,輸入尺寸為 5x5,卷積核尺寸 3x3。首先通過公式計算得到輸出尺寸:output_h = output_w = ceil(5/2) = ceil(2.5) = 3,即 3x3;然後利用公式計算 pad_h = pad_w = ((3 - 1) * 2 + 3 - 5)/2 = 1,與圖中一致。

當 stride > 1 時,使用 'VALID' padding 方式,計算過程仍滿足卷積核只在「有效的」輸入像素點範圍內滑動的約束。

VALID PADDING 計算公式(stride > 1)

pad_h = 0

pad_w = 0

output_h = ceil((input_h - kernel_h + 1) / stride_h)

output_w = ceil((input_w - kernel_w + 1) / stride_w)

上圖中 input : 5x5,kernel : 3x3,stride : 2x2,output : 2x2,請讀者自行核算。

另外,MaxPool 和 AvePool 的輸出尺寸計算公式也可從上面公式推導得到。

參考:

【1】 https://github.com/vdumoulin/conv_arithmetic

【2】 TensorFlow 源碼 v1.7

相關焦點

  • 擴展之Tensorflow2.0 | 21 Keras的API詳解(上)卷積、激活、初始化、正則
    None,    activity_regularizer=None,    kernel_constraint=None,    bias_constraint=None,    **kwargs)先看一個簡單的例子:import tensorflow
  • TensorFlow安裝與卷積模型
    使用pip安裝1)下載安裝Python 2)打開windows的命令行窗口,安裝CPU版本pip installtensorflow安裝GPU版本Pip install tensorflow-gpu之後驗證是否安裝了 TensorFlow 可以嘗試一下代碼>>> importtensorflow
  • 關於Padding實現的一些細節
    ,這與paddding運算的目的相悖如果padding的值是一個非常小的值,假設是負無窮,在上面的情形下看似不影響結果,但是無法適用於更多的情況,比如卷積,比如平均池化。這是兩種處理padding的方案,pytorch採用的是第一種,即在卷積或池化時先確定padding數量,自動推導輸出形狀;tensorflow和caffe採用的是更為人熟知的第二種,即先根據Valid還是Same確定輸出大小,再自動確定padding的數量Valid和Same是預設的兩種padding模式,Valid指不padding,same指輸出大小儘可能和輸入大小成比例
  • 使用tensorflow layers相關API快速構建卷積神經網絡
    首先需要詳解的介紹一下卷積層與池化層API與參數。tf.layers.conv2d是卷積層組件、定義與參數解釋如下:conv2d(    inputs,    filters,    kernel_size,    strides=(1, 1),    padding='valid',    data_format='channels_last',    dilation_rate
  • Tensorflow.keras筆記-卷積神經網絡
    給圖識物#載入包import tensorflow as tfimport osimport numpy as npfrom matplotlib import pyplot as pltfrom tensorflow.keras.layers import Conv2D,BatchNormalization,Activation,MaxPool2D
  • TensorFlow layers模塊用法
    概覽layers 模塊的路徑寫法為 tf.layers,這個模塊定義在 tensorflow/python/layers/layers.py,其官方文檔地址為:https://www.tensorflow.org/api_docs/python/tf/layers,TensorFlow 版本為 1.5。這裡面提供了多個類和方法以供使用,下面我們分別予以介紹。
  • Fast-SCNN的解釋以及使用Tensorflow 2.0的實現
    pip install tensorflow-gpu==2.0.0這裡,' -gpu '說明我的谷歌Colab筆記本使用GPU,而在你的情況下,如果你不喜歡使用它,你可以簡單地刪除' -gpu ',然後Tensorflow安裝將利用系統的cpu。
  • 擴展之Tensorflow2.0 | 19 TF2模型的存儲與載入
    擴展之Tensorflow2.0 | 18 TF2構建自定義模型擴展之Tensorflow2.0
  • 乾貨 TensorFlow之深入理解AlexNet
    基於ReLU的深度卷積網絡比基於tanh的網絡訓練塊數倍,下圖是一個基於CIFAR-10的四層卷積網絡在tanh和ReLU達到25%的training error的迭代次數:import imreadfrom scipy.misc import imresizeimport matplotlib.image as mpimgfrom scipy.ndimage import filtersimport urllibfrom numpy import randomimport tensorflow
  • TensorFlow開發者證書 中文手冊
    要獲得證書需要理解如何使用計算機視覺、卷積神經網絡、自然語言處理以及真實世界的圖像數據和策略來構建TensorFlow模型。、目標檢測、文本識別算法使用不同尺寸的真實圖像通過卷積提取體現特徵,理解計算機如何「看到」信息,繪製損失和精度曲線嘗試防止過擬合的策略,包括數據增強和dropout用神經網絡求解自然語言處理問題
  • TensorFlow之CNN
    這是奔跑的鍵盤俠的第190篇文章作者|我是奔跑的鍵盤俠 來源|奔跑的鍵盤俠(ID:runningkeyboardhero)轉載請聯繫授權(微信ID:ctwott)接上一篇,我們繼續……CNN 就是convolutional neural network, 也就是卷積神經網絡,是一種類似於人類或動物視覺系統結構的人工神經網絡,包含一個或多個卷積層
  • TensorFlow Eager圖文教程(附9張圖解和Jupyter)
    Jupyter:https://github.com/madalinabuzau/tensorflow-eager-tutorials/blob/master/03_save_and_restore_model.ipynb
  • Tensorflow之 CNN卷積神經網絡的MNIST手寫數字識別
    如果你尚未了解,請查看MNIST For ML Beginners(https://www.tensorflow.org/get_started/mnist/beginners)。在學習教程之前,請確保已經安裝Install TensorFlow(https://www.tensorflow.org/install/)。
  • mnist tensorflow 預測專題及常見問題 - CSDN
    , lsize=4) 78 79 # 第三層卷積 80 # 卷積 81 conv3 = conv2d('conv3', norm2, _weights['wc3'], _biases['bc3']) 82 # 歸一化 83 norm3 = norm('norm3', conv3, lsize=4) 84 85 # 第四層卷積 86 # 卷積
  • 人工智慧TensorFlow(十五)CNN 結構(代碼實現)
    1、插入MNIST數據集  import tensorflow as tfimport numpy as npfromtensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets('MNIST_data', one_hot=True)  2、精度定義函數  def compute_accuracy
  • GitHub趨勢榜第一:TensorFlow+PyTorch深度學習資源大匯總
    感知器TensorFlow 1:https://github.com/rasbt/deeplearning-models/blob/master/tensorflow1_ipynb/basic-ml/perceptron.ipynbPyTorch:https://github.com/rasbt/
  • 深度學習筆記13:Tensorflow實戰之手寫mnist手寫數字識別
    數據挖掘與機器學習,R與Python,理論與實踐並行。個人公眾號:數據科學家養成記 (微信ID:louwill12)前文傳送門:深度學習筆記1:利用numpy從零搭建一個神經網絡深度學習筆記2:手寫一個單隱層的神經網絡深度學習筆記3:手動搭建深度神經網絡(DNN)深度學習筆記4:深度神經網絡的正則化深度學習筆記5:正則化與dropout
  • 深度學習筆記16:CNN經典論文研讀之AlexNet及其Tensorflow實現
    所以 AlexNet 的簡略結構如下:輸入>卷積>池化>卷積>池化>卷積>卷積>卷積>池化>全連接>全連接>全連接>輸出各層的結構和參數如下:C1層是個卷積層,其輸入輸出結構如下:輸入: 227 x 227 x 3  濾波器大小: 11 x 11 x 3   濾波器個數:96輸出:
  • 如何從Tensorflow中創建CNN,並在GPU上運行該模型(附代碼)
    卷積,池化和完全連接層。這些組件協同工作來學習輸入密集的特徵表達。卷積要計算池操作的輸出大小,可以使用公式 (輸入寬度 - 內核寬度+ 2 * padding)/ strides + 1。 回顧你現在已經了解了什麼構成卷積神經網絡。通過卷積輸入,您可以提取高維度特徵。匯總空間信息並降低維度。最後,該特徵表示通過完全連接的層傳遞到分類器或回歸器。
  • TensorFlow 入門(MNIST數據集)
    包括全連接層,卷積層,激活函數,dropout regularization。在本文中,將構建CNN網絡來進行手寫數字識別。  MNIST數據集包括60000個訓練樣本,10000個測試樣本,每個樣本為28*28像素的圖片。