(四)激活函数与loss梯度
激活函数
科学家对于青蛙的神经元的研究,发现青蛙的神经元有多个输入,中间是一个对输入加权的响应,但是这个响应不是线性的输出,而是基于一个阈值来作为标准,当响应值大于阈值时才会输出,而且输出的大小是固定的。这个计算的函数就是阶梯函数。
上图就是基于青蛙的神经元发明的一个计算机上的模型。它的输入是 x 1 , . . . , x n x_1,...,x_n x1,...,xn,然后经过加权求和,但并不是直接输出,而是经过一个阶梯函数后输出。这里就可以比较好的解释激活函数激活的意思,如果计算的结果大于0,则输出为1(这里假设为1),如果小于0则输出为0,认为大于0的输出才有效,所以大于0的输出就起到了激活作用,而小于0的输出处于睡眠状态。但是这个函数是不可导的,所以我们不能用梯度下降的方法来优化,在当时采用了一种启发式搜索的方法来优化,这里不再多说。
sigmoid
为了解决单层感知机激活函数不可导的情况,科学家提出了一种连续的可导的函数——sigmoid
σ
(
x
)
=
1
1
+
e
−
x
\sigma (x) = \frac{1}{1 + e^{-x}}
σ(x)=1+e−x1
可以看到sigmoid函数能够把一个函数值为 ( − ∞ , + ∞ ) (-\infty,+\infty) (−∞,+∞)压缩到 ( 0 , 1 ) (0,1) (0,1)区间内
下面来推导sigmoid函数导数的情况
可以看到,sigmoid函数求导只需要自身函数的值即可。
但是当 x − > − ∞ x->-\infty x−>−∞或者 x − > + ∞ x->+\infty x−>+∞时, σ ′ = 0 \sigma'=0 σ′=0,所以 θ ′ = θ − Δ \theta' = \theta - \Delta θ′=θ−Δ会很长时间得不到更新,使得长时间 l o s s loss loss保持不变的情况,导致梯度离散的情况。
下面来看下sigmoid函数在PyTorch中怎么实现
tanh
从上面公式可以看出,其可以用sigmoid函数来表示。
下面来看其导数:
下面来看在Pytorch中怎么使用
relu
下面来看下在PyTorch中怎么使用relu
softmax
下面给出sotfmax的求导过程
总结一下
下面来看下在PyTorch中怎么使用softmax
这里的retain_graph让图不能被清楚,可以再次调用计算梯度的信息。
loss及其梯度
以下介绍两种典型的loss
Mean Squared Error(均方差)
以下先给出均方差的一些公式:
以上公式是为了得出均方差和norm的关系,norm的一些概念比较简单,norm(1)为求和,norm(2)为平方和开根,不清楚直接查询即可。
第一个公式就是均方差的公式,可以直接得出loss,下面我们来看loss的梯度求解情况:
具体的求导过程这里不再给出,运用高数的知识很容易求解。
Cross Entropy Loss(交叉熵)
entropy中文叫做熵也叫做不确定性或者自由度。熵越大说明不确定越小,自由度越小。举个例子,假如你本来就长得很好看,我说你长得好看,那我这句话基本等于废话,所以这句话的不确定性就很低,熵就很高;再举个反面的例子,假如你本来很穷,我说你很有钱,这句话就会产生很大的反响,所以这句话的不确定性就很高,熵就很低。下面来看熵的定义
下面我们来用一些具体例子来理解下:
从中可以看出,当数据的差别越小的时候,熵越大,数据差别越大的时候,熵越小。
entorpy指的是一个分布,而cross entropy指的是两个分布,这里设为p,q
以上为两个分布的交叉熵公式
D K L D_{KL} DKL为散度,是真正衡量两个分布具体的关系。
当两个分布几乎完全一样的时候 D K L D_{KL} DKL的值几乎为0,两个分布不相同的时候, D K L D_{KL} DKL的值很大,这和熵的值相反。
当p和q的分布相同的时候得到 H ( p , q ) = H ( p ) H(p,q) = H(p) H(p,q)=H(p)。
这里提一下one-hot encoding,如果采用交叉熵的话,会得到
H
(
p
,
q
)
=
D
K
L
(
p
∣
q
)
H(p,q) = D_{KL}(p|q)
H(p,q)=DKL(p∣q)
这是因为H§ = 1log1 = 0。所以采用one-hot encoding的话,就直接用
D
K
L
D_{KL}
DKL来衡量交叉熵就行。
小结
在分类问题中我们会经常使用交叉熵,而不是使用均方差,这是因为
(1)用sigmoid和MSE搭配的话会很容易出现梯度离散的情况,这样创建起来会非常困难
(2)交叉熵的梯度更大,更容易收敛得更快
但是MSE求导会比较简单,在很多问题上也有很好的表现。
下面看看PyTorch中怎么使用交叉熵
从中可以看出 cross_entropy = softmax + log + nll_loss
下面顺便说下如何使用PyTorch来进行求导
这种方法无法更新动态图,求导比较麻烦,我们下面使用另外一种方法进行求导
这里使用backward()函数进行反向自动的动态图更新,在创建w的时候使用requires_grad=True,让w可以计算梯度。
如果博客有问题欢迎大家给出意见,记得点赞、收藏加关注哦!