This is a simple code implementing linear regression.
import numpy as np
x_data = np.array([1, 2, 3, 4, 5]).reshape(5, 1)
t_data = np.array([2, 3, 4, 5, 6]).reshape(5, 1)
W = np.random.rand(x_data.shape[1], 1)
b = np.random.rand(1)
print("W ==", W, ", b ==", b)
def CostFunc(input_data, answer):
y = np.dot(input_data, W) + b
e = y - answer
eT = e.T
n = len(answer)
loss = np.dot(e.T, e) / n
return loss
def numerical_partial_derivative(f, x):
delta = 1e-4
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
initialx = x[idx]
x[idx] = initialx + delta
f1 = f(x)
x[idx] = initialx - delta
f2 = f(x)
grad[idx] = (f1 - f2)/(2*delta)
x[idx] = initialx
it.iternext()
return grad
f = lambda x : CostFunc(x_data, t_data)
print("Initial error value = ", CostFunc(x_data, t_data),
"Initial W = ", W, "\n", ", b = ", b )
WNPD = numerical_partial_derivative(f, W)
bNPD = numerical_partial_derivative(f, b)
alpha = 1e-2
for step in range(8001):
for i in range(len(W)):
W[i] = W[i] - alpha*WNPD[i]
for i in range(len(b)):
b[i] = b[i] - alpha*bNPD[i]
WNPD = numerical_partial_derivative(f, W)
bNPD = numerical_partial_derivative(f, b)
if (step % 400 == 0):
print("step ==", step, ", W ==", W, ", b ==", b, ", error ==", CostFunc(x_data, t_data))
def predict(input_data):
y = np.dot(input_data, W) + b
return y
print("predict ==", predict(44))
Look at the f = lambda x : CostFunc(x_data, t_data) part: It says that f is a function of x, and it returns CostFunc(x_data, t_data).
Therefore, I thought it should be constant for any x and it means that the derivative of f with respect to any variable is 0, right?
However, the code was able to calculate the numerical derivative of f with respect to W and b.
It seems weird so I wrote the new code like this.
import numpy as np
x_data = np.array([1, 2, 3, 4, 5]).reshape(5, 1)
t_data = np.array([2, 3, 4, 5, 6]).reshape(5, 1)
delta = 1e-4
W = np.random.rand(x_data.shape[1], 1)
W2 = np.array([[1]])
b = np.random.rand(1)
b2 = np.array([[1]])
def CostFunc(input_data, answer):
y = np.dot(input_data, W2) + b2
e = y - answer
eT = e.T
n = len(answer)
loss = np.dot(e.T, e) / n
return loss
def numerical_partial_derivative(f, x):
delta = 1e-4
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
initialx = x[idx]
x[idx] = initialx + delta
print("x ==", x[idx])
f1 = f(x)
print("f1 ==", f1)
x[idx] = initialx - delta
print("x ==", x[idx])
f2 = f(x)
print("f2 ==", f2)
grad[idx] = (f1 - f2)/(2*delta)
x[idx] = initialx
it.iternext()
return grad
f = lambda x : CostFunc(x_data, t_data)
print("NPD===", numerical_partial_derivative(f, W2))
print("====================================================")
print("f(variable) ==", f(W2-delta))
It prints f1=f(W+delta) and f2=f(W-delta) during calculation of numerical derivative; numerical derivative of f; and the value of f at any point.
As you can see, f is constant outside the numerical derivative, but it does vary inside the numerical derivative.
I think it derives from the using lambda, but I cannot find the detail. Please let me know the secret of lambda.