deep-learning-from-scratch icon indicating copy to clipboard operation
deep-learning-from-scratch copied to clipboard

Is the numerical_gradient function wrong?

Open RainaRLN opened this issue 5 years ago • 1 comments

Here is the test code:

import numpy as np

def numerical_gradient(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x) # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val # 値を元に戻す
        it.iternext()   
        
    return grad

def func(x):
    if x.ndim == 1:
        return np.sum(x**2)
    else:
        return np.sum(x**2, axis=1)

if __name__ == "__main__":
    x = np.array([1, 2])
    grad = numerical_gradient(func, x)
    print(grad)

The output is [5000 15000].

Then I added x = x.astype(float) at the beginning of numerical_gradient():

def numerical_gradient(f, x):
    x = x.astype(float)
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x) # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val # 値を元に戻す
        it.iternext()   
        
    return grad

The output is [2. 4.]

Why type change is unnecessary?

RainaRLN avatar Jun 03 '20 05:06 RainaRLN

You can try this. def numerical_gradient(f, x):     h = 1e-4 # 0.0001     grad=np.zeros_like(x)     #print(x.shape[0],x.size)     for inx in range(x.shape[0]): #data size         #print(inx)         temp_x=x[inx]         x[inx]=temp_x+h         f_x1=f(x)         x[inx]=temp_x-h         f_x2=f(x)         grad[inx]=(f_x1-f_x2)/2*h         x[inx]=temp_x     return grad

------------------ 原始邮件 ------------------ 发件人:  "RainaRLN"<[email protected]>; 发送时间:  2020年6月3日(星期三)中午1:49 收件人:  "oreilly-japan/deep-learning-from-scratch"<[email protected]>; 抄送:  "Subscribed"<[email protected]>; 主题:  [oreilly-japan/deep-learning-from-scratch] Is the numerical_gradient function wrong? (#51)

Here is the test code: import numpy as np def numerical_gradient ( f , x ): h = 1e-4 # 0.0001 grad = np . zeros_like ( x ) it = np . nditer ( x , flags = [ 'multi_index' ], op_flags = [ 'readwrite' ]) while not it . finished : idx = it . multi_index tmp_val = x [ idx ] x [ idx ] = float ( tmp_val ) + h fxh1 = f ( x )# f(x+h) x [ idx ] = tmp_val - h fxh2 = f ( x ) # f(xh) grad [ idx ] = ( fxh1 - fxh2 ) / ( 2 * h ) x [ idx ] = tmp_val #値を元に戻す it . iternext () return grad def func ( x ): if x . ndim == 1 : return np . sum ( x ** 2 ) else : return np . sum ( x ** 2 , axis = 1 ) if name == "main" : x = np . array ([ 1 , 2 ]) grad = numerical_gradient ( func , x ) print ( grad )

The output is [5000 15000] .

Then I added x = x.astype(float)at the beginning of numerical_gradient(): def numerical_gradient ( f , x ): x = x . astype ( float ) h = 1e-4 # 0.0001 grad = np . zeros_like ( x ) it = np . nditer ( x , flags = [ 'multi_index' ], op_flags = [ 'readwrite' ]) while not it . finished : idx = it . multi_index tmp_val = x [ idx ] x [ idx ] = tmp_val + h fxh1 = f ( x ) # f(x+h) x [ idx ] = tmp_val - h fxh2 = f ( x ) # f(xh) grad [ idx ] = ( fxh1 - fxh2 ) / ( 2 * h ) x [ idx ] = tmp_val #値を元に戻す it . iternext () return grad

The output is [2. 4.]

Why type change is unnecessary?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub , or unsubscribe .

WILDCHAP avatar Jun 04 '20 06:06 WILDCHAP