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.cpp
中im2col_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中對於越界問題的處理如圖所示: