def finite_differences(func, inputs, func_output_shape=(), epsilon=1e-5):
"""
Computes gradients via finite differences.
derivative = (func(x+epsilon) - func(x-epsilon)) / (2*epsilon)
Args:
func: Function to compute gradient of. Inputs and outputs can be
arbitrary dimension.
inputs: Vector value to compute gradient at.
func_output_shape: Shape of the output of func. Default is
empty-tuple, which works for scalar-valued functions.
epsilon: Difference to use for computing gradient.
Returns:
Gradient vector of each dimension of func with respect to each
dimension of input.
"""
gradient = np.zeros(inputs.shape+func_output_shape)
for idx, _ in np.ndenumerate(inputs):
test_input = np.copy(inputs)
test_input[idx] += epsilon
obj_d1 = func(test_input)
assert obj_d1.shape == func_output_shape
test_input = np.copy(inputs)
test_input[idx] -= epsilon
obj_d2 = func(test_input)
assert obj_d2.shape == func_output_shape
diff = (obj_d1 - obj_d2) / (2 * epsilon)
gradient[idx] += diff
return gradient
评论列表
文章目录