我目前正在尝试实现一个机器学习算法,涉及到在MATLAB中的logistic loss function不幸的是,由于数值溢出,我遇到了一些麻烦。
一般来说,对于给定的输入s
,logistic函数的值为:
log(1 + exp(s))
logistic损失函数的斜率为:
exp(s)./(1 + exp(s)) = 1./(1 + exp(-s))
在我的算法中,
s = X*beta
的值这里X
是具有每个数据点的N
数据点和P
特征(即size(X)=[N,P]
)的矩阵,beta
是每个特征的P
系数的向量,因此size(beta)=[P 1]
。我特别感兴趣的是计算给定值
beta
的Logistic函数的平均值和梯度。Logistic函数w.r.t的平均值
beta
为: L = 1/N * sum(log(1+exp(X*beta)),1)
Logistic函数w.r.t.的斜率平均值
b
为: dL = 1/N * sum((exp(X*beta)./(1+exp(X*beta))' X, 1)'
注意
size(dL) = [P 1].
我的问题是这些表达式不断产生数值溢出问题实际上来自于当
exp(s)=Inf
时s>1000
和exp(s)=0
时s<-1000.
这两个事实我正在寻找一种解决方案,使得
s
可以接受浮点运算中的任何值理想情况下,我也会非常感谢一个解决方案,它允许我以矢量化/高效的方式评估值和梯度。 最佳答案
下面的近似是怎样的:
–对于计算L
,如果s
很大,则exp(s)
将远远大于1:
1 + exp(s) ≅ exp(s)
因此
log(1 + exp(s)) ≅ log(exp(s)) = s.
如果
s
很小,则使用exp()的Taylor seriesexp(s) ≅ 1 + s
使用Taylor级数log()
log(1 + exp(s)) ≅ log(2 + s) ≅ log(2) + s / 2.
–对于计算
dL
,对于大型s
exp(s) ./ (1 + exp(s)) ≅ 1
对于较小的
s
exp(s) ./ (1 + exp(s)) ≅ 1/2 + s / 4.
–计算
L
的代码可以如下所示:s = X*beta;
l = log(1+exp(s));
ind = isinf(l);
l(ind) = s(ind);
ind = (l == 0);
l(ind) = log(2) + s(ind) / 2;
L = 1/N * sum(l,1)