【问题标题】:RuntimeWarning: invalid value encountered in greaterRuntimeWarning:在更大的范围内遇到无效值
【发布时间】:2021-12-28 06:12:36
【问题描述】:

我尝试使用以下代码实现soft-maxout_vecnumpy 浮点向量):

numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator

但是,由于np.exp(out_vec),我收到了溢出错误。因此,我(手动)检查了np.exp()的上限是多少,发现np.exp(709)是一个数字,但np.exp(710)被认为是np.inf。因此,为了避免溢出错误,我将代码修改如下:

out_vec[out_vec > 709] = 709 #prevent np.exp overflow
numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator

现在,我得到一个不同的错误:

RuntimeWarning: invalid value encountered in greater out_vec[out_vec > 709] = 709

我添加的行有什么问题?我查找了这个特定的错误,我发现的只是人们关于如何忽略该错误的建议。简单地忽略错误对我没有帮助,因为每次我的代码遇到此错误时,它都不会给出通常的结果。

【问题讨论】:

  • out_vec 数组包含 NaNInf 值?
  • @kvorobiev 你知道我怎样才能捕捉到警告以便检查吗?
  • 试试np.isnan(np.sum(out_vec))
  • @kvorobiev 是的,我的意思是如何真正catch它(我调用这个代码数千次,我不能只打印输出)。
  • 请看我的回答

标签: python numpy softmax


【解决方案1】:

您的问题是由 out_vec 数组中的 NaNInf 元素引起的。您可以使用以下代码来避免此问题:

if np.isnan(np.sum(out_vec)):
    out_vec = out_vec[~numpy.isnan(out_vec)] # just remove nan elements from vector
out_vec[out_vec > 709] = 709
...

或者您可以使用以下代码将 NaN 值保留在您的数组中:

out_vec[ np.array([e > 709 if ~np.isnan(e) else False for e in out_vec], dtype=bool) ] = 709

【讨论】:

  • 谢谢@kvorobiev,但我不能这样做 - 简单地删除元素会导致数据丢失......
【解决方案2】:

IMO 更好的方法是使用指数和的数值更稳定的实现。

from scipy.misc import logsumexp
out_vec = np.exp(out_vec - logsumexp(out_vec))

【讨论】:

    【解决方案3】:

    在我的情况下,在比较之前调用它时警告没有出现(我比较了 NaN 值)

    np.warnings.filterwarnings('ignore')
    

    【讨论】:

    • numpy 中没有警告模块,这个 (np.warnings.filterwarnings('ignore')) 正在访问 python 标准库中内置的警告包,numpy 恰好导入了该包。该代码等效于import warningswarnings.filterwarnings('ignore'),它将禁止所有代码(不仅仅是numpy)生成的所有警告,除非您稍后重新启用警告。
    • 我也使用警告模块进行了警告抑制,但将其限制为需要它的少数语句:with np.warnings.filterwarnings('ignore'):
    • np.seterr(invalid='ignore') 似乎是一个更好的选择
    • 如果你想全力以赴,试试np.seterr(all='raise')
    【解决方案4】:

    如果发生这种情况是因为您的 NaN 值,那么这可能会有所帮助:

    out_vec[~np.isnan(out_vec)] = out_vec[~np.isnan(out_vec)] > 709
    

    这对没有 NaN 值执行更大的操作,其余保持不变。如果您需要其余部分为 False,那么也这样做:

    out_vec[np.isnan(out_vec)] = False
    

    【讨论】:

    • 这应该是最好的答案!
    猜你喜欢
    • 1970-01-01
    • 2013-02-18
    • 2018-04-30
    • 1970-01-01
    • 2016-10-13
    • 2013-01-29
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多