本文介绍Softmax运算、Softmax损失函数及其反向传播梯度计算, 内容上承接前两篇博文 损失函数 & 手推反向传播公式

Softmax 梯度

设有K类, 那么期望标签y形如\([0,0,...0,1,0...0]^T\)的one-hot的形式. softmax层的输出为\([a_1,a_2,...,a_j,...a_K]^T\), 其中第j类的softmax输出为:

\[\begin{align}
a_{j} &= \frac{\exp(z_{j})}{\sum_{k=1}^K \exp(z_{k})} \forall j\in 1...K \\
{\partial a_{j}\over \partial z_{j} } &= {\exp(z_{j})\cdot(\Sigma - \exp(z_{j}) )\over \Sigma^2} = a_j(1 - a_j) \\
{\partial a_{k}\over \partial z_{j} } &= { - \exp(z_{k}) \cdot \exp(z_{j}) \over \Sigma^2} = -a_j a_k \tag{$k\ne j$}
\end{align}
\]

如果是全连接的DNN,那么有: \(z_{j}^{l+1}=\sum_i w_{ij} a_{i}^{l}+b_j^{l+1}\)

\(a_j^{l+1}\)可以解释成观察到的数据 \(a^l\) 属于类别 j 的概率,或者称作似然 (Likelihood)。

求输出对输入的梯度\(\partial a\over \partial z\):

\[\begin{align}
{\partial a\over \partial z_k}=
\begin{bmatrix}
{\partial a_1\over \partial z_k} \\
\vdots \\
{\partial a_k\over \partial z_k} \\
\vdots \\
{\partial a_K\over \partial z_k}
\end{bmatrix}
=
\begin{bmatrix}
-a_1 \\
\vdots \\
(1-a_k) \\
\vdots \\
-a_K
\end{bmatrix}a_k
=
(\begin{bmatrix}
0 \\
\vdots \\
1 \\
\vdots \\
0
\end{bmatrix}
-a)a_k
\end{align}
\]

因此损失对输入的梯度为\({\partial E\over \partial z}\):

\[{\partial E\over \partial z_k}={\partial E\over \partial a}{\partial a\over \partial z_k}=({\partial E\over \partial a_k} - [{\partial E\over \partial a}]^T a)a_k \\
{\partial E\over \partial z}={\partial E\over \partial a}{\partial a\over \partial z}=({\partial E\over \partial a} - [{\partial E\over \partial a}]^T a)⊙ a
\]

对应的 Caffe 中的SoftmaxLayer的梯度反向传播计算实现代码为:

  1. # dot 表示矩阵乘法, * 表示按对应元素相乘
  2. bottom_diff = (top_diff - dot(top_diff, top_data)) * top_data

Softmax loss 梯度

单样本的损失函数为:

\[E = -\sum^K_{k}y_k\log(a_{k}) \\
{\partial E\over \partial a_j} = -\sum^K_{k}{y_k\over a_k}\cdot {\partial a_k\over \partial a_j}=-{y_j\over a_j}
\]

接下来求E对w,b的梯度, 过程与反向传播的通用梯度计算公式相同, 这里指定了具体的激活函数(softmax)与损失函数:

\[\begin{align}
{\partial E\over \partial b_j^{l+1}} &= {\partial E\over \partial z_j^{l+1}} = \sum_k{\partial E\over \partial a_k^{l+1}} \cdot {\partial a_k^{l+1}\over \partial z_j^{l+1}} \\
&=-{y_j^{l+1}\over a_j^{l+1}} \cdot a_j^{l+1}(1 - a_j^{l+1})+\sum_{k\ne j}[-{y_k^{l+1}\over a_k^{l+1}} \cdot -a_j^{l+1} a_k^{l+1}] \\
&= -y_j^{l+1}+y_j^{l+1} a_j^{l+1} +\sum_{k\ne j}y_k^{l+1}a_j^{l+1} \\
&= a_j^{l+1}-y_j^{l+1} \\
{\partial E\over \partial w_{ij}^{l+1}} &= {\partial E\over \partial z_j^{l+1}} \cdot {\partial z_j^{l+1}\over w_{ij}^{l+1}}=(a_j^{l+1}-y_j^{l+1})a_i^l
\end{align}
\]

对应的 Caffe 中的SoftmaxWithLossLayer的梯度反向传播计算实现为(\({\partial E\over \partial z}\)):

  1. # prob_data 为前向传播时softmax的结果, label_data 是标签的one-hot表示
  2. bottom_diff = prob_data - label_data

参考[1][2][3]


  1. softmax的log似然代价函数(公式求导) https://blog.csdn.net/u014313009/article/details/51045303 ↩︎

  2. Softmax与SoftmaxWithLoss原理及代码详解 https://blog.csdn.net/u013010889/article/details/76343758 ↩︎

  3. 数值计算稳定性 http://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/ ↩︎

Softmax 损失-梯度计算的更多相关文章

  1. 实现属于自己的TensorFlow(二) - 梯度计算与反向传播

    前言 上一篇中介绍了计算图以及前向传播的实现,本文中将主要介绍对于模型优化非常重要的反向传播算法以及反向传播算法中梯度计算的实现.因为在计算梯度的时候需要涉及到矩阵梯度的计算,本文针对几种常用操作的梯 ...

  2. 多类 SVM 的损失函数及其梯度计算

    CS231n Convolutional Neural Networks for Visual Recognition -- optimization 1. 多类 SVM 的损失函数(Multicla ...

  3. Theano学习-梯度计算

    1. 计算梯度 创建一个函数 \(y\) ,并且计算关于其参数 \(x\) 的微分. 为了实现这一功能,将使用函数 \(T.grad\) . 例如:计算 \(x^2\) 关于参数 \(x\) 的梯度. ...

  4. 机器学习进阶-图像梯度计算-scharr算子与laplacian算子(拉普拉斯) 1.cv2.Scharr(使用scharr算子进行计算) 2.cv2.laplician(使用拉普拉斯算子进行计算)

    1. cv2.Scharr(src,ddepth, dx, dy), 使用Scharr算子进行计算 参数说明:src表示输入的图片,ddepth表示图片的深度,通常使用-1, 这里使用cv2.CV_6 ...

  5. pytorch 反向梯度计算问题

    计算如下\begin{array}{l}{x_{1}=w_{1} * \text { input }} \\ {x_{2}=w_{2} * x_{1}} \\ {x_{3}=w_{3} * x_{2} ...

  6. 优化梯度计算的改进的HS光流算法

    前言 在经典HS光流算法中,图像中两点间的灰度变化被假定为线性的,但实际上灰度变化是非线性的.本文详细分析了灰度估计不准确造成的偏差并提出了一种改进HS光流算法,这种算法可以得到较好的计算结果,并能明 ...

  7. TensorFlow 学习(八)—— 梯度计算(gradient computation)

    maxpooling 的 max 函数关于某变量的偏导也是分段的,关于它就是 1,不关于它就是 0: BP 是反向传播求关于参数的偏导,SGD 则是梯度更新,是优化算法: 1. 一个实例 relu = ...

  8. 理解自动梯度计算autograd

    理解自动求导 例子 def f(x): a = x * x b = x * a c = a + b return c 基于图理解 代码实现 def df(x): # forward pass a = ...

  9. [图解tensorflow源码] MatMul 矩阵乘积运算 (前向计算,反向梯度计算)

随机推荐

  1. Oracle数据库重做日志及归档日志的工作原理说明

    Oracle数据库重做日志及归档日志的工作原理: lgwr进程将redo log buffer中的重做数据写入到redo log中,此时的redo log分组,每当一个redo log group写满 ...

  2. SuperMaze(Hello World 团队)Alpha版使用说明

    一.产品介绍 超级迷宫是一款android的手机游戏,目前我们已经在PC 端成功实现大体功能,虽然虽然迷宫游戏不少但我们的游戏渐渐的会假如自己的特色功能,尽量吸引用户,通过游戏开发智力,通过游戏打发无 ...

  3. 剑指offer:复杂链表的复制

    题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用, ...

  4. B01-java学习-阶段2-面向对象

    对象内存分析 构造方法 类的深入解释 预定义类型和自定义类型深入分析和解释 预定义类源码的查看 预定义类和自定义类的对比 跨过类中使用自定义类型作为属性类型的门槛 构造方法的定义和执行过程 编译器提供 ...

  5. 自己实现数据结构系列二---LinkedList

    一.先上代码: 1.方式一: public class LinkedList<E> { //节点,用来存放数据:数据+下一个元素的引用 private class Node{ privat ...

  6. Oracle备份恢复简单过程以及中间的坑.

    Oracle 冷备: 貌似需要dbca创建一致的oracle instance 服务器配置版本尽量相同,安装路径相同. 关闭Oracle服务 将oracle app 目录下的oradata以及有快速闪 ...

  7. centos7切换gnome3桌面与gnome经典桌面

    登陆界面选择设置按钮,选择gnome,进行登陆

  8. Swagger2 配置

    1. 每个请求都需要换取key: @Bean public Docket createRestApi() { //添加head参数start ParameterBuilder appId = new ...

  9. File类总结

    1.File类是描述文件或文件夹的.File类可以用来操作文件或文件夹本身.但它不能操作文件中的数据. File( String name  )  把一个字符串封装成File对象.这个字符串可以是文件 ...

  10. LightOJ - 1074 Extended Traffic(标记负环)

    题意:有n个城市,每一个城市有一个拥挤度ai,从一个城市u到另一个城市v的时间为:(au-av)^3,存在负环.问从第一个城市到达第k个城市所话的时间,如果不能到达,或者时间小于3输出?否则输出所花的 ...