答案来自专栏:机器学习算法与自然语言处理

详解softmax函数以及相关求导过程

这几天学习了一下softmax激活函数,以及它的梯度求导过程,整理一下便于分享和交流。

softmax函数

softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!

假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值就是

<img src="https://pic3.zhimg.com/50/v2-39eca1f41fe487983f5111f5e5073396_hd.jpg" data-rawwidth="140" data-rawheight="71" class="content_image" width="140">

更形象的如下图表示:

<img src="https://pic1.zhimg.com/50/v2-87b232ab0e292a536e94b73952caadd0_hd.jpg" data-rawwidth="670" data-rawheight="396" class="origin_image zh-lightbox-thumb" width="670" data-original="https://pic1.zhimg.com/v2-87b232ab0e292a536e94b73952caadd0_r.jpg">

softmax直白来说就是将原来输出是3,1,-3通过softmax函数一作用,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!

举一个我最近碰到利用softmax的例子:我现在要实现基于神经网络的句法分析器。用到是基于转移系统来做,那么神经网络的用途就是帮我预测我这一个状态将要进行的动作是什么?比如有10个输出神经元,那么就有10个动作,1动作,2动作,3动作...一直到10动作。(这里涉及到nlp的知识,大家不用管,只要知道我现在根据每个状态(输入),来预测动作(得到概率最大的输出),最终得到的一系列动作序列就可以完成我的任务即可

原理图如下图所示:

<img src="https://pic1.zhimg.com/50/v2-892ff35f895772d419c77bdd00984f48_hd.jpg" data-rawwidth="627" data-rawheight="188" class="origin_image zh-lightbox-thumb" width="627" data-original="https://pic1.zhimg.com/v2-892ff35f895772d419c77bdd00984f48_r.jpg">

那么比如在一次的输出过程中输出结点的值是如下:

[0.2,0.1,0.05,0.1,0.2,0.02,0.08,0.01,0.01,0.23]

那么我们就知道这次我选取的动作是动作10,因为0.23是这次概率最大的,那么怎么理解多分类呢?很容易,如果你想选取俩个动作,那么就找概率最大的俩个值即可~(这里只是简单的告诉大家softmax在实际问题中一般怎么应用)

softmax相关求导

当我们对分类的Loss进行改进的时候,我们要通过梯度下降,每次优化一个step大小的梯度,这个时候我们就要求Loss对每个权重矩阵的偏导,然后应用链式法则。那么这个过程的第一步,就是对softmax求导传回去,不用着急,我后面会举例子非常详细的说明。在这个过程中,你会发现用了softmax函数之后,梯度求导过程非常非常方便!

下面我们举出一个简单例子,原理一样,目的是为了帮助大家容易理解!

<img src="https://pic2.zhimg.com/50/v2-284da728c54de850e34573d6fe682965_hd.jpg" data-rawwidth="620" data-rawheight="391" class="origin_image zh-lightbox-thumb" width="620" data-original="https://pic2.zhimg.com/v2-284da728c54de850e34573d6fe682965_r.jpg">

我们能得到下面公式:

z4 = w41*o1+w42*o2+w43*o3

z5 = w51*o1+w52*o2+w53*o3

z6 = w61*o1+w62*o2+w63*o3

z4,z5,z6分别代表结点4,5,6的输出,01,02,03代表是结点1,2,3往后传的输入.

那么我们可以经过softmax函数得到

好了,我们的重头戏来了,怎么根据求梯度,然后利用梯度下降方法更新梯度!

要使用梯度下降,肯定需要一个损失函数,这里我们使用交叉熵作为我们的损失函数,为什么使用交叉熵损失函数,不是这篇文章重点,后面有时间会单独写一下为什么要用到交叉熵函数(这里我们默认选取它作为损失函数)

交叉熵函数形式如下:

<img src="https://pic2.zhimg.com/50/v2-cd3d19d3680993cb9ae62d2fd110e43d_hd.jpg" data-rawwidth="173" data-rawheight="59" class="content_image" width="173">

其中y代表我们的真实值,a代表我们softmax求出的值。i代表的是输出结点的标号!在上面例子,i就可以取值为4,5,6三个结点(当然我这里只是为了简单,真实应用中可能有很多结点

现在看起来是不是感觉复杂了,居然还有累和,然后还要求导,每一个a都是softmax之后的形式!

但是实际上不是这样的,我们往往在真实中,如果只预测一个结果,那么在目标中只有一个结点的值为1,比如我认为在该状态下,我想要输出的是第四个动作(第四个结点),那么训练数据的输出就是a4 = 1,a5=0,a6=0,哎呀,这太好了,除了一个为1,其它都是0,那么所谓的求和符合,就是一个幌子,我可以去掉啦!

为了形式化说明,我这里认为训练数据的真实输出为第j个为1,其它均为0!

那么Loss就变成了,累和已经去掉了,太好了。现在我们要开始求导数了!

我们在整理一下上面公式,为了更加明白的看出相关变量的关系:

其中,那么形式变为

那么形式越来越简单了,求导分析如下:

参数的形式在该例子中,总共分为w41,w42,w43,w51,w52,w53,w61,w62,w63.这些,那么比如我要求出w41,w42,w43的偏导,就需要将Loss函数求偏导传到结点4,然后再利用链式法则继续求导即可,举个例子此时求w41的偏导为:

<img src="https://pic3.zhimg.com/50/v2-b345590cc09867302a22071e69b1f81e_hd.jpg" data-rawwidth="595" data-rawheight="331" class="origin_image zh-lightbox-thumb" width="595" data-original="https://pic3.zhimg.com/v2-b345590cc09867302a22071e69b1f81e_r.jpg">

w51.....w63等参数的偏导同理可以求出,那么我们的关键就在于Loss函数对于结点4,5,6的偏导怎么求,如下:

这里分为俩种情况:

<img src="https://pic3.zhimg.com/50/v2-da652b68fb126c709e69eda674fb42be_hd.jpg" data-rawwidth="433" data-rawheight="284" class="origin_image zh-lightbox-thumb" width="433" data-original="https://pic3.zhimg.com/v2-da652b68fb126c709e69eda674fb42be_r.jpg">

 

j=i对应例子里就是如下图所示:

比如我选定了j为4,那么就是说我现在求导传到4结点这!

<img src="https://pic2.zhimg.com/50/v2-40a344cb96d81d30aec0d91a95a04409_hd.jpg" data-rawwidth="570" data-rawheight="353" class="origin_image zh-lightbox-thumb" width="570" data-original="https://pic2.zhimg.com/v2-40a344cb96d81d30aec0d91a95a04409_r.jpg">

那么由上面求导结果再乘以交叉熵损失函数求导

,它的导数为,与上面相乘为形式非常简单,这说明我只要正向求一次得出结果,然后反向传梯度的时候,只需要将它结果减1即可,后面还会举例子!)那么我们可以得到Loss对于4结点的偏导就求出了了(这里假定4是我们的预计输出

第二种情况为:

<img src="https://pic1.zhimg.com/50/v2-fa3ff8ff1c781e259a15b36b85c65fcc_hd.jpg" data-rawwidth="356" data-rawheight="292" class="content_image" width="356">

这里对应我的例子图如下,我这时对的是j不等于i,往前传:

<img src="https://pic1.zhimg.com/50/v2-a4edb7767bfed190991e86cbdaa472cc_hd.jpg" data-rawwidth="547" data-rawheight="361" class="origin_image zh-lightbox-thumb" width="547" data-original="https://pic1.zhimg.com/v2-a4edb7767bfed190991e86cbdaa472cc_r.jpg">

那么由上面求导结果再乘以交叉熵损失函数求导

,它的导数为,与上面相乘为形式非常简单,这说明我只要正向求一次得出结果,然后反向传梯度的时候,只需要将它结果保存即可,后续例子会讲到这里就求出了除4之外的其它所有结点的偏导,然后利用链式法则继续传递过去即可!我们的问题也就解决了!

下面我举个例子来说明为什么计算会比较方便,给大家一个直观的理解

举个例子,通过若干层的计算,最后得到的某个训练样本的向量的分数是[ 2, 3, 4 ],

那么经过softmax函数作用后概率分别就是=[

,,] = [0.0903,0.2447,0.665],如果这个样本正确的分类是第二个的话,那么计算出来的偏导就是[0.0903,0.2447-1,0.665]=[0.0903,-0.7553,0.665],是不是非常简单!!然后再根据这个进行back propagation就可以了

到这里,这篇文章的内容就讲完了,我希望根据自己的理解,通过列出大量例子,直白的给大家讲解softmax的相关内容,让大家少走弯路,真心希望对大家的理解有帮助!欢迎交流指错!画图整理不易,觉得有帮助的给个赞呗,哈哈!

参考:

softmax的log似然代价函数(公式求导)

交叉熵代价函数(作用及公式推导)

Softmax回归 - Ufldl

部分图片来自于网络!

softmax函数详解的更多相关文章

  1. [转]softmax函数详解

    答案来自专栏:机器学习算法与自然语言处理 详解softmax函数以及相关求导过程 这几天学习了一下softmax激活函数,以及它的梯度求导过程,整理一下便于分享和交流. softmax函数 softm ...

  2. Softmax函数详解与推导

    一.softmax函数 softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类! 假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个 ...

  3. malloc 与 free函数详解<转载>

    malloc和free函数详解   本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...

  4. NSSearchPathForDirectoriesInDomains函数详解

    NSSearchPathForDirectoriesInDomains函数详解     #import "NSString+FilePath.h" @implementation ...

  5. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  6. Linux C popen()函数详解

    表头文件 #include<stdio.h> 定义函数 FILE * popen( const char * command,const char * type); 函数说明 popen( ...

  7. kzalloc 函数详解(转载)

    用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0. view plain /** * kzal ...

  8. Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt

    PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...

  9. jQuery.attr() 函数详解

    一,jQuery.attr()  函数详解: http://www.365mini.com/page/jquery-attr.htm 二,jQuery函数attr()和prop()的区别: http: ...

随机推荐

  1. Java开源生鲜电商平台-订单抽成模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-订单抽成模块的设计与架构(源码可下载) 说明:订单抽成指的是向卖家收取相应的信息服务费.(目前市场上有两种抽成方式,一种是按照总额的抽成比率,另外一种是按照订单明细的抽成比率 ...

  2. CentOS 7安装Python3.6过程(让linux系统共存Python2和Python3环境)

    CentOS 7系统自带了python2,不过可以不用2版本,直接使用python3运行python脚本就可以,但是千万别去动系统自带的python2,因为有程序依赖目前的python2环境,比如yu ...

  3. 图解HTTPS建立过程

    阅读目录 准备工作(对应图中prepare1234) 发起链接 最后 关于网络安全加密的介绍可以看之前文章: 1. 网络安全——数据的加密与签名,RSA介绍2. Base64编码.MD5.SHA1-S ...

  4. 对于bootstrap可视化布局设计可以参考2017.6.2

    http://www.layoutit.cn/v3/index.html  可视化布局链接,拖好控件自动生成代码非常方便 http://www.jq22.com/jquery-info14044  这 ...

  5. javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法

    前言 for,slice(0),concact() 在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝.如下图演示:  如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并不 ...

  6. 【转】linux系统中如何进入退出vim编辑器,方法及区别

    在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致 ...

  7. 玩转spring mvc(六)---自定义异常跳转页面

    本文主要是关于如何在出现异常 如404时,跳转到自定义的异常页面,当然这不是spring的知识,但可以整合进去. 在web.xml中新增如下代码,里边的路径可以根据实际情况进行修改 <!-- 7 ...

  8. css布局-双飞翼布局

    <div class="header">Header</div> <div class="bd"> <div clas ...

  9. VMware12下CentOS 7安装教程

    CentOS 7 DVD安装光盘(百度搜索CentOS即可找到官方主页):VMware Workstation 12 Pro及以上软件: 启动VMware Workstation 12 Pro程序,在 ...

  10. 夏娜的菠萝包 JDFZ1098

    Description 问题描述:夏娜很喜欢吃菠萝包,她的经纪人RC每半个月就要为她安排接下来的菠萝包计划.今天是7月份,RC又要去商场进货买菠萝包了.这次RC总共买了N种菠萝包,每种一个.每个菠萝包 ...