我正在尝试对共生矩阵(C)进行因子分析,该矩阵是根据术语 - 文档矩阵(TD)计算的,如下所示:C = TD*TD'
理论上C应该是正半正定的,但事实并非如此,并且因子分析算法因此无法使用它.由于速度原因,我无法改变算法.
我查阅它可能是一个数值稳定性问题: 一个生成正半定矩阵的简单算法 - 答案2.
什么是在这里继续前进的好方法?
我目前正在尝试实现一种涉及MATLAB中逻辑损失函数的机器学习算法.不幸的是,由于数字溢出,我遇到了一些麻烦.
通常,对于给定的输入s,逻辑函数的值为:
log(1 + exp(s))
Run Code Online (Sandbox Code Playgroud)
并且逻辑损失函数的斜率是:
exp(s)./(1 + exp(s)) = 1./(1 + exp(-s))
Run Code Online (Sandbox Code Playgroud)
在我的算法中,值为s = X*beta.这X是一个矩阵,每个数据点具有N数据点和P特征(即size(X)=[N,P]),并且beta是P每个特征的系数向量size(beta)=[P 1].
我特别感兴趣的是计算给定值的Logistic函数的平均值和梯度beta.
Logistic函数的平均值为beta值为:
L = 1/N * sum(log(1+exp(X*beta)),1)
Run Code Online (Sandbox Code Playgroud)
Logistic函数斜率的平均值为b值为:
dL = 1/N * sum((exp(X*beta)./(1+exp(X*beta))' X, 1)'
Run Code Online (Sandbox Code Playgroud)
注意 size(dL) = [P 1].
我的问题是这些表达式不断产生数值溢出.问题有效地来自于一个事实,即exp(s)=Inf当s>1000与exp(s)=0时s<-1000.
我正在寻找一种解决方案,s可以采用浮点运算中的任何值.理想情况下,我也非常感谢一种解决方案,它允许我以矢量化/有效的方式评估值和梯度.
floating-point matlab numerical-methods numerical-stability logistic-regression
当我使用这个随机发生器时numpy.random.multinomial,我不断得到:
ValueError: sum(pvals[:-1]) > 1.0
Run Code Online (Sandbox Code Playgroud)
我总是传递这个softmax函数的输出:
def softmax(w, t = 1.0):
e = numpy.exp(numpy.array(w) / t)
dist = e / np.sum(e)
return dist
Run Code Online (Sandbox Code Playgroud)
除了我现在收到这个错误,我还为参数(pvals)添加了这个:
while numpy.sum(pvals) > 1:
pvals /= (1+1e-5)
Run Code Online (Sandbox Code Playgroud)
但这并没有解决它.确保我避免此错误的正确方法是什么?
编辑:这是包含此代码的函数
def get_MDN_prediction(vec):
coeffs = vec[::3]
means = vec[1::3]
stds = np.log(1+np.exp(vec[2::3]))
stds = np.maximum(stds, min_std)
coe = softmax(coeffs)
while np.sum(coe) > 1-1e-9:
coe /= (1+1e-5)
coeff = unhot(np.random.multinomial(1, coe))
return np.random.normal(means[coeff], stds[coeff])
Run Code Online (Sandbox Code Playgroud) 在我在C中工作的数值解算器中,我需要反转2x2矩阵,然后在右侧乘以另一个矩阵:
C = B . inv(A)
Run Code Online (Sandbox Code Playgroud)
我一直在使用倒置2x2矩阵的以下定义:
a = A[0][0];
b = A[0][1];
c = A[1][0];
d = A[1][1];
invA[0][0] = d/(a*d-b*c);
invA[0][1] = -b/(a*d-b*c);
invA[1][0] = -c/(a*d-b*c);
invA[1][1] = a/(a*d-b*c);
Run Code Online (Sandbox Code Playgroud)
在我解算器的前几次迭代中,这似乎给出了正确的答案,然而,经过几个步骤后,事情开始增长并最终爆炸.
现在,与使用SciPy的实现相比,我发现相同的数学不会爆炸.我能找到的唯一区别是SciPy代码使用scipy.linalg.inv(),它在内部使用LAPACK来执行反转.
当我用inv()上面的计算替换调用时,Python版本确实会爆炸,所以我很确定这是问题所在.计算中的微小差异正在蔓延,这使我相信它是一个数值问题 - 对于反演操作并不完全令人惊讶.
我正在使用双精度浮点数(64位),希望数值问题不会成为问题,但显然情况并非如此.
但是:我想在我的C代码中解决这个问题,而不需要调用像LAPACK这样的库,因为将它移植到纯C的全部原因是让它在目标系统上运行.此外,我想了解这个问题,而不仅仅是呼唤黑匣子.最终,如果可能的话,我也希望它以单精度运行.
所以,我的问题是,对于这样一个小矩阵,有一个数值上更稳定的方法来计算A的倒数吗?
谢谢.
编辑:目前试图弄清楚我是否可以通过解决来避免反演C.
我正在用C#构建类似CAD的应用程序.我正在使用SlimDX图形引擎,对于数字运算部分,我构建了最终依赖于System.Math类的自定义库.
现在,问题是SlimDX库使用由float数据类型组成的结构,而Math类包含几个只接受和返回双重对象的方法,例如:Math.Ceiling和Math.Sin.所以我发现自己不断地从浮动到双重来回投射我的数据.
这似乎不对.我不是那么担心演员阵容可能会对演奏造成的影响(也许我应该这么做?),但由于它们可能会出现数值不稳定性,这更加令人恐惧.
所以我只是想知道你通常如何管理这些情况,因为我猜这绝不是一个不常见的场景.
任何非零值recurrent_dropout都会产生 NaN 损失和权重;后者要么是 0,要么是 NaN。发生在堆叠、浅、stateful, return_sequences= 任何、带有 & w/o Bidirectional(), activation='relu', loss='binary_crossentropy'。NaN 发生在几个批次内。
有修复吗?感谢帮助。
recurrent_dropout=0.2,0.1,0.01,1e-6kernel_constraint=maxnorm(0.5,axis=0)recurrent_constraint=maxnorm(0.5,axis=0)clipnorm=50 (经验确定),Nadam 优化器activation='tanh'- 无 NaN,权重稳定,测试最多 10 个批次lr=2e-6,2e-5- 无 NaN,权重稳定,测试最多 10 个批次lr=5e-5- 3 个批次没有 NaN,权重稳定 - 第 4 批次有 NaNbatch_shape=(32,48,16)- 2 个批次损失较大,第 3 批次为 NaN注意:每批次batch_shape=(32,672,16)17 次调用train_on_batch
以下函数的工作原理应该与该函数类似,pow(x, 1/k)但围绕该线对称y = 1 - x,并且在 [0, 1] 的两端不具有 0 或 1 斜率:
def sym_gamma(x, k):
if k == 1.0:
return x
a = 1.0 / k - 1.0
b = 1.0 / a
c = k + 1.0 / k - 2.0;
return 1.0 / (a - c * x) - b
Run Code Online (Sandbox Code Playgroud)
可以看出,它没有定义,k = 1所以在这种情况下,我只需 return x。然而,这种特殊情况处理还不够,因为当x不等于但非常接近时,该函数的表现也很差1.0。例如,虽然它应该返回非常接近的东西,但它sym_gamma(0.5, 1.00000001)会产生。0.00.5
如何在稳定性差的情况下实现同样的效果?我知道我可以引入关于kequaling的容差1.0,但这感觉就像黑客,我还想确保该函数在 方面完全平滑 …
我正在研究一段代码,其中数字相等是几个逻辑条件中的一个重要因素.Clojure正在做一些我不太了解的事情.例如:
user=> (- 5 4.9)
0.09999999999999964
user=> (- 5 4.8)
0.20000000000000018
user=> (- 5 2.9)
2.1
user=> (- 5 2.7)
2.3
user=> (- 5 2.8)
2.2
user=> (- 9 6.9)
2.0999999999999996
user=> (- 9 2.9)
6.1
Run Code Online (Sandbox Code Playgroud)
在某些情况下,Clojure数字似乎将减法理解为0.1,而在其他情况下则不然.这里发生了什么?