Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def numerical_derivative_2d(func, epsilon):
- """
- Функция для приближённого вычисления градиента функции двух переменных.
- :param func: np.array[2] -> float — произвольная дифференцируемая функция
- :param epsilon: float — максимальная величина приращения по осям
- :return: другая функция, которая приближённо вычисляет градиент в точке
- """
- def grad_func(x):
- """
- :param x: np.array[2] — точка, в которой нужно вычислить градиент
- :return: np.array[2] — приближённое значение градиента в этой точке
- """
- return np.array([(func([x[0] + epsilon, x[1]]) - func(x)) / epsilon, (func([x[0], x[1] + epsilon]) - func(x)) / epsilon])
- return grad_func
- def grad_descent_2d(func, low, high, start=None, callback=None):
- """
- Реализация градиентного спуска для функций двух переменных
- Обратите внимание, что здесь градиент функции не дан.
- Его нужно вычислять приближённо.
- :param func: np.ndarray -> float — функция
- :param low: левая граница интервала по каждой из осей
- :param high: правая граница интервала по каждой из осей
- """
- def find_local_min(df, low_local, high_local, iters=5000, lr=0.01):
- x = np.array(np.random.uniform(low, high, 2), dtype=float)
- grad = df(x)
- while iters > 0:
- # if low_local <= x[0] - eps * grad[0] <= high_local and low_local <= x[1] - eps * grad[1] <= high_local:
- x[0] = x[0] - eps * grad[0]
- x[1] = x[1] - eps * grad[1]
- # print(x)
- grad = df(x)
- iters -= 1
- callback(x, func(x))
- return x
- eps = 1e-2
- iters = 500
- df = numerical_derivative_2d(func, eps)
- estimates = np.empty((0, 2), dtype=float)
- segment = (high - low) / 60
- while low < high:
- estimates = np.vstack([estimates, find_local_min(df, low, low + segment, lr=eps)])
- low += segment
- y = np.min(func(estimates))
- print(estimates[:])
- best_estimate = estimates[np.where(func(estimates) == y)[0]][0]
- callback(best_estimate, func(best_estimate))
- return best_estimate
Add Comment
Please, Sign In to add comment