2013-02-23 56 views
2

我想使用scipy.optimize.check_grad來檢查我的sigmoid function實現的漸變;這裏是我的Python功能:使用Scipy檢查漸變

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。任何想法可能會造成這種情況?

File "scipy\optimize\optimize.py", line 597, in approx_fprime
grad[k] = (f(*((xk+d,)+args)) - f0)/d[k]
ValueError: operands could not be broadcast together with shapes (4,5) (4)

+0

如下所述,這是因爲要檢查梯度,您必須迭代矩陣的每個單元和+/-某個epsilon以計算導數(使用標準方程)。 Scipy可以將你的矩陣扁平化。但是,使用'M.flatten()'來傳遞一個扁平版本應該很容易。在Matlab中,你只需要'M(:)'。 – 2013-07-29 01:43:21

回答

2

你得到的錯誤是因爲check_gradient只接受平面數組的點。如果您使用形狀爲(20,)而非(4, 5)的數組x0,它應該可以工作。但它不!

這裏是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]) 

所以現在看來​​,這是真的不準備在其他地方非平面陣列了。但是,實施過程非常糟糕:您應該提交錯誤報告。

+0

儘管如此,逼近漸變的方式不起作用。您應該逐個增加每個參數「eps」。例如,當'f'將數組映射到標量時:梯度應該是一個數組,但是(f(x + eps) - f(x))/ eps'將產生一個標量。 – 2013-02-23 16:14:32

+1

@PaulManta我明白了,畢竟它並沒有那麼錯,那就是抓住了......在我看來,它仍然是一個非常無用的功能。我認爲它的設置方式只適用於將矢量轉換爲標量的函數,然後'x0'必須是單個矢量,而不是一堆。在你的情況下,如果'x0.shape =(1,)',你可以讓你的調用工作,即如果你給它一個長度爲1的矢量,它將不能用於標量。據我所知,這與它被破壞一樣好! – Jaime 2013-02-23 17:13:08

+0

是的,'check_grad'在很多情況下不是很有用,不幸的是。那麼,該算法很容易實現,所以它不應該是一個大問題。 – 2013-02-23 17:49:28