学习Caffe(三)Caffe卷积实现解析并手写前馈网络Armadillo+Opencv

本文介绍如何通过矩阵相乘实现图像卷积,并详细解释了Caffe中im2col函数的工作原理。此外,还展示了如何使用Armadillo库构建简单的前馈神经网络。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图像卷积的实现

矩阵相乘

卷积是乘累加运算,把图像和卷积核展开成列,可用矩阵相乘加速运算。比如,输入feature map是32*32*3,卷积核是5*5*3*20,padding是1,stride是1,则展开后得到的feature map矩阵宽度是5*5*3,高度是((32+2*1-5)/1+1)*((32+2*1-5)/1+1),卷积核矩阵高度是5*5*3,宽度是20。
Caffe中相关代码在im2col.cpp:

template <typename Dtype>
void im2col_cpu(const Dtype* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w,
    const int stride_h, const int stride_w,
    const int dilation_h, const int dilation_w,
    Dtype* data_col) {
    //计算输出的大小
  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;
  const int channel_size = height * width;
  //遍历,把kernel放在图像上扫,从kernel的第一个元素开始
  for (int channel = channels; channel--; data_im += channel_size) {
    for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) {
      for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
        int input_row = -pad_h + kernel_row * dilation_h;
        for (int output_rows = output_h; output_rows; output_rows--) {
          if (!is_a_ge_zero_and_a_lt_b(input_row, height)) {
          //Padding
            for (int output_cols = output_w; output_cols; output_cols--) {
              *(data_col++) = 0;
            }
          } else {
            int input_col = -pad_w + kernel_col * dilation_w;
            for (int output_col = output_w; output_col; output_col--) {
              if (is_a_ge_zero_and_a_lt_b(input_col, width)) {
                *(data_col++) = data_im[input_row * width + input_col];
              } else {
                *(data_col++) = 0;
              }
              input_col += stride_w;
            }
          }
          input_row += stride_h;
        }
      }
    }
  }
}

im2col的过程

手写前馈网络

前馈网络实际就是一些矩阵运算。这里我们选用Armadillo作为矩阵库,这是个操作比较接近matlab的库。首先我们把Caffe中的一些基础的层剥离出来。然后再实现我们自己的前馈网络。代码放在github上:https://github.com/goodluckcwl/simple-cnn
最终的速度是:i5 CPU上单张55*47的图,一次前馈20-30ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值