10.3. Метод Ньютона#
Приблизим локально значение функции \(f\) в точке \(\mathbf{x}_k + \mathbf{d}\) квадратичной функцией \(m_k(\mathbf{d})\), используя разложение Тейлора
Предположим, что гессиан \(\nabla^2 f(\mathbf{x}_k)\) положительно определён, тогда в качестве направления убывания возьмём вектор \(\mathbf{p}\), который минимизирует модельную функцию \(m_k(\mathbf{d})\). Для этого найдём ноль градиента функции \(m_k\)
откуда
Данный вектор будем использовать в качестве направления убывания на \(k\)-ом шаге оптимизации. Направление вида (10.7) называют Ньютоновским. В сочетании с линейным поиском получаем метод Ньютона для задачи оптимизации. Однако, прежде сделаем модификацию.
10.3.1. Модификация метода#
Отметим предположения, при которых (10.7) справедливо. Во-первых, размер направления \(\|\mathbf{d}\|\) не должен быть слишком большим, во-вторых, мы предполагали положительную определённость гессиана.
На практике размер шага \(\|\mathbf{d}\|\) подбирается линейным поиском \(\mathbf{x}_k + \alpha \mathbf{d}\), начиная с \(\alpha = 1\). Вдали от минимума подходящие шаги могу оказаться \(\alpha < 1\), однако, вблизи минимума полный шаг чаще подходит.
Направление \(\mathbf{d}\) (10.7) может быть не убывающим вдали от минимума, поскольку гессиан может быть не положительно определён. Чтобы гарантировать положительную определённость, используют модифицированное разложение Холецкого. Мы уже упоминали о Разложении Холецкого. Его же модифицированная версия принимает на вход произвольную матрицу \(\mathbf{A}\) и, пытаясь выполнить стандартное разложение, корректирует элементы \(\mathbf{A}\) так, чтобы итоговая матрица \(\mathbf{A}^{(m)}\) была положительно определена и не слишком сильно отличалась от исходной:
Наша модификация алгоритма Ньютона заключается в использовании на \(k\)-ом шаге оптимизации не исходного гессиана \(\mathbf{H}\), а его приближения \(\mathbf{H}^{(m)}\), полученного из модифицированного разложения Холецкого. Вдали от минимума гессиан и приближение могут отличаться, однако вблизи минимума разложение практически не внесёт поправок.
В принципе, мы могли бы проверять на итерации, является ли гессиан положительно определённым и, если нет, то использовать \(\mathbf{H}^{(m)}\). Однако, процедура проверки строится на попытке выполнить стандартное разложение Холецкого, поэтому большой выгоды от этого нет.
10.3.2. Реализация#
Модифицированное разложение Холецкого приведено в Приложении.
Ниже дан шаблон метода Ньютона, который нужно будет завершить в домашнем задании.
Структура данных для результата алгоритма
struct NewtonResult{T<:Real}
converged::Bool # метод сошёлся
argument::Vector{T} # найденный минимум
iters::Int # число прошедших итераций
end
Метод Ньютона (шаблон)
"""
newton(f, ∇f, hess, x0[; gtol=1e-5, maxiter=200])
Поиск локального безусловного минимума функции `f`, с градиентом ∇f и гессианом `hess`. Поиск начинается с `x0` и заканчивается, когда норма градиента не превышает `gtol` или максимальное число итераций `maxiter` превышено.
- `f::Function`: по вектору x возвращает значение функции, `f(x)`: `Vector` → `Real`;
- `∇f::Function`: по вектору x возвращает градиент `f`, `∇f(x)`: `Vector` → `Vector`;
- `hess::Function`: по вектору x возвращает гессиан `f`, `hess(x)`: `Vector` → `Matrix`.
Возвращает `NewtonResult` - результат оптимизации.
"""
function newtontemplate(
f::Function,
∇f::Function,
hess::Function,
x0::AbstractVector;
gtol::Real=1e-5,
maxiter::Integer=200,
)
x = float.(x0) # копирование и приведение к флоат-числам
# проверяем сходимость по норме-2 градиента
g = ∇f(x)
# ... && return NewtonResult(true, x, 0)
for i in 1:maxiter
# выбор направления d из модифицированного Гессиана Hᵐ
# см. mcholesky!, LinearAlgebra.ldiv!
# ...
# d = ...
# выбор шага вдоль d
# α = ...
# ... && return NewtonResult(false, x, i) # α не найдено
# совершаем шаг
# x = ...
# проверяем сходимость
g = ∇f(x)
# ... && return NewtonResult(true, x, i)
end
return NewtonResult(false, x, maxiter)
end