如何解决Python NumPy在计算过程中出现的数值溢出问题?

千静姑娘_9873

千静姑娘_9873

2026-07-04

361人浏览

原创

np.float64会溢出是因为其动态范围有限(约±1.8e308),而非精度不足;当exp(x)等运算产出超限值时即得inf/nan,常见于softmax、logsumexp等场景,需通过减最大值等数值稳定技巧规避。

如何解决python numpy在计算过程中出现的数值溢出问题?

为什么 np.float64 还会溢出?

不是精度不够,而是动态范围超限——np.float64 最大值约 1.8e308,一旦中间计算(如 np.exp(x)、np.power(2, x) 或矩阵指数)产出更大值,就会变成 inf,后续运算全失效。常见于 softmax、log-sum-exp、概率密度函数或深度学习梯度计算中。

典型错误现象:RuntimeWarning: overflow encountered in exp,或结果突然出现 inf / nan,但输入本身看起来“很安全”。

  • 别直接对原始输入调 np.exp,尤其当输入含较大正数时
  • 检查是否在循环或累积计算中未重置中间状态(比如累加未归一化)
  • np.float64 无法避免溢出,只是延后;真正要控制的是数值的“相对尺度”

用 logsumexp 替代 np.log(np.sum(np.exp(x)))

这是最典型的修复场景:手动写 np.log(np.sum(np.exp(x))) 极易溢出,而 scipy.special.logsumexp 内部做了平移稳定化(减去 x.max())。

示例对比:

import numpy as np
from scipy.special import logsumexp
<p>x = np.array([1000, 1001, 1002])  # 直接 exp 会 overflow</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6591" title="Li Python Sec Check"><img
														src="https://img.php.cn/upload/skill/000/000/081/179102166033725.jpg" alt="Li Python Sec Check" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill6591" title="Li Python Sec Check" class="overflowclass">Li Python Sec Check</a>
													<p class="overflowclass">Python 安全规范检查工具:基于 CloudBase 规范、腾讯安全指南,LLM 智能分析(默认禁用,优先本地执行)</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill6591" title="Li Python Sec Check" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div><h1>❌ 危险写法</h1><p>try:
bad = np.log(np.sum(np.exp(x)))
except:
bad = float('nan')  # 实际会得 inf → log(inf) → inf</p><h1>✅ 安全写法</h1><p>good = logsumexp(x)  # 返回 ~1002.55,精确且无警告</p>
  • 如果你没引入 scipy,可手写等效逻辑:max_x = x.max(); np.log(np.sum(np.exp(x - max_x))) + max_x
  • 注意 logsumexp 支持 axis 和 b(权重)参数,别忽略维度匹配
  • 不要在已知会溢出的数组上先调 np.exp 再传给它——它自己会处理

softmax 计算必须做减最大值预处理

标准 softmax 公式 np.exp(x) / np.sum(np.exp(x)) 在任意单个元素远大于其余时,分子分母都可能溢出,但比值其实稳定。关键是在指数前统一减去 x.max()。

正确实现:

def stable_softmax(x):
    x = x - x.max(axis=-1, keepdims=True)  # 沿最后一维减最大值
    exp_x = np.exp(x)
    return exp_x / np.sum(exp_x, axis=-1, keepdims=True)
<h1>测试</h1><p>x = np.array([[1000, 1005, 1002]])
print(stable_softmax(x))  # [0.042, 0.877, 0.081],而非 [nan, nan, nan]</p>
  • 务必用 keepdims=True,否则广播失败
  • 如果 x 是 1D,axis=-1 仍有效;但若明确是行向量,用 axis=1 更直觉
  • 框架如 PyTorch/TensorFlow 的 F.softmax 默认已稳定,但手写或调试时必须自己加这步

何时该换数据类型或算法,而不是硬扛?

有些场景靠平移技巧也救不回来:比如高阶多项式求值、大整数阶乘、或 np.linalg.inv 对病态矩阵求逆时的中间范数爆炸。这时需跳出“只调参”思维。

  • 确认是否真需要 float64:多数机器学习任务用 np.float32 足够,且内存/速度更优;溢出风险反而更低(因数值本就更小)
  • 避免显式计算大指数:例如贝叶斯后验中,用对数空间全程运算,最后才 np.exp(log_posterior)(且仅当必要时)
  • 线性代数问题优先考虑 SVD 或 QR 分解替代直接求逆;np.linalg.solve 比 np.linalg.inv + dot 更稳
  • 实在要算大数?用 decimal.Decimal 或 mpmath,但代价是速度暴跌,仅限调试或小规模验证

数值稳定不是“加个 -x.max() 就万事大吉”,而是理解每一步运算的量级如何传导。溢出往往暴露的是建模或流程设计缺陷,比如未归一化的特征、未裁剪的梯度、或过深的网络层叠。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1671

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4224

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1669

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

24497

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2987

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3027

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1163

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2343

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程