梯度下降法,顾名思义即通过梯度下降的方法。对于一个函数而言,梯度是一个向量,方向是表示函数值增长最快的方向,而大小则表示该方向的导数。下面展示了用梯度下降法求解一元函数的MATLAB代码:
syms x;
y = @(x)((x-1).^2); % 定义一元函数
dy = diff(y,x); % 一元函数导数
x = 7; % 梯度初始值
l = 0.1; % 梯度下降步长
err = inf; % 定义初始误差
Total_x = []; % 存储每次梯度下降的x值
Total_y = []; % 存储每次梯度下降的y值
i = 0;
while i <= 100
i = i + 1;
y1 = y(x); % 获取当前的函数值
x = x - l * double(subs(dy,x)); % 更新x
y2 = double(subs(y,x)); % 获取进行一次梯度下降后的函数值;
err = abs(y1-y2); % 求误差
Total_x = [Total_x;x]; % 收集梯度变化的x值
Total_y = [Total_y;y2]; % 收集梯度变化的y值
if err <= 10^-10 % 当函数值变化小于阈值时,跳出循环
break;
end
end
disp(Total_x); % 输出Total_x
%% 可视化过程
x = -5:0.1:7; % 设定x范围
figure;
plot(x,y(x)); % 绘制函数曲线图像
hold on; % 在函数曲线图像上,继续绘制图像
scatter(Total_x,Total_y); % 绘制散点图
title("y = (x-1)^2"); % 取标题
仿真结果如下:
下面展示了用梯度下降法求解二元函数的MATLAB代码:
syms x y;
z = @(x,y)((x-1)^2+(y-1)^2); % 定义二元函数
dzx = diff(z,x); % 一元函数导数
dzy = diff(z,y);
x = 3; % x梯度初始值
y = 3; % y梯度初始值
subs(z,x,y)
l = 0.1; % 梯度下降步长
err = inf; % 定义初始误差
Total_x = []; % 存储每次梯度下降的x值
Total_y = []; % 存储每次梯度下降的y值
Total_f = []; % 存储每次梯度下降的z值
i = 0;
while i <= 100
i = i + 1;
c_f = z(x,y); % 获取进行梯度变化前的y值
x = x - l * double(subs(dzx,x)); % 更新x
y = y - l * double(subs(dzy,y));
n_f = z(x,y); % 获取进行梯度变化后的y值
err = abs(c_f-n_f); % 求误差
Total_x = [Total_x;x];
Total_y = [Total_y;y];
Total_f = [Total_f;n_f ];
if err <= 10^-10 % 当误差小于等于指定阈值时,跳出循环
break;
end
end
disp("Total_y");
x = -2:0.1:2; % 设定x范围
y = -2:0.1:2; % 设定y范围
[xx,yy]=meshgrid(x,y);
figure;
zz = (xx-1).^2+(yy-1).^2;
surf(xx,yy,zz); % 绘制函数曲线图像
hold on; % 在函数曲线图像上,继续绘制图像
scatter3(Total_x,Total_y,Total_f); % 绘制散点图
title("y = (x-1)^2+(y-1)^2"); % 取标题
仿真结果如下:
当然,梯度下降方法也可以求解最大值,例如:采用梯度下降法求解最大值的MATLAB代码如下:
syms x y;
z = @(x,y)(-(x-1)^2-(y-1)^2); % 定义二元函数
dzx = diff(z,x); % 一元函数导数
dzy = diff(z,y);
x = -3; % x梯度初始值
y = -3; % y梯度初始值
subs(z,x,y)
l = 0.1; % 梯度下降步长
err = inf; % 定义初始误差
Total_x = []; % 存储每次梯度下降的x值
Total_y = []; % 存储每次梯度下降的y值
Total_f = []; % 存储每次梯度下降的z值
i = 0;
while i <= 100
i = i + 1;
c_f = z(x,y); % 获取进行梯度变化前的y值
x = x + l * double(subs(dzx,x)); % 更新x
y = y + l * double(subs(dzy,y));
n_f = z(x,y); % 获取进行梯度变化后的y值
err = abs(c_f-n_f); % 求误差
Total_x = [Total_x;x];
Total_y = [Total_y;y];
Total_f = [Total_f;n_f ];
if err <= 10^-10 % 当误差小于等于指定阈值时,跳出循环
break;
end
end
disp("Total_y");
x = -2:0.1:2; % 设定x范围
y = -2:0.1:2; % 设定y范围
[xx,yy]=meshgrid(x,y);
figure;
zz = -(xx-1).^2-(yy-1).^2;
surf(xx,yy,zz); % 绘制函数曲线图像
hold on; % 在函数曲线图像上,继续绘制图像
scatter3(Total_x,Total_y,Total_f); % 绘制散点图
title("y = -(x-1)^2-(y-1)^2"); % 取标题
仿真结果如下:
版权归原作者 萝卜青菜~ 所有, 如有侵权,请联系我们删除。