You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数返回标量仍触发ValueError:目标函数需返回标量问题排查

问题排查:scipy.optimize.minimize(BFGS)触发ValueError:目标函数需返回标量

使用scipy.optimize.minimize的BFGS方法优化时,持续触发如下错误:

ValueError: The user-provided objective function must return a scalar value

但确认自定义目标函数my_func_v每次返回的都是标量或SymPy常量,附上代码寻求原因排查:

from sympy import Symbol
from sympy.stats import Normal, density, sample_iter
from scipy.optimize import minimize
from sympy import Sum, binomial, exp, simplify
def my_func_v(args):
    print(args)
    N = Normal("N", args[0], args[1])
    y = Symbol("y", real = True)
    samples = list(sample_iter(N, numsamples=200))
    sampleSum = sum(samples)
    print("Gotten samples")
    func = simplify((Sum(sum([simplify(binomial(20,y)*(1/(1+exp(-sample)))**y*(exp(-sample)/(1+exp(-sample)))**(20-y)*density(N)(sample))/sampleSum for sample in samples]), (y, 0, 10)).doit() - 0.8)**2)
    print(f"Done with func with end value: {func}")
    return func
print("Now optimizing")
results = minimize(my_func_v, [1,1], method='BFGS', options={"disp": True, "return_all": True})

错误原因

  • 目标函数返回的是SymPy符号表达式对象,而非scipy优化器要求的Python原生数值标量(如float类型)。即使SymPy常量看起来是数值,它本质是符号对象,scipy无法将其识别为可用于优化的数值标量。
  • 代码中func经过simplify处理后仍是SymPy的符号类型(比如Float),不符合scipy对目标函数返回值的类型要求。

解决方法

  1. 转换返回值类型:在返回结果前,将SymPy对象转换为Python原生数值,修改目标函数的return语句:

    return float(func)
    

    或者用func.evalf()先求值再转float,效果一致。

  2. 额外优化建议:

    • 当前代码用SymPy做采样+符号求和,计算效率极低,且BFGS算法依赖目标函数的梯度(当前实现无法提供有效解析梯度,自动差分也会因为符号运算变得异常缓慢)。
    • 建议改用纯数值计算替代SymPy符号运算,或者切换到不需要梯度的优化方法(如Nelder-Mead);如果坚持用BFGS,需要手动实现目标函数的梯度计算。

内容的提问来源于stack exchange,提问作者Striking eagle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:30:55