forward

template<>void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,    const float alpha, const float* A, const float* B, const floatbeta,    float* C) {  int lda = (TransA == CblasNoTrans) ? K : M;  int ldb = (TransB == CblasNoTrans) ? N : K;  cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,      ldb, beta, C, N);}




功能: C=alpha*A*B+beta*C 
A,B,C 是输入矩阵(一维数组格式) 
CblasRowMajor :数据是行主序的(二维数据也是用一维数组储存的) 
TransA, TransB:是否要对A和B做转置操作(CblasTrans CblasNoTrans) 
M: A、C 的行数 
N: B、C 的列数 
K: A 的列数, B 的行数 
lda : A的列数(不做转置)行数(做转置) 
ldb: B的列数(不做转置)行数(做转置)

  1. template <typename Dtype>  
  2. void BaseConvolutionLayer<Dtype>::forward_cpu_gemm(const Dtype* input,  
  3.     const Dtype* weights, Dtype* output, bool skip_im2col) {  
  4.   const Dtype* col_buff = input;  
  5.   if (!is_1x1_) {  
  6.     if (!skip_im2col) {  
  7.       // 如果没有1x1卷积,也没有skip_im2col    
  8.       // 则使用conv_im2col_cpu对使用卷积核滑动过程中的每一个kernel大小的图像块    
  9.       // 变成一个列向量,形成一个height=kernel_dim_的    
  10.       // width = 卷积后图像heght*卷积后图像width   
  11.       conv_im2col_cpu(input, col_buffer_.mutable_cpu_data());  
  12.     }  
  13.     col_buff = col_buffer_.cpu_data();  
  14.   }  
  15.   // 使用caffe的cpu_gemm来进行计算  
  16.   for (int g = 0; g < group_; ++g) {  
  17.       // conv_out_channels_ / group_是每个卷积组的输出的channel    
  18.       // kernel_dim_ = input channels per-group x kernel height x kernel width    
  19.       // 计算的是output[output_offset_ * g] =    
  20.       // weights[weight_offset_ * g] X col_buff[col_offset_ * g]  
  21.       // weights的维度为(conv_out_channels_ /group_) x kernel_dim_   
  22.       // weights的形状是 [conv_out_channel x kernel_dim_]    
  23.       // col_buff相当于数据,它的形状是[kernel_dim_ x (卷积后图像高度乘以卷积后图像宽度)]=  
  24.       //    kernel_dim_ x conv_out_spatial_dim_    
  25.       // 所以output的形状自然就是conv_out_channel X (卷积后图像高度乘以卷积后图像宽度)=  
  26.       //       (conv_out_channels_ /group_) x conv_out_spatial_dim_  
  27.     caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, conv_out_channels_ /  
  28.         group_, conv_out_spatial_dim_, kernel_dim_,  
  29.         (Dtype)1., weights + weight_offset_ * g, col_buff + col_offset_ * g,  
  30.         (Dtype)0., output + output_offset_ * g);  
  31.   }  
  32. }//只是对一张图像进行前向传播!与全连接层类比,conv_out_channels_ / group_相当与全连接层的输出神经元个数;conv_out_spatial_dim_相当于全连接层中的样本个数;kernel_dim_相当与全连接层中每个样本特征向量的维数。  




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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值