Caffe softmax_layer.cpp学习

来源:互联网 发布:电脑怎么连接宽带网络 编辑:程序博客网 时间:2024/05/21 00:17

目录

  • 目录
    • 首先需要注意的
    • Forward_cpu函数
    • backward_cpu函数
    • backward_cpu函数实现说明

首先需要注意的:

整个网络的参数的 gradient 的计算方法是从顶层出发向后,在 层的时候,会拿到从 得到的 也就是 ,然后需要做两个计算:首先是自己层内的参数的 gradient,比如如果是一个普通的全连通内积层,则会有参数 和 bias 参数 ,根据刚才的 Chain Rule 式子直接计算就可以了,如果 层没有参数 (例如 Softmax 或者 Softmax-Loss 层就是没有参数的。),这一步可以省略;其次就是“向后传递”的步骤,同样地,根据 Chain Rule 我们可以计算. 即当对输入数据bottom求导时,仅仅是为了“向后传递”,这个导数并不参与该层的参数的gradient descent 参数更新,因为该层就没有参数,何须更新参数呢?

Forward_cpu函数

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) {    // initialize scale_data to the first plane    caffe_copy(inner_num_, bottom_data + i * dim, scale_data);//注意,inner_num_和dim的值并不相等,dim是inner_num_的倍数,为通道数channels倍    for (int j = 0; j < channels; j++) {      for (int k = 0; k < inner_num_; k++) {        scale_data[k] = std::max(scale_data[k],            bottom_data[i * dim + j * inner_num_ + k]);      }    }//在每张图像中,沿着通道轴上取最大像素值。虽然scale_data所指向内存区域可存储的数据量为outer_num_×1×inner_num_,但每次也只是更新scale_data最前面的inner_num_个元素。scale_只是用来存储中间变量。    // subtraction    caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_,        1, -1., sum_multiplier_.cpu_data(), scale_data, 1., top_data);//在caffe_cpu_gemm函数中,从top_data所指的内存区域选取channels×inner_num_=dim个元素进行更新,其他函数类似    // 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_;//更新top_data指针    }  }}

backward_cpu函数

template <typename Dtype>void SoftmaxLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,    const vector<bool>& propagate_down,    const vector<Blob<Dtype>*>& bottom) {  const Dtype* top_diff = top[0]->cpu_diff();  const Dtype* top_data = top[0]->cpu_data();  Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();  Dtype* scale_data = scale_.mutable_cpu_data();  int channels = top[0]->shape(softmax_axis_);  int dim = top[0]->count() / outer_num_;  caffe_copy(top[0]->count(), top_diff, bottom_diff);//从top_diff拷贝到bottom_diff  for (int i = 0; i < outer_num_; ++i) {    // compute dot(top_diff, top_data) and subtract them from the bottom diff    for (int k = 0; k < inner_num_; ++k) {      scale_data[k] = caffe_cpu_strided_dot<Dtype>(channels,          bottom_diff + i * dim + k, inner_num_,          top_data + i * dim + k, inner_num_);//因为bottom_diff是从top_diff拷贝而来,所以caffe_cpu_strided_dot的参数不用top_diff,用bottom_diff即可,而且,这样的话就可以在下面的代码("caffe_cpu_gemm<Dtype>()")中直接更新bottom_diff.    }    // subtraction    caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_, 1,        -1., sum_multiplier_.cpu_data(), scale_data, 1., bottom_diff + i * dim);//实现的非常巧妙  }  // elementwise multiplication  caffe_mul(top[0]->count(), bottom_diff, top_data, bottom_diff);}

backward_cpu函数实现说明

参考Softmax vs. Softmax-Loss: Numerical Stability, 我们可以得到oizk:

oizk=δikokoiok={(1ok)ok(0oi)oki=kik

但是,所谓BP,则必须获取上一层diff,即top_diff, 然后相乘,以完成“向后传播”。也就是说oizktop_diff
画张图以表示:图中假设一张图像只有2个通道,inner_num_=4.
这里写图片描述
可见,图中a1αoizk是一致的,最后bottom_diff中的元素是oizk关于i的求和,即
i=0noizktop_diff

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东刚买完东西第二天降价了怎么办 微信上买东西不给退货怎么办 微信买东西转红包被骗怎么办 买手机分期被骗了怎么办 苹果手机摔弯了怎么办 6s主板摔弯了怎么办 京东显示器坏了怎么办 苹果6s手机弯了怎么办 苹果手机变弯了怎么办 苹果手机屏幕摔碎了怎么办 苹果6p后壳弯曲怎么办 苹果手机后壳有点弯曲怎么办 苹果手机x弯了怎么办 苹果8手机弯了怎么办 苹果8p手机弯了怎么办? 美版iphone弯了怎么办 oppor9手机听筒声音小怎么办 苹果7摔弯了屏幕怎么办 苹果手机压弯了怎么办 京东买的电脑坏了怎么办 拼多多低价乱价怎么办 厂家不通过经销商直接发货怎么办 媳妇吵架说我全家有病怎么办 全家都不尊重媳妇怎么办 招商闪电贷有额度不通过怎么办 闪电贷页面登录不进去怎么办 91借钱极速逾期怎么办 论文没过拿不到毕业证怎么办 大学论文不过拿不到毕业证怎么办 转店被黑中介骗了钱怎么办? 被星外转铺骗了怎么办 店铺转了后悔了怎么办 商铺转让不出去怎么办? 和包券密码丢失怎么办 天猫购物卷兑换不了怎么办 淘宝新店每天只有几个访客怎么办 注册淘宝企业店铺需要审核怎么办 淘宝店铺被投诉知识产权怎么办 一般违规扣48分怎么办 金税盘处于报税期不能开票怎么办 小规模税率开错了怎么办