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

调用scipy.fmin_powell优化时报'tuple' object is not callable如何解决

问题描述

我正在学习编写机器学习模型代码,遇到了TypeError类型错误。我查到了类似问题python fsolve: 'list' object is not callable,但该问题的解决方案无法解决我的问题。

代码如下:

def cost_fun(self, lam, x, theta, m):
    """
    :type lam: int
    :type x: numpy.ndarray
    :type theta: numpy.ndarray 
    :type m: int
    """
    # sigmoid为sigmoid激活函数
    hyp = np.transpose(sigmoid(np.transpose(theta) * x))
    J = np.dot(-self.y, np.transpose(np.log(hyp))) - \
        (np.dot(1 - self.y,
                np.transpose(np.log(1 - hyp))) / m) + \
        np.dot((sum(theta ** 2) - theta[0] ** 2), lam / (2 * m))

    grad = np.transpose(np.dot(np.transpose(np.divide(x, m // 2)),
                        np.transpose((hyp - self.y)))) + \
        (np.dot(theta, lam) / (m // 2))

    grad[0] = 1 / m * sum(np.transpose(hyp - self.y) * x[0])

    return J, grad


def grad_desc(self, lam):
    """
    :type lam: int
    :type params: numpy.ndarray
    """
    min_theta1 = fmin_powell(
        self.cost_fun(lam, self.x, self.params, self.m), self.params
    )

报错信息如下:

Traceback (most recent call last):
  File "C:/Users/Michael/OneDrive/Desktop/machinelearning.py", line 133, in <module>
    main()
  File "C:/Users/Michael/OneDrive/Desktop/machinelearning.py", line 17, in main
    ai.train(lam=5)
  File "C:/Users/Michael/OneDrive/Desktop/machinelearning.py", line 126, in train
    self.grad_desc(lam)
  File "C:/Users/Michael/OneDrive/Desktop/machinelearning.py", line 111, in grad_desc
    self.cost_fun(lam, self.x, self.params, self.m), self.params
  File "C:\Users\Michael\anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 2558, in fmin_powell
    res = _minimize_powell(func, x0, args, callback=callback, **opts)
  File "C:\Users\Michael\anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 2631, in _minimize_powell
    fval = squeeze(func(x))
  File "C:\Users\Michael\anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 327, in function_wrapper
    return function(*(wrapper_args + args))
TypeError: 'tuple' object is not callable
Process finished with exit code 1
错误原因
  • scipy的fmin_powell优化器第一个入参要求传入可调用的函数对象,你代码中直接写self.cost_fun(lam, self.x, self.params, self.m)是先执行了损失函数,拿到了返回的(J, grad)元组,优化器运行时尝试把这个元组当做函数调用,直接触发类型错误。
  • 待优化的参数theta应该是优化器动态调整的变量,你提前把固定的self.params传给损失函数,相当于写死了待优化参数,优化器无法完成参数更新。
  • fmin_powell是无导数优化算法,不需要传入梯度值,你当前的损失函数同时返回损失和梯度,优化器无法正确解析返回结果。
修复方案
  1. 调整损失函数的参数顺序,把待优化的theta放到第一位,同时仅返回损失值:
def cost_fun(self, theta, lam, x, m):
    """
    :type theta: numpy.ndarray 
    :type lam: int
    :type x: numpy.ndarray
    :type m: int
    """
    hyp = np.transpose(sigmoid(np.transpose(theta) * x))
    J = np.dot(-self.y, np.transpose(np.log(hyp))) - \
        (np.dot(1 - self.y,
                np.transpose(np.log(1 - hyp))) / m) + \
        np.dot((sum(theta ** 2) - theta[0] ** 2), lam / (2 * m))
    return J
  1. 调整fmin_powell的调用方式,传入函数对象,把固定参数放到args中:
def grad_desc(self, lam):
    """
    :type lam: int
    """
    min_theta1 = fmin_powell(
        self.cost_fun, # 仅传入函数对象,不要加括号执行
        self.params, # 待优化参数的初始值
        args=(lam, self.x, self.m) # 其他固定参数按顺序传入
    )

如果你需要利用已经计算好的梯度提升优化效率,可以更换为支持梯度输入的优化器(比如fmin_tnc),保留损失函数返回(J, grad)的逻辑,调用时补充fprime参数即可。

内容的提问来源于stack exchange,提问作者Michael Williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 22:51:02