1. 程式人生 > >Caffe(6)--卷積、池化後輸出影象尺寸計算

Caffe(6)--卷積、池化後輸出影象尺寸計算

在影象卷積和池化操作中有固定的kernel_size和stride,當stride > 1時,邊界上會有可能發生越界的問題。

Caffe中的卷積、池化後輸出影象尺寸計算

(1)卷積

計算定義在conv_layer.cpp中的compute_output_shape()函式中
這裡寫圖片描述

const int output_h = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
const int output_w = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;

height、width :卷積操作輸入的影象h、w,conv_input_shape_.cpu_data()[1], conv_input_shape_.cpu_data()[2]
kernel_h、kernel_w:卷積核的h、w,kernel_shape_.cpu_data()[0], kernel_shape_.cpu_data()[1]
stride_h、stride_w:步長的h、w,stride_.cpu_data()[0], stride_.cpu_data()[1]
pad_h、pad_w:zero padding的h、w,pad_.cpu_data()[0], pad_.cpu_data()[1]

caffe的卷積操作:將kernel轉為channel*kernel_h*kernel_w大小的一維行向量,例如CIFAR10 接data層的conv1,對於3*32*32的輸入,那在conv1中卷積核就是3*5*5的一維行向量。然後將3*32*32的輸入影象按3*5*5的長度轉換為多個列向量。最後通過求向量的點積完成卷積運算。

注:channel不是指輸入影象的通道數,其指的是輸入到卷積層的通道數,比如接pooling1的conv2,輸入為32*16*16的特徵圖,那麼kernel則轉換為32*5*5的一維行向量,特徵圖對應轉為32*5*5長度的多個列向量。

im2col.cppim2col_cpu()

函式實現了轉換輸入為列向量的操作:

這裡寫圖片描述

(2)池化

pooled_height_ = static_cast<int>(ceil(static_cast<float>(height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
pooled_width_ = static_cast<int>(ceil(static_cast<float>(width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;

定義在pooling_layer.cpp
CIFAR10中的pooling1,kernel為33,stride為2,pad未定義,輸入為conv1得到的3232*32的特徵圖,

pooled_height_=static_cast<int>(ceil(static_cast<float>(32+2*0-3)/2))+1=static_cast<int>(ceil(14.5))+1=16

ceil為向上取整
所以,pooling1的輸出為32*16*16

Caffe中對於越界問題的處理如圖所示:
這裡寫圖片描述