caffe forward_cpu

来源:互联网 发布:软件脱壳工具 编辑:程序博客网 时间:2024/05/17 22:58

关联函数解析:Forward_cpu ->  forward_cpu_gemm -> caffe_cpu_gemm


  1. void ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,    
  2.       const vector<Blob<Dtype>*>& top) {   
  3.    // blob_[0] 是 weight blob, blob_[1] 是 bias blob
  4.   const Dtype* weight = this->blobs_[0]->cpu_data();    
  5.   for (int i = 0; i < bottom.size(); ++i) {    
  6.     const Dtype* bottom_data = bottom[i]->cpu_data();    
  7.     Dtype* top_data = top[i]->mutable_cpu_data();    
  8.     // num_ 是参数配置文件中设置的batchsize  
  9.     for (int n = 0; n < this->num_; ++n) {    
  10.       // 基类的forward_cpu_gemm函数执行矩阵乘积运算
  11.       // top_data[n * this->top_dim_] = weights X bottom_data[n * this->bottom_dim_]      
  12.       this->forward_cpu_gemm(bottom_data + n * this->bottom_dim_, weight, top_data + n * this->top_dim_);    
  13.       if (this->bias_term_) {    
  14.         const Dtype* bias = this->blobs_[1]->cpu_data();    
  15.         this->forward_cpu_bias(top_data + n * this->top_dim_, bias);    
  16.       }    
  17.     }    
  18.   }    
  19. }   


  1. void BaseConvolutionLayer<Dtype>::forward_cpu_gemm(const Dtype* input,    
  2.     const Dtype* weights, Dtype* output, bool skip_im2col) {    
  3.   const Dtype* col_buff = input;    
  4.   if (!is_1x1_) {    
  5.     if (!skip_im2col) {    
  6.       // 如果没有1x1卷积,也没有skip_im2col    
  7.       // 则使用conv_im2col_cpu对使用卷积核滑动过程中的每一个kernel大小的图像块    
  8.       // 变成一个列向量,形成一个height=kernel_dim_的    
  9.       // width = 卷积后图像heght*卷积后图像width    
  10.       conv_im2col_cpu(input, col_buffer_.mutable_cpu_data());    
  11.     }    
  12.     col_buff = col_buffer_.cpu_data();    
  13.   }    
  14.     
  15.   // 分割为group_组分别进行计算,可能是为了避免通道数过多(如1024个)一次完成计算会占用太多内存   
  16.   // conv_out_channels_,权重矩阵 weight matrix 的行数
  17.   // conv_out_spatial_dim_ 卷积后输出特征图的空间维度 = 卷积后图像h*卷积后图像w  = col_buff matrix的列数
  18.   // kernel_dim_, 卷积核的维度 = 输入图像的维度*卷积核的h*卷积核的w = weight matrix 的列数
  19.   for (int g = 0; g < group_; ++g) {    
  20.        // conv_out_channels_是参数配置文件中设置的num_output
  21.       // conv_out_channels_ / group_是每个卷积组的大小。卷积组内的每个卷积核一般都是3D的,但在weight matrix中展开为一行
  22.       // 每次参与乘积运算的是weight matrix的row slices. weights的形状是 [conv_out_channel, kernel_dim_]        
  23.       // col_buff的形状是[kernel_dim_ , (卷积后图像高度乘以卷积后图像宽度)]    
  24.       // 所以output的形状自然就是[conv_out_channel, (卷积后图像高度乘以卷积后图像宽度)]    
  25.       caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, conv_out_channels_ / group_, conv_out_spatial_dim_, kernel_dim_,
  26.         (Dtype)1., weights + weight_offset_ * g, col_buff + col_offset_ * g, (Dtype)0., output + output_offset_ * g);
  27.   }    
  28. }    

              

   

  1. /* 
  2.  *功能: C=alpha*A*B+beta*C 
  3.  *A,B,C 是输入矩阵(一维数组格式) 
  4.  *CblasRowMajor :数据是行主序的(二维数据也是用一维数组储存的) 
  5.  *TransA, TransB:是否要对A和B做转置操作(CblasTrans CblasNoTrans) 
  6.  *M: A、C 的行数 
  7.  *N: B、C 的列数 
  8.  *K: A 的列数, B 的行数 
  9.  *lda : A的列数(不做转置)行数(做转置) 
  10.  *ldb: B的列数(不做转置)行数(做转置) 
  11. */  
  12. template<>  
  13. void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,  
  14.     const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,  
  15.     const float alpha, const float* A, const float* B, const float beta,  
  16.     float* C) {  
  17.   int lda = (TransA == CblasNoTrans) ? K : M;  
  18.   int ldb = (TransB == CblasNoTrans) ? N : K;  
  19.   cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,  
  20.       ldb, beta, C, N);  
  21. }  

                      

                

原创粉丝点击