caffe源码分析:softmax_layer.cpp && softmax_loss_layer.cpp
来源:互联网 发布:java合并两个单链表 编辑:程序博客网 时间:2024/06/05 03:53
本文仅分析了softmax_layer.cpp 和 softmax_loss_layer.cpp两个文件中的forward函数,backward函数有待补充。
1、softmax_layer.cpp
softmax function
设有m个已标记样本,
其中,
带入softmax进行计算其实就是先对每一个
在softmax_layer.cpp中,可以将forward函数比较直观的表现为以下形式:
在
softmax.cpp
中forward
函数代码: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); 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]); } } // 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_; } }}
代码不多,针对Line 21至Line 32分析如下:
1、//division
top_data=top_data/scale_data;
top_data=top_data+inner_num_;
2、//sum after exp
scale_data=top_data*sum_multiplier_.cpu_data()
分析:求和,每一层各自求和放到scale_data中
3、//exponentiation
top_data=exp(top_data)
分析:比较直观,能看出是在exponentiation。函数caffe_exp()的第一个参数是dim,那么应该是对K维列向量做exp
4、//subtraction
通过矩阵相乘的方式来计算,有channels层的top_data,每层元素减去该层的最大值
2、softmax_loss_layer.cpp
softmax loss function
根据上面讲到的softmax函数,假设x属于第i类,我们要最大似然化
loss function:
其中,
在
softmax_loss_layer.cpp
中forward函数代码:template <typename Dtype>void SoftmaxWithLossLayer<Dtype>::Forward_cpu( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // The forward pass computes the softmax prob values. softmax_layer_->Forward(softmax_bottom_vec_, softmax_top_vec_); const Dtype* prob_data = prob_.cpu_data();//定义了一个指针指向最初的可能值 const Dtype* label = bottom[1]->cpu_data();//原始的label int dim = prob_.count() / outer_num_;//输入图像类的个数 int count = 0; Dtype loss = 0; for (int i = 0; i < outer_num_; ++i) {//outer_num_=batch_size for (int j = 0; j < inner_num_; j++) {//inner_num_的存在可解决多标签问题,对于单一标签问题inner_num_=1 const int label_value = static_cast<int>(label[i * inner_num_ + j]);//对于多标签问题还不是很理解,在单一标签问题中inner_num_=1,那么label[i * inner_num_ + j]表示第i * inner_num_ + j个输入图像的标签值,label[i * inner_num_ + j]一定属于[0,输入图像类别数-1] if (has_ignore_label_ && label_value == ignore_label_) { continue; } DCHECK_GE(label_value, 0); DCHECK_LT(label_value, prob_.shape(softmax_axis_)); loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j],Dtype(FLT_MIN)));//对于单标签问题,每张图像经过计算后都会输出一个dim×1大小的矩阵(列向量),矩阵中的第k个值表示该图像属于第k类的概率;prob_data[i * dim + label_value * inner_num_ + j]表示第i个输入图像属于第label_value的概率。 ++count; } } if (normalize_) { top[0]->mutable_cpu_data()[0] = loss / count; } else { top[0]->mutable_cpu_data()[0] = loss / outer_num_; } if (top.size() == 2) { top[1]->ShareData(prob_); }}
0 0
- caffe源码分析:softmax_layer.cpp && softmax_loss_layer.cpp
- caffe源码分析--softmax_layer.cpp
- Caffe源码:Softmax_loss_layer.cpp
- Caffe softmax_layer.cpp学习
- Caffe softmax_loss_layer.cpp 学习
- 学习笔记: 源码 softmax_layer.cpp 略通
- caffe源码分析--data_layer.cpp
- caffe源码分析--poolinger_layer.cpp
- Caffe源码:io.cpp 分析
- 学习笔记: 源码 softmax_loss_layer.cpp 略析
- Caffe源码(十一):io.cpp 分析
- Caffe源码(十一):io.cpp 分析
- caffe源码:math_functions.cpp
- Caffe源码:inner_product_layer.cpp
- Caffe源码:relu_layer.cpp
- Caffe源码:pooling_layer.cpp
- caffe bechmark.cpp 分析
- Caffe源码解析caffe.cpp
- 在部署iis的web服务过程中遇到的问题
- 百度地图只出现网格的问题
- 从零创建maven工程
- STL-string(4.12)
- DPM Voc release 5在CentOS 6上运行
- caffe源码分析:softmax_layer.cpp && softmax_loss_layer.cpp
- px 与 dp, sp换算公式?
- decimal double
- oracle 基本查询
- API常用类(String类)
- 利用简洁的图片预加载组件提升h5移动页面的用户体验
- JVM内存解析 笔记联想
- jsp入门学习2
- iOS开发:多线程之GCD