caffe源码分析:softmax_layer.cpp softmax_loss_layer.cpp
本文仅分析了softmax_layer.cpp 和 softmax_loss_layer.cpp两个文件中的forward函数,backward函数有待补充。
1、softmax_layer.cpp
softmax function
设有m个已标记样本,σ(z)=(σ1(z),σ2(z),...,σm(z))\sigma\mathit(z)=(\sigma_1(\mathit{z}),\sigma_2(\mathit{z}),...,\sigma_m(\mathit{z}))定义:
\sigma_\mathit{i}(\mathit{z})=\frac{\exp(z_i)}{\sum_{j=1}^m\exp(z_j)},\quad i=1,...,m
其中, σi(z)\sigma_\mathit{i}(\mathit{z})是loss层的输入; zi=WTix+biz_i=W_i^Tx+b_i,表示第i类的线性预测结果, WTiW_i^T为权重, bib_i为偏置值。
带入softmax进行计算其实就是先对每一个ziz_i取exponential变为非负,然后除以所有项之和进行归一化。
在softmax_layer.cpp中,可以将forward函数比较直观的表现为以下形式:
h_\theta\left(x^\mathit{(i)}\right)=\left[\begin{matrix}p(y^\mathit{(i)}=1|x^\mathit{(i)};\theta)\\p(y^\mathit{(i)}=2|x^\mathit{(i)};\theta)\\\vdots\\p(y^\mathit{(i)}=k|x^\mathit{(i)};\theta)\end{matrix}\right]=\frac{1}{\sum_{l=1}^ke^\mathit{\theta_j^Tx^\mathit{(i)}}}\left[\begin{matrix}e^\mathit{\theta_\mathsf{1}^Tx^\mathit{(i)}}\\e^\mathit{\theta_\mathsf{2}^Tx^\mathit{(i)}}\\\vdots\\e^\mathit{\theta_\mathsf{k}^Tx^\mathit{(i)}}\end{matrix}\right]
在 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 planecaffe_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]);}}// subtractioncaffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_,1, -1., sum_multiplier_.cpu_data(), scale_data, 1., top_data);// exponentiationcaffe_exp<Dtype>(dim, top_data, top_data);// sum after expcaffe_cpu_gemv<Dtype>(CblasTrans, channels, inner_num_, 1.,top_data, sum_multiplier_.cpu_data(), 0., scale_data);// divisionfor (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类,我们要最大似然化σi(z)\sigma_i(z),通常使用negtive log-likelihood ,也就是要最小化−log(oy)-log(o_y)的值。
loss function:
J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^m\sum_{j=1}^k1\{y^\mathit{(i)}=j\}log\frac{e^\mathit{\theta_j^Tx^\mathit{(i)}}}{\sum_{l=1}^ke^\mathit{\theta_j^Tx^\mathit{(i)}}}\right]
其中, 1{y(i)=j}1\{y^\mathit{(i)}=j\}为示性函数。
在 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();//原始的labelint dim = prob_.count() / outer_num_;//输入图像类的个数int count = 0;Dtype loss = 0;for (int i = 0; i < outer_num_; ++i) {//outer_num_=batch_sizefor (int j = 0; j < inner_num_; j++) {//inner_num_的存在可解决多标签问题,对于单一标签问题inner_num_=1const 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_);}
}
caffe源码分析:softmax_layer.cpp softmax_loss_layer.cpp相关推荐
- caffe源码分析--SyncedMemory 内存管理机制
caffe源码分析–SyncedMemory 内存管理机制 SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...
- caffe源码分析-layer
本文主要分析caffe layer层,主要内容如下: 从整体上说明下caffe的layer层的类别,以及作用 通过proto定义与类Layer简要说明下Layer的核心成员变量; Layer类的核心成 ...
- x265源码分析 main函数 x265.cpp
图片转载于x265源码流程分析_Dillon2015的博客-CSDN博客_x265编码流程 cliopt.prase main ()函数--解析函数参数并进行编码准备工作:x265.cpp (1)Ge ...
- 【AI】caffe源码分析(一)
[一]caffe依赖开源库 [C++]google gflags详解 [C++]google glog详解 [C++]Google Protocol Buffer(protobuf)详解(一) [C+ ...
- caffe源码分析:layer.hpp分析
文件路径:caffe-master_github/include/caffe/ Backward函数: template <typename Dtype> inline void Laye ...
- caffe 源码分析:Euclidean loss layer
最近做项目需要修改Euclidean loss函数,所以就先分析了一下Euclidean loss layer的代码 以gpu版本的为例: 一. 前向函数 template <typename ...
- caffe源码分析:blob.hpp分析
文件路径:caffe-master_github/include/caffe/ 如果想对blob有详细了解,参考Caffe官网教程:http://caffe.berkeleyvision.org/tu ...
- Android之vold进程启动源码分析
1.Vold (Volume Daemon)介绍 vold进程接收来自内核的外部设备消息,用于管理和控制Android平台外部存储设备,包括SD插拨.挂载.卸载.格式化等:当外部设备发生变化时,内核通 ...
- 【Android 逆向】整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )
文章目录 前言 一.DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 二./bin/dexopt 源码分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ...
最新文章
- 2021年大数据ELK(十九):使用FileBeat采集Kafka日志到Elasticsearch
- 022_applescript快速入门教程
- 剑指offer 算法 (代码的完整性)
- 【ABAP】根据Tcode查找后台IMG路径
- python一个富翁试图与陌生人做一笔生意_VB实验报告一
- 说说MaxTenuringThreshold这个参数
- Jmeter plugins 之 Perfmon Metrics Collector(服务器性能监控)
- java中date类型如何赋值_Java 中的类型传递问题解惑
- DropBox:机器学习每年可以为我们节省170万的文档预览费用
- 2015/10/19总结:ajax传参、jquery.validate自定义日期校验
- Navicat工具怎么连接oracle数据库
- 拿工资,要做差不多的事
- 空号检测和手机在网状态查询的区别
- 如何合并excel文件
- pc端ui图片尺寸_PC端网页尺寸设计一
- 第一节课 opencv图像处理,对图片进行叠加处理
- .m3u8视频格式转换
- Echarts双Y轴图表处理
- 公众号php关键词回复小程序,微信自定义关键词回复信息
- 一文搞懂 | ARM微架构的变化