caffe 源码阅读之softmax data layer

勿在浮沙筑高台。

国人大多浮躁,猪都喜欢往风口跑,曾经的我也不例外。

template <typename Dtype>
void SoftmaxLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  softmax_axis_ =
      bottom[0]->CanonicalAxisIndex(this->layer_param_.softmax_param().axis());
  top[0]->ReshapeLike(*bottom[0]);
  vector<int> mult_dims(1, bottom[0]->shape(softmax_axis_));
  sum_multiplier_.Reshape(mult_dims);
  Dtype* multiplier_data = sum_multiplier_.mutable_cpu_data();
  caffe_set(sum_multiplier_.count(), Dtype(1), multiplier_data);

  // start of liqiming added code
  const string s = "liqiming debuging softmax layer!!"
  Log(s)
  char* t;
  sprintf_s(t,"%d",softmax_axis_)  // 这里的输出应该是1,也即是softmax_axis_ = 1;
  Log(t)
  //// end of liqiming added code
  
  outer_num_ = bottom[0]->count(0, softmax_axis_);            //    这里实际上是shape_(0), 对应的维度是n
  inner_num_ = bottom[0]->count(softmax_axis_ + 1);            //    shape_(2)*shape_(4), 对应的是h*w
  vector<int> scale_dims = bottom[0]->shape();
  scale_dims[softmax_axis_] = 1;
  scale_.Reshape(scale_dims);
}

在source insight软件里可以推断出

outer_num = =n;

inner_num = = h*w;

之前一直困扰我的还有怎么从blob里取出数据?

借着读取softmax data layer的机会消除这个疑问。

在深入细节之前,我先画个图来表示下blob:

 

扫描二维码关注公众号,回复: 9830366 查看本文章

 

由此图,我们不难看出要取出blob中的数据:可以采取如下的操作:

for ( int  i = 0; i < n; i++)

{

    for ( int j = 0; j < c; j++ )

    {

           for ( int k = 0; k < h*w; k++ )

            value = blob[i*c*h*w+j*h*w+k]

    }   

}

各位看官,请看以下的函数:

template <typename Dtype>
void SoftmaxLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = top[0]->mutable_cpu_data();
  Dtype* scale_data = scale_.mutable_cpu_data();
  int channels = bottom[0]->shape(softmax_axis_);
  int dim = bottom[0]->count() / outer_num_;
  caffe_copy(bottom[0]->count(), bottom_data, top_data);
  // We need to subtract the max to avoid numerical issues, compute the exp,
  // and then normalize.
  for (int i = 0; i < outer_num_; ++i) {                   //  这里outer_num_ == n
    // initialize scale_data to the first plane
    caffe_copy(inner_num_, bottom_data + i * dim, scale_data);   // 
    for (int j = 0; j < channels; j++) {                                    //  这里的channels == c
      for (int k = 0; k < inner_num_; k++) {                          //  这里的inner_num_ == h*w
        scale_data[k] = std::max(scale_data[k],
            bottom_data[i * dim + j * inner_num_ + k]);
      }
    }
    // subtraction
    caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_,
        1, -1., sum_multiplier_.cpu_data(), scale_data, 1., top_data);
    // exponentiation
    caffe_exp<Dtype>(dim, top_data, top_data);
    // sum after exp
    caffe_cpu_gemv<Dtype>(CblasTrans, channels, inner_num_, 1.,
        top_data, sum_multiplier_.cpu_data(), 0., scale_data);
    // division
    for (int j = 0; j < channels; j++) {
      caffe_div(inner_num_, top_data, scale_data, top_data);
      top_data += inner_num_;
    }
  }
}

发布了61 篇原创文章 · 获赞 12 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/liqiming100/article/details/88553057