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

以手写字符集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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值