今天研究了一下卷积计算。
卷积涉及到的两个输入为: 图像和filter
图像: 维度为
C*H*W
C是channel, 也叫做 depth, H和W就是图像的宽和高了。filter, 维度为
K*K
, 假设 filter的个数为 M个
直接进行卷积的伪代码为
for w in 1..W (img_width)
for h in 1..H (img_height)
for x in 1..K (filter_width)
for y in 1..K (filter_height)
for m in 1..M (num_filters)
for c in 1..C (img_channel)
output(w, h, m) += input(w+x, h+y, c) * filter(m, x, y, c)
end
end
end
end
end
end
卷积之后的输出的维度为 num_filter* out_h * out_w
注意out_h 和 out_w 是img_h, img_w经过pading 和stride之后的宽高,计算公式为:
hout=himg+2Pading−KfilterhS+1
wout=wimg+2Pading−KfilterwS+1
这个后续再看
一个并行计算的课程:Berkeley’s CS267 (parallel computers)
有一个博士项目课题,卷积计算优化 [1] 就是im2col :
- having two layers of caching
- unrolled innermost computation, SSE2 (不能用AVX ).
卷积就变成了矩阵乘法 (Gemm in BLAS) . BLAS 库有(MKL, Atlas, CuBLAS)。这个算法最近被打败:Alex Krizhevsky’s 在 cuda-convnet [2]的优化 code [3]:
https://github.com/soumith/convnet-benchmarks
参考:Convolution-in-Caffe:-a-memo
另外,caffe里面还有dilation_h的定义,看caffe.proto里面的conv_parameters
int height_col = (height + 2 * pad_h -
(dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
int width_col = (width + 2 * pad_w -
(dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
一个简单的例子
参考:http://blog.csdn.net/xiaoyezi_1834/article/details/50786363