| 
													Последний раз редактировалось B@R5uk 17.04.2025, 01:55, всего редактировалось 1 раз.
												
 
 Но тут вопрос - а как выбрать этот множитель? Если нет никакой информации насчёт функции, то таки надо делать хотя бы неполную оптимизацию вдоль выбранного направления. Ну да, стратегии наискорейшего спуска и минимального градиента выбирают множитель за нас. Я тут попытался проанализировать, что в них происходит. Опять же на самой простой задаче: Квадратичная функция с минимумом в нуле:        Если потребовать минимум функции вдоль направления спуска (стратегия наискорейшего спуска, Steepest Descent ) и проварьировать по параметру, то придём к формулам:      Если же потребовать минимум модуля (или, что более удобно квадрата модуля) градиента (стратегия минимального градиента, Minimum Gradient ), то получится так:      Очевидно, оператор шага S  в обоих стратегиях не является линейным (является дробно-рациональным?):    Пока не очень представляю, что с этим делать аналитически, поэтому попробовал промоделировать. Составил программку для двумерного случая с диагональной матрицей и задал начальное множество точек на единичной окружности и посмотрел, куда они отображаются обоими стратегиями (а так же, для сравнения, методом с оптимальным фиксированным шагом, выбранным исходя из априорного знания о квадратичной формы). Получилась следующая картинка: Сразу говорю, на картинке нарисована неправда: проекции окружности после первой итерации перевёрнуты по вертикали. Я это сделал, чтобы продемонстрировать, что существует выделенное направление, векторы вдоль которого при применении оператора шага S , во-первых укорачиваются медленно, а во-вторых не меняют своего направления (с учётом смены знака по координате y ). Траектории, для них — это (жёлтая) линия, вторая против часовой стрелки от горизонтальной белой на левом графике и первая, розовая — на втором. Левый график соответствует стратегии максимального спуска, правый — минимального градиента. Синими окружностями помечены точки, в которые отображается исходная единичная окружность стратегией с фиксированным шагом. Получаются окружности, а не эллипсы, потому что шаг выбран оптимальным, а это даёт одинаковые собственные числа для оператора S , соответствующие минимальному и максимальному собственным числам матрицы A квадратичной формы. Поскольку задача двумерная, других чисел быть не может. Поскольку я перевернул результат первой итерации по вертикали, траектории, отмеченные разноцветными тонкими линиями, перестали быть ортогональными линиям уровня целевой функции, если первую итерацию перевернуть назад, то будет всё нормально. Видно, что методы наискорейшего спуска и минимального градиента в самом худшем случае чуть-чуть хуже метода с фиксированным градиентом с оптимально подобранным шагом. По крайней мере в двумерии. Так же, если очень присмотреться, то можно заметить, что векторы в процессе итераций прижимаются к наихудшему направлению спуска. Ну и очевидно, что собственные вектора оператора A  схлопываются в ноль за одну итерацию. У меня есть подозрение, что в трёхмерии и пространствах большей размерности может получиться что-то более интересное. Надо будет попробоать. Программа: 
%   File: study_GD_2.m%   dxdy.ru/topic160189.html
 %   B@R5uk, 2025, April
 
 clc
 clearvars
 format compact
 %format long
 format short
 
 num_iter = 3;
 
 %   Diagonal bilinear form
 A = diag ([1 3]);
 
 func_objective = @(x, A) 0.5 * x' * A * x;
 func_gradient  = @(x, A)            A * x;
 
 %   Starting circle and space for data
 ppp = 2 * pi * (0 : 0.001 : 1);
 num_points = numel (ppp);
 xxx = zeros (num_iter, num_points);
 yyy = zeros (num_iter, num_points);
 xxx (1, :) = cos (ppp);
 yyy (1, :) = sin (ppp);
 xxx2 = xxx;
 yyy2 = yyy;
 xxx3 = xxx;
 yyy3 = yyy;
 
 %   Gradient descent: steepest descent strategy
 for k = 2 : num_iter
 for l = 1 : num_points
 x = [xxx(k - 1, l); yyy(k - 1, l)];
 g = func_gradient (x, A);
 xx = x - g * g' * g / (g' * A * g);
 xxx (k, l) = xx (1);
 yyy (k, l) = xx (2);
 end
 end
 
 %   Gradient descent: minimum gradient strategy
 for k = 2 : num_iter
 for l = 1 : num_points
 x = [xxx2(k - 1, l); yyy2(k - 1, l)];
 g = func_gradient (x, A);
 ag = A * g;
 xx = x - g * g' * ag / (ag' * ag);
 xxx2 (k, l) = xx (1);
 yyy2 (k, l) = xx (2);
 end
 end
 
 %   Gradient descent: fixed step strategy (best step selected)
 step = 2 / trace (A);
 for k = 2 : num_iter
 for l = 1 : num_points
 x = [xxx3(k - 1, l); yyy3(k - 1, l)];
 g = func_gradient (x, A);
 xx = x - step * g;
 xxx3 (k, l) = xx (1);
 yyy3 (k, l) = xx (2);
 end
 end
 
 %   Objective function levels values
 xx = -1 : 0.01 : 1;
 zz = zeros (size (xx, 2));
 for k = 1 : numel (xx)
 for l = 1 : numel (xx)
 zz (l, k) = func_objective ([xx(k); xx(l)], A);
 end
 end
 
 cl = 'wmycg';
 
 %   SD graph
 subplot (121)
 contourf (xx, xx, zz, -1 : 0.1 : 2)
 hold on
 for k = 1 : num_iter
 plot (xxx3 (k, :), yyy3 (k, :), 'LineWidth', 3)
 end
 for k = 1 : num_iter
 %   Odd circle image is flipped vertically
 plot (xxx (k, :), (-1) ^ (k - 1) * yyy (k, :), 'r', 'LineWidth', 3)
 end
 for k = 0 : 9
 n = 1 + k * 26;
 for l = 1 : 2
 %   Odd circle image is flipped vertically
 plot ([xxx(l, n) xxx(l + 1, n)], (-1) ^ l * [-yyy(l, n) yyy(l + 1, n)], cl (mod (k, numel (cl)) + 1))
 end
 end
 n = 251;
 l = 1;
 %   Vertical eigenvector trajectory
 plot ([xxx(l, n) xxx(l + 1, n)], (-1) ^ l * [-yyy(l, n) yyy(l + 1, n)], 'w')
 hold off
 axis equal
 xlim ([-1 1])
 ylim ([-1 1])
 
 %   MG graph
 subplot (122)
 contourf (xx, xx, zz, -1 : 0.1 : 2)
 hold on
 for k = 1 : num_iter
 plot (xxx3 (k, :), yyy3 (k, :), 'LineWidth', 3)
 end
 for k = 1 : num_iter
 %   Odd circle image is flipped vertically
 plot (xxx2 (k, :), (-1) ^ (k - 1) * yyy2 (k, :), 'r', 'LineWidth', 3)
 end
 for k = 0 : 7
 n = 1 + k * 32;
 for l = 1 : 2
 %   Odd circle image is flipped vertically
 plot ([xxx2(l, n) xxx2(l + 1, n)], (-1) ^ l * [-yyy2(l, n) yyy2(l + 1, n)], cl (mod (k, numel (cl)) + 1))
 end
 end
 n = 251;
 l = 1;
 %   Vertical eigenvector trajectory
 plot ([xxx2(l, n) xxx2(l + 1, n)], (-1) ^ l * [-yyy2(l, n) yyy2(l + 1, n)], 'w')
 hold off
 axis equal
 xlim ([-1 1])
 ylim ([-1 1])
 
 %   Possible colour maps:
 %   hsv gray hot cool bone copper pink flag
 colormap (pink)
 
 В программе несколькими постами ранее, я облажался и вместо zz (l, k) = func_objective ...  написал zz (k, l) = func_objective ...  Из-за этого на картинке в том же посте (и при работе самой программы) линии уровня целевой функции отображены неправильно: они отражены вдоль диагонали первого квадранта. Другими словами, иксы и игреки перепутаны местами. Надеюсь, в этой программе нет опечаток.
 |