2

我想用来scipy.optimize.check_grad检查我的sigmoid 函数实现的梯度;这是我的 Python 函数:

def sigmoid(x, gradient=False):
    y = 1 / (1 + numpy.exp(-x))
    return numpy.multiply(y, 1 - y) if gradient else y

以下是参数和对 的调用check_grad

x0 = numpy.random.uniform(-30, 30, (4, 5))
func = sigmoid
grad = lambda x: sigmoid(x, gradient=True)
error = scipy.optimize.check_grad(func, grad, x0)

我收到以下错误。形状不匹配是指操作xk+d。知道是什么原因造成的吗?

文件“scipy\optimize\optimize.py”,第 597 行,在 approx_fprime
grad[k] = (f(*((xk+d,)+args)) - f0) / d[k]
ValueError: 操作数不能与形状一起广播 (4,5) (4)

4

1 回答 1

2

您得到的错误是因为check_gradient只接受平面点数组。x0如果您使用shape数组(20,)而不是(4, 5). 但事实并非如此!

这是approx_fprime我的安装(scipy.__version__ = '0.9.0')中的实现:

def approx_fprime(xk,f,epsilon,*args):
    f0 = f(*((xk,)+args))
    grad = numpy.zeros((len(xk),), float)
    ei = numpy.zeros((len(xk),), float)
    for k in range(len(xk)):
        ei[k] = epsilon
        grad[k] = (f(*((xk+ei,)+args)) - f0)/epsilon
        ei[k] = 0.0
    return grad

我已经看了好几遍,很难相信这么糟糕的代码会在 scipy 发行版中,我确信我一定遗漏了一些东西……但我担心这是错误的。如果您将其替换为:

def approx_fprime(xk,f,epsilon,*args):
    return (f(*((xk + epsilon,) + args)) - f(*((xk,) + args))) / epsilon

它现在对我有用。我得到x0.shape = (20,)

In [2]: error
Out[2]: 1.746097524556073e-08

并与x0.shape = (4, 5)

In [4]: error
Out[4]: 
array([  1.03560895e-08,   1.45994321e-08,   8.54143390e-09,
         1.09225833e-08,   9.85988655e-09])

所以它似乎真的没有为其他地方的非平面阵列做好准备。但无论哪种方式,实现都非常糟糕:您应该提交错误报告。

于 2013-02-23T15:42:53.377 回答