caffe中 softmax 函数的前向传播和反向传播
1.前向传播:
template <typename Dtype>
void SoftmaxLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
const Dtype* bottom_data = bottom[]->cpu_data();
Dtype* top_data = top[]->mutable_cpu_data();
Dtype* scale_data = scale_.mutable_cpu_data();
int channels = bottom[]->shape(softmax_axis_);
int dim = bottom[]->count() / outer_num_; //dim表示要分类的类别数,count()得到的是总共的输入Blob数,outer_num_得到的是是每一类的Blob数
caffe_copy(bottom[]->count(), bottom_data, top_data); //先将输入拷贝到输出缓冲区
// We need to subtract the max to avoid numerical issues, compute the exp,
// and then normalize,减去最大值,避免数值问题,计算指数,归一化
for (int i = ; i < outer_num_; ++i) {
// 初始化scale_的data域为第一个平面,其中scale用来存放临时计算结果
caffe_copy(inner_num_, bottom_data + i * dim, scale_data);
for (int j = ; j < channels; j++) {
for (int k = ; k < inner_num_; k++) {
scale_data[k] = std::max(scale_data[k],
bottom_data[i * dim + j * inner_num_ + k]);
}
}
// 输出缓冲区减去最大值
caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_,
, -., sum_multiplier_.cpu_data(), scale_data, ., top_data);
// exponentiation
caffe_exp<Dtype>(dim, top_data, top_data);
// sum after exp
caffe_cpu_gemv<Dtype>(CblasTrans, channels, inner_num_, .,
top_data, sum_multiplier_.cpu_data(), ., scale_data);
// division
for (int j = ; j < channels; j++) {
caffe_div(inner_num_, top_data, scale_data, top_data);
top_data += inner_num_;
}
}
}
一般的我们有top[0]来存放数据,top[1]来存放标签(对于bottom也一样)
2.反向传播:
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[]->cpu_diff();
const Dtype* top_data = top[]->cpu_data();
Dtype* bottom_diff = bottom[]->mutable_cpu_diff();
Dtype* scale_data = scale_.mutable_cpu_data();
int channels = top[]->shape(softmax_axis_);
int dim = top[]->count() / outer_num_;
caffe_copy(top[]->count(), top_diff, bottom_diff); //先用top_diff初始化bottom_diff
for (int i = ; i < outer_num_; ++i) {
// 计算top_diff和top_data的点积,然后从bottom_diff中减去该值
for (int k = ; 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_);
}
// 减值
caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_, ,
-., sum_multiplier_.cpu_data(), scale_data, ., bottom_diff + i * dim);
}
// 逐点相乘
caffe_mul(top[]->count(), bottom_diff, top_data, bottom_diff);
}
解释:

补充:最后部分,Zi!=Zj和Zi=Zj部分写反了,大家注意一下~
caffe中 softmax 函数的前向传播和反向传播的更多相关文章
- 机器学习(ML)八之正向传播、反向传播和计算图,及数值稳定性和模型初始化
正向传播 正向传播的计算图 通常绘制计算图来可视化运算符和变量在计算中的依赖关系.下图绘制了本节中样例模型正向传播的计算图,其中左下角是输入,右上角是输出.可以看到,图中箭头方向大多是向右和向上,其中 ...
- 小白学习之pytorch框架(6)-模型选择(K折交叉验证)、欠拟合、过拟合(权重衰减法(=L2范数正则化)、丢弃法)、正向传播、反向传播
下面要说的基本都是<动手学深度学习>这本花书上的内容,图也采用的书上的 首先说的是训练误差(模型在训练数据集上表现出的误差)和泛化误差(模型在任意一个测试数据集样本上表现出的误差的期望) ...
- caffe中的前向传播和反向传播
caffe中的网络结构是一层连着一层的,在相邻的两层中,可以认为前一层的输出就是后一层的输入,可以等效成如下的模型 可以认为输出top中的每个元素都是输出bottom中所有元素的函数.如果两个神经元之 ...
- caffe中softmax源码阅读
(1) softmax函数 (1) 其中,zj 是softmax层的bottom输入, f(zj)是softmax层的top输 ...
- BP原理 - 前向计算与反向传播实例
Outline 前向计算 反向传播 很多事情不是需要聪明一点,而是需要耐心一点,踏下心来认真看真的很简单的. 假设有这样一个网络层: 第一层是输入层,包含两个神经元i1 i2和截距b1: 第二层是隐含 ...
- 反向传播算法(前向传播、反向传播、链式求导、引入delta)
参考链接: 一文搞懂反向传播算法
- caffe中softmax loss源码阅读
(1) softmax loss <1> softmax loss的函数形式为: (1) zi为softmax的输入,f(zi)为softmax的输出. <2> sof ...
- 前向传播和反向传播实战(Tensor)
前面在mnist中使用了三个非线性层来增加模型复杂度,并通过最小化损失函数来更新参数,下面实用最底层的方式即张量进行前向传播(暂不采用层的概念). 主要注意点如下: · 进行梯度运算时,tensorf ...
- caffe中python接口的使用
下面是基于我自己的接口,我是用来分类一维数据的,可能不具通用性: (前提,你已经编译了caffe的python的接口) 添加 caffe塻块的搜索路径,当我们import caffe时,可以找到. 对 ...
随机推荐
- Deep Learning(深度学习)学习笔记整理系列 一
声明: 1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家所无私奉献的资料的.具体引用的资料请看参考文献.具体的版本声明也参考原文献. 2)本文仅供学术交流,非商用.所以每一部 ...
- jasperReport和Ireport
<!-- groovy --> <dependency> <groupId>org.codehaus.groovy</groupId> <arti ...
- 自学Zabbix9.1 Network Discovery 网络发现原理
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix9.1 Network Discovery 网络发现原理 1. 网络发现简介 网络 ...
- Cgod省选的爆零日记
声明 虽然是日记,但博主太咕咕咕了,所以可能会鸽掉. 3.11 辣鸡杭二的机子,卡我常数,削我分数. 他们那边的机子好像比我们慢四倍的样子? 开局刚\(T3\),分数全靠骗. \(yy\)许久\(GG ...
- BZOJ 2929: [Poi1999]洞穴攀行
2929: [Poi1999]洞穴攀行 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 351 Solved: 195[Submit][Status][ ...
- 【转】cJSON 使用笔记
缘 起 最近在stm32f103上做一个智能家居的项目,其中选择的实时操作系统是 rt_thread OS v1.2.2稳定版本,其中涉及到C和java(android)端数据 ...
- shell(3)-mysql主从监控shell
需要先明白数据库主从同步正常的标准是来查看两个线程Slave_IO和Slave_SQL两个线程的工作状态: #!/bin/bash #Check MySQL Slave's Runnning Stat ...
- Dijstra算法求最短路径
参考博客:http://blog.51cto.com/ahalei/1387799 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. ...
- C#基础 常用语&数据类型定义&类型转换
int temp = Console.Read(); Console.WriteLine(temp); Console.Read(); Console.Write(" ");直接 ...
- A1016. Phone Bills
A long-distance telephone company charges its customers by the following rules: Making a long-distan ...