sigmod和sigmoid「SI和VGM」
神经网络:损失函数详解
交叉熵代价函数(Cross-entropy cost function)是用来衡量人工神经网络(ANN)的预测值与实际值的一种方式。与二次代价函数相比,它能更有效地促进ANN的训练。在介绍交叉熵代价函数之前,本文先简要介绍二次代价函数,以及其存在的不足。
1. 二次代价函数的不足
ANN的设计目的之一是为了使机器可以像人一样学习知识。人在学习分析新事物时,当发现自己犯的错误越大时,改正的力度就越大。比如投篮:当运动员发现自己的投篮方向离正确方向越远,那么他调整的投篮角度就应该越大,篮球就更容易投进篮筐。同理, 我们希望:ANN在训练时,如果预测值与实际值的误差越大,那么在 反向传播训练 的过程中,各种参数调整的幅度就要更大,从而使训练更快收敛。 然而,如果使用二次代价函数训练ANN,看到的实际效果是,如果误差越大,参数调整的幅度可能更小,训练更缓慢。

以一个神经元的二类分类训练为例,进行两次实验(ANN常用的激活函数为sigmoid函数,该实验也采用该函数):输入一个相同的样本数据x=1.0(该样本对应的实际分类y=0);两次实验各自随机初始化参数,从而在各自的第一次前向传播后得到不同的输出值,形成不同的代价(误差):
实验1:第一次输出值为0.82
实验2:第一次输出值为0.98
在实验1中,随机初始化参数,使得第一次输出值为0.82(该样本对应的实际值为0);经过300次迭代训练后,输出值由0.82降到0.09,逼近实际值。而在实验2中,第一次输出值为0.98,同样经过300迭代训练,输出值只降到了0.20。
从两次实验的代价曲线中可以看出: 实验1的代价随着训练次数增加而快速降低,但实验2的代价在一开始下降得非常缓慢;直观上看,初始的误差越大,收敛得越缓慢 。
其实,误差大导致训练缓慢的原因在于使用了二次代价函数。二次代价函数的公式如下:
其中,C表示代价,x表示样本,y表示实际值,a表示输出值,n表示样本的总数。为简单起见,同样一个样本为例进行说明,此时二次代价函数为:
目前训练ANN最有效的 算法 是 反向传播算法 。简而言之,训练ANN就是通过反向传播代价,以减少代价为导向,调整参数。参数主要有:神经元之间的连接权重w,以及每个神经元本身的偏置b。调参的方式是采用梯度下降算法(Gradient
descent),沿着梯度方向调整参数大小。w和b的梯度推导如下:
其中,z表示神经元的输入,
表示激活函数。从以上公式可以看出,w和b的梯度跟激活函数的梯度成正比,激活函数的梯度越大,w和b的大小调整得越快,训练收敛得就越快。而神经网络常用的激活函数为sigmoid函数,该函数的曲线如下所示:
如图所示, 实验2的初始输出值(0.98)对应的梯度明显小于实验1的输出值(0.82),因此实验2的参数梯度下降得比实验1慢。这就是初始的代价(误差)越大,导致训练越慢的原因。 与我们的期望不符,即:不能像人一样,错误越大,改正的幅度越大,从而学习得越快。
可能有人会说,那就选择一个梯度不变化或变化不明显的激活函数不就解决问题了吗?图样图森破,那样虽然简单粗暴地解决了这个问题,但可能会引起其他更多更麻烦的问题。而且,类似sigmoid这样的函数(比如tanh函数)有很多优点,非常适合用来做激活函数,具体请自行google之。
2. 交叉熵代价函数
换个思路,我们不换激活函数,而是换掉二次代价函数,改用交叉熵代价函数:
其中,x表示样本,n表示样本的总数。那么,重新计算参数w的梯度:
其中(具体证明见附录):
因此,w的梯度公式中原来的
被消掉了;另外,该梯度公式中的
表示输出值与实际值之间的误差。所以,当误差越大,梯度就越大,参数w调整得越快,训练速度也就越快。同理可得,b的梯度为:
实际情况证明,交叉熵代价函数带来的训练效果往往比二次代价函数要好。
3. 交叉熵代价函数是如何产生的?
以偏置b的梯度计算为例,推导出交叉熵代价函数:
在第1小节中,由二次代价函数推导出来的b的梯度公式为:
为了消掉该公式中的
,我们想找到一个代价函数使得:
即:
对两侧求积分,可得:
而这就是前面介绍的交叉熵代价函数。
附录:
sigmoid函数为:
可证:
更系统的回答:
在之前的内容中,我们用的损失函数都是平方差函数,即
C=12(a−y)2
其中y是我们期望的输出,a为神经元的实际输出(a=σ(Wx+b)。也就是说,当神经元的实际输出与我们的期望输出差距越大,代价就越高。想法非常的好,然而在实际应用中,我们知道参数的修正是与∂C∂W和∂C∂b成正比的,而根据
∂C∂W=(a−y)σ′(a)xT∂C∂b=(a−y)σ′(a)
我们发现其中都有σ′(a)这一项。因为sigmoid函数的性质,导致σ′(z)在z取大部分值时会造成饱和现象,从而使得参数的更新速度非常慢,甚至会造成离期望值越远,更新越慢的现象。那么怎么克服这个问题呢?我们想到了交叉熵函数。我们知道,熵的计算公式是
H(y)=−∑iyilog(yi)
而在实际操作中,我们并不知道y的分布,只能对y的分布做一个估计,也就是算得的a值, 这样我们就能够得到用a来表示y的交叉熵
H(y,a)=−∑iyilog(ai)
如果有多个样本,则整个样本的平均交叉熵为
H(y,a)=−1n∑n∑iyi,nlog(ai,n)
其中n表示样本编号,i表示类别编。 如果用于logistic分类,则上式可以简化成
H(y,a)=−1n∑nylog(a)+(1−y)log(1−a)
与平方损失函数相比,交叉熵函数有个非常好的特质,
H′=1n∑(an−yn)=1n∑(σ(zn)−yn)
可以看到其中没有了σ′这一项,这样一来也就不会受到饱和性的影响了。当误差大的时候,权重更新就快,当误差小的时候,权重的更新就慢。这是一个很好的性质。
3.总结
当我们用sigmoid函数作为神经元的激活函数时,最好使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢。
不过,你也许会问,为什么是交叉熵函数?导数中不带σ′(z)项的函数有无数种,怎么就想到用交叉熵函数?这自然是有来头的,更深入的讨论就不写了,少年请自行了解。
另外,交叉熵函数的形式是−[ylna+(1−y)ln(1−a)]而不是
−[alny+(1−a)ln(1−y)],为什么?因为当期望输出的y=0时,lny没有意义;当期望y=1时,ln(1-y)没有意义。而因为a是sigmoid函数的实际输出,永远不会等于0或1,只会无限接近于0或者1,因此不存在这个问题。
4.还要说说:log-likelihood cost
对数似然函数也常用来作为softmax回归的代价函数,在上面的讨论中,我们最后一层(也就是输出)是通过sigmoid函数,因此采用了交叉熵代价函数。而 深度学习 中更普遍的做法是将softmax作为最后一层,此时常用的是代价函数是log-likelihood cost。
In fact, it’s useful to think of a softmax output layer with
log-likelihood cost as being quite similar to a sigmoid output layer
with cross-entropy cost。
其实这两者是一致的,logistic回归用的就是sigmoid函数,softmax回归是logistic回归的多类别推广。log-likelihood代价函数在二类别时就可以化简为交叉熵代价函数的形式。
补充一个困扰我很久的问题:
;mid=502840969idx=1sn=05b8d27dccf6efc3f85f47a74669e1c9#rd
总结:
softmax 损失函数,适合单标签多分类问题
欧式损失函数(就是均方误差),适合实数值回归问题
sigmod 交叉熵,适合多标签分类问题,这里上面说是主要用在二分类,暂时理解为多标签二分类问题。
contrastive loss,适合深度测度学习,就是siamese网络的相似度学习。
数据挖掘用rapidminer预测Sigmod代表什么含义?bias代表什么含义?
Sigmoid是在神经网络算法中中间层和输出层设置的激活函数,即输入输出转换函数,将不一致的输入转换到(0,1)范围内。而bias是输入层和中间层设置的偏置,可以理解成有一个X0节点,它的值是1,它的权重是bias。
两个Relu怎么合成一个sigmod
两个Relu合成一个sigmod的解决方法如下:
(1)对于深度神经网络,中间的隐层的输出必须有一个激活函数。否则多个隐层的作用和没有隐层相同。这个激活函数不一定是sigmoid,常见的有sigmoid、tanh、relu等。
(2)对于二分类问题,输出层是sigmoid函数。这是因为sigmoid函数可以把实数域光滑的映射到[0,1]空间。函数值恰好可以解释为属于正类的概率(概率的取值范围是0~1)。另外,sigmoid函数单调递增,连续可导,导数形式非常简单,是一个比较合适的函数
(3)对于多分类问题,输出层就必须是softmax函数了。softmax函数是sigmoid函数的推广。
Sigmod Loss 相关总结
一、sigmoid 函数的应用背景:
是起初用于分类的线性模型 (是个通过属性的线性组合来预测的函数[ 每个样本都包含多个属性 ],w权重表达了样本中各个属性在预测中的重要性,b偏置表达了从物理世界到数据表达中存在的不确定性,比如某些噪声无法通过数据表征出来) ,模型的最终目的是为了找到这样的一条直线(平面)将空间中的样本点进行分类。但是获得的直线(平面)上的取值是连续的,并不能对离散的值进行拟合。为解决这个问题就引入了条件概率的使用: :当x取某值时,y=1的概率,概率取值范围是[0,1],概率值是个连续值。 所以可以用线性模型来拟合概率值,但是,概率值的范围是[0,1],而线性模型的结果值是负无穷到正无穷。 所以,就需要有函数将模型的输出值映射在[0,1]范围内。首先,想到的是利用阶跃函数(分段函数),
所以,就有了sigmoid函数的使用。 其数学表达式是: ,【这里就表明了sigmoid函数是直接以模型的输出作为输入变量的】。该函数的曲线图为:
所以,模型的表达式为: 。
存在关系式: ,该比值称为对数几率(log odds,logit)该几率反映了样本为正例的相对可能性。从该关系式可以看出,逻辑回归的本质是用线性回归的预测结果去逼近真实标记的对数几率。
好处:不仅预测出了类别 ,也表示出来属于该类别的概率,有利于利用概率来辅助决策。
二、sigmoid 损失函数的使用:
sigmoid 属于逻辑损失函数的一种,适用于 二分类 任务中,需要满足假设之一:数据满足伯努利分布。
logical 函数 也叫作 sigmoid 函数
表示将样本预测为正类的概率,1- 将样本预测为负类的概率,整个模型可以表示为: ,其中, ,(θ是权重,x是输入变量,该指数代表模型的输出),最后得到逻辑回归的最终表达式。
逻辑回归的损失函数,是其极大似然函数:
由一可知: ,则 ,所以似然函数为: ,使用负对数似然函数作为模型的损失函数(为了好计算但式子性质不变):
在模型训练时,需要对该loss函数求梯度(就是对权重W求导),就是按照函数求偏导的方法对该loss进行求导,最终结果为:
接着就使用梯度下降法,对网路参数进行更新,求得最优参数解。
一文读懂神经网络
要说近几年最引人注目的技术,无疑的,非人工智能莫属。无论你是否身处科技互联网行业,随处可见人工智能的身影:从 AlphaGo 击败世界围棋冠军,到无人驾驶概念的兴起,再到科技巨头 All in AI,以及各大高校向社会输送海量的人工智能专业的毕业生。以至于人们开始萌生一个想法:新的革命就要来了,我们的世界将再次发生一次巨变;而后开始焦虑:我的工作是否会被机器取代?我该如何才能抓住这次革命?
人工智能背后的核心技术是深度神经网络(Deep Neural Network),大概是一年前这个时候,我正在回老家的高铁上学习 3Blue1Brown 的 Neural Network 系列视频课程,短短 4 集 60 多分钟的时间,就把神经网络从 High Level 到推导细节说得清清楚楚,当时的我除了获得新知的兴奋之外,还有一点新的认知,算是给头脑中的革命性的技术泼了盆冷水:神经网络可以解决一些复杂的、以前很难通过写程序来完成的任务——例如图像、语音识别等,但它的实现机制告诉我,神经网络依然没有达到生物级别的智能,短期内期待它来取代人也是不可能的。
一年后的今天,依然在这个春运的时间点,将我对神经网络的理解写下来,算是对这部分知识的一个学习笔记,运气好的话,还可以让不了解神经网络的同学了解起来。
****这样解释 神经网络 :
这个定义比较宽泛,你甚至还可以用它来定义其它的机器学习算法,例如之前我们一起学习的逻辑回归和 GBDT 决策树。下面我们具体一点,下图是一个逻辑回归的示意图:
其中 x1 和 x2 表示输入,w1 和 w2 是模型的参数,z 是一个线性函数:
接着我们对 z 做一个 sigmod 变换(图中蓝色圆),得到输出 y:
其实,上面的逻辑回归就可以看成是一个只有 1 层 输入层 , 1 层 输出层 的神经网络,图中容纳数字的圈儿被称作 神经元 ;其中,层与层之间的连接 w1、w2 以及 b,是这个 神经网络的参数 ,层之间如果每个神经元之间都保持着连接,这样的层被称为 全连接层 (Full Connection Layer),或 稠密层 (Dense Layer);此外,sigmoid 函数又被称作 激活函数 (Activation Function),除了 sigmoid 外,常用的激活函数还有 ReLU、tanh 函数等,这些函数都起到将线性函数进行非线性变换的作用。我们还剩下一个重要的概念: 隐藏层 ,它需要把 2 个以上的逻辑回归叠加起来加以说明:
如上图所示,除输入层和输出层以外,其他的层都叫做 隐藏层 。如果我们多叠加几层,这个神经网络又可以被称作 深度神经网络 (Deep Neural Network),有同学可能会问多少层才算“深”呢?这个没有绝对的定论,个人认为 3 层以上就算吧:)
以上,便是神经网络,以及神经网络中包含的概念,可见,神经网络并不特别,广义上讲,它就是
可见,神经网络和人脑神经也没有任何关联,如果我们说起它的另一个名字—— 多层感知机(Mutilayer Perceptron) ,就更不会觉得有多么玄乎了,多层感知机创造于 80 年代,可为什么直到 30 年后的今天才爆发呢?你想得没错,因为改了个名字……开个玩笑;实际上深度学习这项技术也经历过很长一段时间的黑暗低谷期,直到人们开始利用 GPU 来极大的提升训练模型的速度,以及几个标志性的事件:如 AlphaGo战胜李世石、Google 开源 TensorFlow 框架等等,感兴趣的同学可以翻一下这里的历史。
就拿上图中的 3 个逻辑回归组成的神经网络作为例子,它和普通的逻辑回归比起来,有什么优势呢?我们先来看下单逻辑回归有什么劣势,对于某些情况来说,逻辑回归可能永远无法使其分类,如下面数据:
这 4 个样本画在坐标系中如下图所示
因为逻辑回归的决策边界(Decision Boundary)是一条直线,所以上图中的两个分类,无论你怎么做,都无法找到一条直线将它们分开,但如果借助神经网络,就可以做到这一点。
由 3 个逻辑回归组成的网络(这里先忽略 bias)如下:
观察整个网络的计算过程,在进入输出层之前,该网络所做的计算实际上是:
即把输入先做了一次线性变换(Linear Transformation),得到 [z1, z2] ,再把 [z1, z2] 做了一个非线性变换(sigmoid),得到 [x1', x2'] ,(线性变换的概念可以参考 这个视频 )。从这里开始,后面的操作就和一个普通的逻辑回归没有任何差别了,所以它们的差异在于: 我们的数据在输入到模型之前,先做了一层特征变换处理(Feature Transformation,有时又叫做特征抽取 Feature Extraction),使之前不可能被分类的数据变得可以分类了 。
我们继续来看下特征变换的效果,假设 为 ,带入上述公式,算出 4 个样本对应的 [x1', x2'] 如下:
再将变换后的 4 个点绘制在坐标系中:
显然,在做了特征变换之后,这两个分类就可以很容易的被一条决策边界分开了。
所以, 神经网络的优势在于,它可以帮助我们自动的完成特征变换或特征提取 ,尤其对于声音、图像等复杂问题,因为在面对这些问题时,人们很难清晰明确的告诉你,哪些特征是有用的。
在解决特征变换的同时,神经网络也引入了新的问题,就是我们需要设计各式各样的网络结构来针对性的应对不同的场景,例如使用卷积神经网络(CNN)来处理图像、使用长短期记忆网络(LSTM)来处理序列问题、使用生成式对抗网络(GAN)来写诗和作图等,就连去年自然语言处理(NLP)中取得突破性进展的 Transformer/Bert 也是一种特定的网络结构。所以, 学好神经网络,对理解其他更高级的网络结构也是有帮助的 。
上面说了,神经网络可以看作一个非线性函数,该函数的参数是连接神经元的所有的 Weights 和 Biases,该函数可以简写为 f(W, B) ,以手写数字识别的任务作为例子:识别 MNIST 数据集 中的数字,数据集(MNIST 数据集是深度学习中的 HelloWorld)包含上万张不同的人写的数字图片,共有 0-9 十种数字,每张图片为 28*28=784 个像素,我们设计一个这样的网络来完成该任务:
把该网络函数所具备的属性补齐:
接下来的问题是,这个函数是如何产生的?这个问题本质上问的是这些参数的值是怎么确定的。
在机器学习中,有另一个函数 c 来衡量 f 的好坏,c 的参数是一堆数据集,你输入给 c 一批 Weights 和 Biases,c 输出 Bad 或 Good,当结果是 Bad 时,你需要继续调整 f 的 Weights 和 Biases,再次输入给 c,如此往复,直到 c 给出 Good 为止,这个 c 就是损失函数 Cost Function(或 Loss Function)。在手写数字识别的列子中,c 可以描述如下:
可见,要完成手写数字识别任务,只需要调整这 12730 个参数,让损失函数输出一个足够小的值即可,推而广之,绝大部分神经网络、机器学习的问题,都可以看成是定义损失函数、以及参数调优的问题。
在手写识别任务中,我们既可以使用交叉熵(Cross Entropy)损失函数,也可以使用 MSE(Mean Squared Error)作为损失函数,接下来,就剩下如何调优参数了。
神经网络的参数调优也没有使用特别的技术,依然是大家刚接触机器学习,就学到的梯度下降算法,梯度下降解决了上面迭代过程中的遗留问题——当损失函数给出 Bad 结果时,如何调整参数,能让 Loss 减少得最快。
梯度可以理解为:
把 Loss 对应到 H,12730 个参数对应到 (x,y),则 Loss 对所有参数的梯度可以表示为下面向量,该向量的长度为 12730:
$$
\nabla L(w,b) = \left[
\frac{\partial L}{\partial w_1},
\frac{\partial L}{\partial w_2},...,
\frac{\partial L}{\partial b_{26}}
\right] ^\top
$$
所以,每次迭代过程可以概括为
用梯度来调整参数的式子如下(为了简化,这里省略了 bias):
上式中, 是学习率,意为每次朝下降最快的方向前进一小步,避免优化过头(Overshoot)。
由于神经网络参数繁多,所以需要更高效的计算梯度的算法,于是,反向传播算法(Backpropagation)呼之欲出。
在学习反向传播算法之前,我们先复习一下微积分中的链式法则(Chain Rule):设 g = u(h) , h = f(x) 是两个可导函数,x 的一个很小的变化 △x 会使 h 产生一个很小的变化 △h,从而 g 也产生一个较小的变化 △g,现要求 △g/△x,可以使用链式法则:
有了以上基础,理解反向传播算法就简单了。
假设我们的演示网络只有 2 层,输入输出都只有 2 个神经元,如下图所示:
其中 是输入, 是输出, 是样本的目标值,这里使用的损失函数 L 为 MSE;图中的上标 (1) 或 (2) 分别表示参数属于第 (1) 层或第 (2) 层,下标 1 或 2 分别表示该层的第 1 或 第 2 个神经元。
现在我们来计算 和 ,掌握了这 2 个参数的偏导数计算之后,整个梯度的计算就掌握了。
所谓反向传播算法,指的是从右向左来计算每个参数的偏导数,先计算 ,根据链式法则
对左边项用链式法则展开
又 是输出值, 可以直接通过 MSE 的导数算出:
而 ,则 就是 sigmoid 函数的导数在 处的值,即
于是 就算出来了:
再来看 这一项,因为
所以
注意:上面式子对于所有的 和 都成立,且结果非常直观,即 对 的偏导为左边的输入 的大小;同时,这里还隐含着另一层意思:需要调整哪个 来影响 ,才能使 Loss 下降得最快,从该式子可以看出,当然是先调整较大的 值所对应的 ,效果才最显著 。
于是,最后一层参数 的偏导数就算出来了
我们再来算上一层的 ,根据链式法则 :
继续展开左边这一项
你发现没有,这几乎和计算最后一层一摸一样,但需要注意的是,这里的 对 Loss 造成的影响有多条路径,于是对于只有 2 个输出的本例来说:
上式中, 都已经在最后一层算出,下面我们来看下 ,因为
于是
同理
注意:这里也引申出梯度下降的调参直觉:即要使 Loss 下降得最快,优先调整 weight 值比较大的 weight。
至此, 也算出来了
观察上式, 所谓每个参数的偏导数,通过反向传播算法,都可以转换成线性加权(Weighted Sum)计算 ,归纳如下:
式子中 n 代表分类数,(l) 表示第 l 层,i 表示第 l 层的第 i 个神经元。 既然反向传播就是一个线性加权,那整个神经网络就可以借助于 GPU 的矩阵并行计算了 。
最后,当你明白了神经网络的原理,是不是越发的认为,它就是在做一堆的微积分运算,当然,作为能证明一个人是否学过微积分,神经网络还是值得学一下的。Just kidding ..
本文我们通过
这四点,全面的学习了神经网络这个知识点,希望本文能给你带来帮助。
参考:
