sigmoid/softmax指数运算溢出问题
sigmoid/softmax指数运算溢出问题
sigmoid和softmax函数在计算中,都会用到指数运算
e
−
x
e^{-x}
e−x或
e
x
e^{x}
ex,如果在
e
−
x
e^{-x}
e−x中
x
x
x是一个很小的负数,如-128等,或者在
e
x
e^{x}
ex中
x
x
x是一个很大的正数,如128等,这时有溢出的风险。
而sigmoid和softmax的结果是一个在0~1之间的值,所以可以看到这种溢出只是一种中间过程,对于结果来说并不会有溢出,来看下如何去解决这个问题
解决 s i g m o i d sigmoid sigmoid函数溢出问题
1.如果 x > 0 x>0 x>0则 y = 1 1 + e − x y=\frac{1}{1+e^{-x}} y=1+e−x1
2.如果
x
<
0
x<0
x<0则
y
=
e
x
1
+
e
x
y=\frac{e^{x}}{1+e^{x}}
y=1+exex
python代码如下:
import numpy as np
def sigmoid(x):
if x >= 0:
return 1 / (1 + np.exp(-x))
else:
return np.exp(x) / (1 + np.exp(x))
解决LR模型中计算cross entropy溢出问题
1.label记为
y
y
y
2. 记
z
=
1
1
+
e
−
x
z=\frac{1}{1+e^{-x}}
z=1+e−x1
c
r
o
s
s
e
n
t
r
o
p
y
=
y
∗
−
l
o
g
(
s
i
g
m
o
i
d
(
z
)
)
+
(
1
−
y
)
∗
−
l
o
g
(
1
−
s
i
g
m
o
i
d
(
z
)
)
cross entropy=y*-log(sigmoid(z))+(1-y)*-log(1-sigmoid(z))
crossentropy=y∗−log(sigmoid(z))+(1−y)∗−log(1−sigmoid(z))
=
y
∗
−
l
o
g
(
1
1
+
e
−
x
)
+
(
1
−
y
)
∗
−
l
o
g
(
1
−
1
1
+
e
−
x
)
=y*-log(\frac{1}{1+e^{-x}})+(1-y)*-log(1-\frac{1}{1+e^{-x}})
=y∗−log(1+e−x1)+(1−y)∗−log(1−1+e−x1)
=
y
∗
l
o
g
(
1
+
e
−
x
)
+
(
1
−
y
)
∗
(
−
l
o
g
(
e
−
x
)
+
l
o
g
(
1
+
e
−
x
)
)
=y*log({1+e^{-x}})+(1-y)*(-log(e^{-x})+log(1+e^{-x}))
=y∗log(1+e−x)+(1−y)∗(−log(e−x)+log(1+e−x))
=
y
∗
l
o
g
(
1
+
e
−
x
)
+
(
1
−
y
)
∗
(
x
+
l
o
g
(
1
+
e
−
x
)
)
=y*log({1+e^{-x}})+(1-y)*(x+log(1+e^{-x}))
=y∗log(1+e−x)+(1−y)∗(x+log(1+e−x))
=
(
1
−
y
)
∗
x
+
l
o
g
(
1
+
e
−
x
)
=(1-y)*x+log(1+e^{-x})
=(1−y)∗x+log(1+e−x)
=
x
−
x
∗
y
+
l
o
g
(
1
+
e
−
x
)
=x-x*y+log(1+e^{-x})
=x−x∗y+log(1+e−x)
对于
x
<
0
x<0
x<0有溢出风险时,变换
x
x
x为
l
o
g
(
e
x
)
log(e^{x})
log(ex)
则上式可以变换为:
=
x
−
x
∗
y
+
l
o
g
(
1
+
e
−
x
)
=x-x*y+log(1+e^{-x})
=x−x∗y+log(1+e−x)
=
l
o
g
(
e
x
)
−
x
∗
y
+
l
o
g
(
1
+
e
−
x
)
=log(e^{x})-x*y+log(1+e^{-x})
=log(ex)−x∗y+log(1+e−x)
=
−
x
∗
y
+
l
o
g
(
1
+
e
x
)
=-x*y+log(1+e^{x})
=−x∗y+log(1+ex)
综合起来,对于
c
r
o
s
s
e
n
t
r
o
p
y
=
m
a
x
(
x
,
0
)
−
x
∗
y
+
l
o
g
(
1
+
e
−
∣
x
∣
)
cross entropy = max(x,0)-x*y+log(1+e^{-|x|})
crossentropy=max(x,0)−x∗y+log(1+e−∣x∣)
python代码如下:
import numpy as np
def cross_entropy(y, x):
if x >= 0:
return (1-y) * x + np.log(1 + np.exp(-x))
else:
return (-x) * y + np.log(1 + np.exp(x))
解决 s o f t m a x softmax softmax函数溢出问题
在多元分类问题中,经常会用到
s
o
f
t
m
a
x
softmax
softmax函数
s
o
f
t
m
a
x
softmax
softmax函数形式如下:
y
=
e
x
i
∑
i
=
1
n
e
x
i
y=\frac{e^{x_{i}}}{\sum_{i=1}^{n}{e^{x_{i}}}}
y=∑i=1nexiexi
a.取所有
x
i
x_{i}
xi中的最大值M,则计算
(
x
1
,
x
2
,
x
3
,
.
.
.
.
.
.
,
x
n
)
(x_{1},x_{2},x_{3},......,x_{n})
(x1,x2,x3,......,xn)这组数的softmax等同于计算
(
x
1
−
M
,
x
2
−
M
,
x
3
−
M
,
.
.
.
.
.
.
,
x
n
−
M
)
(x_{1}-M,x_{2}-M,x_{3}-M,......,x_{n}-M)
(x1−M,x2−M,x3−M,......,xn−M)这一组数据的softmax,非常容易推导的,分子分母同时除以
e
M
e^{M}
eM即可
b.所以这样softmax改成计算
y
=
e
x
i
−
M
∑
i
=
1
n
e
x
i
−
M
y=\frac{e^{x_{i}-M}}{\sum_{i=1}^{n}{e^{x_{i}-M}}}
y=∑i=1nexi−Mexi−M,就解决了上溢出的问题,因为中间项都是小于等于1的值
python代码
import numpy as np
def softmax(X, k):
if k >= len(X):
return -1
else:
X = np.array(X)
# 获得X中的最大值
val_max = max(X)
sum_X = 0
for i in range(len(X)):
sum_X += np.exp(X[i] - val_max)
return np.exp(X[k] - val_max) / sum_X