Итак, я написал следующий код MATLAB в качестве упражнения для градиентный спуск. Я, очевидно, выбрал функцию, которая имеет минимум в (0,0), но алгоритм бросает меня на (-3,3).градиентный спуск сценарий MATLAB
я не узнал, что переключение между xGrad
и yGrad
на линии: [xGrad,yGrad] = gradient(f);
дает правильную сходимость, несмотря на то, что xGrad
, yGrad
являются приблизительно 2*X
, 2*Y
, как ожидалось. Я предполагаю, что я перевернутое что-то здесь, но я пытался выяснить, что это какое-то время, и я не понимаю, так что я надеялся, что кто-то может заметить свою ошибку ...
dx=.01;
dy=.01;
x=-3:dx:3;
y=-3:dy:3;
[X,Y]=meshgrid(x,y);
f=X.^2+Y.^2;
lr = .1; %learning rate
eps = 1e-10; %epsilon threshold
tooMuch = 1e5; %limit iterations
p = [.1 1]; %starting point
[~, idx] = min(abs(x-p(1))); %index of closest value
[~, idy] = min(abs(y-p(2))); %index of closest value
p = [x(idx) y(idy)]; %closest point to start
[xGrad,yGrad] = gradient(f); %partial derivatives of f
xGrad = xGrad/dx; %scale correction
yGrad = yGrad/dy; %scale correction
for i=1:tooMuch %prevents too many iterations
fGrad = [ xGrad(idx,idy) , yGrad(idx,idy) ]; %gradient's definition
pTMP = p(end,:) - lr*fGrad; %gradient descent's core
[~, idx] = min(abs(x-pTMP(1))); %index of closest value
[~, idy] = min(abs(y-pTMP(2))); %index of closest value
p = [p;x(idx) y(idy)]; %add the new point
if sqrt(sum((p(end,:)-p(end-1,:)).^2)) < eps %check conversion
break
end
end
Спасибо любому, кто помогает
изменить: исправлены опечатки и сделали код более четким. Он по-прежнему делает то же самое и имеет ту же проблему
Тангенциальный комментарий: Это необычно, чтобы прекомпретировать градиент на сетке, подобной этому. Я думаю, вы не должны работать на сетке. Это значительно упростит код, а также будет более правильным и даст лучшие результаты. – littleO
Я показываю это в конце как диаграмма стрелки (используя «колчан»), но если вы можете показать мне способ более градиента вычислить, я буду счастлив (возможно, по ссылке на некоторую документацию) –
Я предполагаю, что это в основном для учебных целей. Для такой проблемы нет необходимости выстраивать все. Вы можете отслеживать x_val и y_val без индексов, сеток и т. Д. ... и вычислять градиент, беря частные производные самостоятельно: 'fGrad = [2 * x_val, 2 * y_val]'.Для многих функций вы можете автоматически вычислять градиент автоматически с помощью автоматического дифференцирования (для этого есть несколько пакетов). –