caffe源码学习(3)--卷积层

来源:互联网 发布:tinyumbrella官网 mac 编辑:程序博客网 时间:2024/05/21 01:46

以手写字符集mnist为例介绍caffe卷积层的实现方式。

1.卷积层C1 源码

在卷积层类ConvolutionLayer中,batch(训练 64*3*28*28,测试 100*3*28*28)中每个样本循环调用前向运算ConvolutionLayer::Forward_cpu()函数计算featrue map。
  函数源码如下:

template <typename Dtype>void ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,      const vector<Blob<Dtype>*>& top) {  const Dtype* weight = this->blobs_[0]->cpu_data();  for (int i = 0; i < bottom.size(); ++i) {    const Dtype* bottom_data = bottom[i]->cpu_data();    Dtype* top_data = top[i]->mutable_cpu_data();    for (int n = 0; n < this->num_; ++n) {      this->forward_cpu_gemm(bottom_data + n * this->bottom_dim_, weight,          top_data + n * this->top_dim_);      if (this->bias_term_) {        const Dtype* bias = this->blobs_[1]->cpu_data();        this->forward_cpu_bias(top_data + n * this->top_dim_, bias);      }    }  }}

Forward_cpu()函数内部又调用forward_cpu_gemm()实现卷积运算:

template <typename Dtype>void BaseConvolutionLayer<Dtype>::forward_cpu_gemm(const Dtype* input,    const Dtype* weights, Dtype* output, bool skip_im2col) {  const Dtype* col_buff = input;  if (!is_1x1_) {    if (!skip_im2col) {      conv_im2col_cpu(input, col_buffer_.mutable_cpu_data());    }    col_buff = col_buffer_.cpu_data();  }  for (int g = 0; g < group_; ++g) {    caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, conv_out_channels_ /        group_, conv_out_spatial_dim_, kernel_dim_,        (Dtype)1., weights + weight_offset_ * g, col_buff + col_offset_ * g,        (Dtype)0., output + output_offset_ * g);  }}

其中:
  input:输入原始图像指针 【3*28*28】 ;(注意:为了验证多通道卷积原理,此处将mnist数据集改为3通道)
  weights:卷积核指针 【 3*5*5】;
  output:输出feature map 【20*24*24】
该函数内部又调用conv_im2col_cpu()和caffe_cpu_gemm();
  总的调用关系如下:
  这里写图片描述
  conv_im2col_cpu()函数实现将多通道图像展开成大的矩阵,有利于后续将卷积操作转化为矩阵相乘操作。caffe_cpu_gemm()主要实现矩阵相乘。

2. caffe多个输入通道和多个输出通道的卷积实现方式

  当有Ci个输入通道,Co个输出通道,则需要训练的卷积核为Co*Ci个。其中,Ci个不同的卷积核分别与Ci个图像通道进行卷积(Ci个核为一批),然后将Ci个输出求和输出一个卷积结果。其他卷积层输出与以上操作一致。
  这里写图片描述
  conv_im2col_cpu()是关键,函数功能:
  将多通道图像展开成矩阵,有利于后续将卷积操作变换为矩阵相乘。展开方式为:按照卷积核的大小展开成列。

  • 展开后的大矩阵的行为:Ci个核的总像素数
  • 展开后的大矩阵的列为:卷积结果图像像素数

这里写图片描述

0 0
原创粉丝点击