oreilly-japan / deep-learning-from-scratch

『ゼロから作る Deep Learning』(O'Reilly Japan, 2016)
MIT License
3.99k stars 3.34k forks source link

Is the numerical_gradient function wrong? #51

Open RainaRLN opened 4 years ago

RainaRLN commented 4 years ago

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?

WILDCHAP commented 4 years ago

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"<notifications@github.com>; 发送时间:  2020年6月3日(星期三)中午1:49 收件人:  "oreilly-japan/deep-learning-from-scratch"<deep-learning-from-scratch@noreply.github.com>; 抄送:  "Subscribed"<subscribed@noreply.github.com>; 主题:  [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 .