本文已参与「新人创作礼」活动,一起开启掘金创作之路。
引言
上一期,我们介绍了softmax函数的C++实现,但是考虑到sigmoid和tanh函数也是带e的次幂,所以现在我们来考虑该函数的防止溢出实现。
sigmoid函数
原理
该函数的公式为:
1+e−x1
在x≥0的时候,e−x≤1,不会溢出,但是在x<0的时候,就有可能溢出了。所以在x<0时,我们可以做如下变换:
1+e−x1=(1+e−x)⋅ex1⋅ex=ex+1ex
这样ex<1,也不会溢出了。
实现
double sigmoid(double x)
{
if (x > 0)
return 1.0 / (1.0 + exp(-x));
else
return exp(x) / (1.0 + exp(x));
}
tanh函数
原理
该函数的公式为:
ex+e−xex−e−x
那么在x很大或者很小时,都有可能溢出,所以我们分开考虑。
1、x≥0时
这时ex可能溢出,e−x<1不会溢出。我们进行如下变换:
ex+e−xex−e−x=e−x⋅(ex+e−x)e−x⋅(ex−e−x)=1+e−2x1−e−2x
1、x<0时
这时e−x可能溢出,ex<1不会溢出。我们进行如下变换:
ex+e−xex−e−x=ex⋅(ex+e−x)ex⋅(ex−e−x)=e2x+1e2x−1
这样就都不会溢出了。
实现
double tanh(double x)
{
if(x > 0)
return (1-exp(-2*x))/(1+exp(-2*x));
else
return (exp(2*x)-1)/(1+exp(2*x));
}