2

シグモイド関数scipy.optimize.check_gradの実装の勾配をチェックするために使用したい。ここに私の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形状の配列を使用した場合に機能するはずです。しかし、そうではありません!(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 に答える