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

使用scipy.optimize最小化二元函数时遇标量返回值错误求助

scipy.optimize.minimize报错:目标函数必须返回标量值

问题重现

你编写了用于最小化卡方值的Python代码,但运行时抛出错误:

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

完整代码及依赖

import numpy as np
import matplotlib.pyplot as plt
import math
from scipy.integrate import quad
import scipy.optimize as optimize

# 已定义变量
f_0 = 0.261
G_F = 1.166 * 10**(-5)
m_e = 0.511 * 10**(-3)
dB_dqsq_arr = np.array([7.2,7.14,6.7,7.56,6.44,7.17,6.67,6.33,6.2,4.32,4.25,3.4,1.17])
dBdqsq_err_arr = np.array([0.70,0.45,0.39,0.43,0.43,0.45,0.47,0.48,0.44,0.43,0.41,0.42,0.26])
q_sq_arr = np.array([1,3,5,7,9,11,13,15,17,19,21,23,25])

def f_multi_para(q_sq, alpha_par):
    return f_0 / (q_sq * alpha_par)

def dB_dqsq_model2_para(q_sq, V_ub_par, alpha_par):
    sec1 = G_F**2 * V_ub_par
    sec2 = (1 - m_e**2 / q_sq)**2
    sec3 = (q_sq * (1 + m_e**2 / q_sq) * f_multi_para(q_sq, alpha_par)**2)
    return sec1 * sec2 * sec3

def chi_sq(params):
    V_ub_par, alpha_par = params
    return np.sum(((dB_dqsq_arr - np.array([dB_dqsq_model2_para(v, V_ub_par, alpha_par) for v in q_sq_arr])) / dBdqsq_err_arr)**2)

initial_guess = [0.0037, 0.54]
result = optimize.minimize(chi_sq, initial_guess)
if result.success:
    fitted_params = result.x
    print(fitted_params)
else:
    raise ValueError(result.message)

错误原因

这个错误的核心是scipy.optimize.minimize要求目标函数(即chi_sq)必须返回单个数值(标量),你的代码出现问题的可能原因:

  • 循环遍历计算模型值时,隐性引入了数组维度不匹配问题(虽然代码中长度一致,但循环写法容易出错);
  • 优化过程中alpha_par可能趋近于0,导致f_multi_para计算出现无穷大,部分旧版本scipy会将其判定为无效返回值;
  • 循环计算效率低,容易在数组转换时产生隐性错误。

修复方法

方法1:改用数组广播计算(推荐)

将模型函数改为直接支持数组输入,避免循环,既高效又能彻底消除维度问题:

def f_multi_para(q_sq, alpha_par):
    return f_0 / (q_sq * alpha_par)  # 直接处理q_sq数组

def dB_dqsq_model2_para(q_sq, V_ub_par, alpha_par):
    sec1 = G_F**2 * V_ub_par
    sec2 = (1 - m_e**2 / q_sq)**2
    sec3 = (q_sq * (1 + m_e**2 / q_sq) * f_multi_para(q_sq, alpha_par)**2)
    return sec1 * sec2 * sec3

def chi_sq(params):
    V_ub_par, alpha_par = params
    # 直接传入整个q_sq_arr数组计算模型值
    model_vals = dB_dqsq_model2_para(q_sq_arr, V_ub_par, alpha_par)
    # 数组自动广播运算,无需循环
    return np.sum(((dB_dqsq_arr - model_vals) / dBdqsq_err_arr)**2)

方法2:添加参数边界约束

为避免alpha_par趋近于0导致的除以0问题,给优化参数设置合理范围:

initial_guess = [0.0037, 0.54]
# 根据实际物理意义调整参数范围
bounds = [(0.001, 0.01), (0.01, 1.0)]
result = optimize.minimize(chi_sq, initial_guess, bounds=bounds)

方法3:验证目标函数返回值

在chi_sq函数中添加打印语句,确认返回值类型和数值:

def chi_sq(params):
    V_ub_par, alpha_par = params
    model_vals = np.array([dB_dqsq_model2_para(v, V_ub_par, alpha_par) for v in q_sq_arr])
    chi_sq_val = np.sum(((dB_dqsq_arr - model_vals) / dBdqsq_err_arr)**2)
    print(f"返回值类型:{type(chi_sq_val)},值:{chi_sq_val}")
    return chi_sq_val

如果返回值是标量但仍报错,建议更新scipy到最新版本,旧版本可能存在兼容性问题。

修复后完整代码

import numpy as np
import scipy.optimize as optimize

# 已定义变量
f_0 = 0.261
G_F = 1.166 * 10**(-5)
m_e = 0.511 * 10**(-3)
dB_dqsq_arr = np.array([7.2,7.14,6.7,7.56,6.44,7.17,6.67,6.33,6.2,4.32,4.25,3.4,1.17])
dBdqsq_err_arr = np.array([0.70,0.45,0.39,0.43,0.43,0.45,0.47,0.48,0.44,0.43,0.41,0.42,0.26])
q_sq_arr = np.array([1,3,5,7,9,11,13,15,17,19,21,23,25])

def f_multi_para(q_sq, alpha_par):
    return f_0 / (q_sq * alpha_par)

def dB_dqsq_model2_para(q_sq, V_ub_par, alpha_par):
    sec1 = G_F**2 * V_ub_par
    sec2 = (1 - m_e**2 / q_sq)**2
    sec3 = (q_sq * (1 + m_e**2 / q_sq) * f_multi_para(q_sq, alpha_par)**2)
    return sec1 * sec2 * sec3

def chi_sq(params):
    V_ub_par, alpha_par = params
    model_vals = dB_dqsq_model2_para(q_sq_arr, V_ub_par, alpha_par)
    return np.sum(((dB_dqsq_arr - model_vals) / dBdqsq_err_arr)**2)

initial_guess = [0.0037, 0.54]
bounds = [(0.001, 0.01), (0.01, 1.0)]
result = optimize.minimize(chi_sq, initial_guess, bounds=bounds)

if result.success:
    fitted_params = result.x
    print(f"拟合参数:V_ub_par={fitted_params[0]:.6f}, alpha_par={fitted_params[1]:.6f}")
else:
    raise ValueError(result.message)

内容的提问来源于stack exchange,提问作者noob anomaly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:45:55