基于MATLAB的梯度下降法实现
基于MATLAB的梯度下降法实现,包含精确线搜索和回溯线搜索两种策略,并针对二次函数优化进行优化:
一、核心代码实现
1. 精确线搜索(黄金分割法)
function t = exact_line_search(f, grad_f, x, d, a=0, b=1, tol=1e-5)
"""黄金分割法实现精确线搜索"""
rho = (3 - sqrt(5))/2; % 黄金分割比例
t1 = a + rho*(b - a);
t2 = b - rho*(b - a);
f1 = f(x - t1*grad_f(x));
f2 = f(x - t2*grad_f(x));
while abs(b - a) > tol
if f1 < f2
b = t2;
t2 = t1;
f2 = f1;
t1 = a + rho*(b - a);
f1 = f(x - t1*grad_f(x));
else
a = t1;
t1 = t2;
f1 = f2;
t2 = b - rho*(b - a);
f2 = f(x - t2*grad_f(x));
end
end
t = (a + b)/2;
end
2. 回溯线搜索(Armijo条件)
function t = backtracking_line_search(f, grad_f, x, d, alpha=0.3, beta=0.8, t_init=1.0)
"""Armijo条件回溯线搜索"""
t = t_init;
while f(x - t*grad_f(x)) > f(x) - alpha * t * norm(grad_f(x))^2
t = beta * t;
if t < 1e-10
break;
end
end
end
3. 梯度下降主函数
function [x_opt, fval, iter] = gradient_descent(f, grad_f, x0, method, max_iter=1000, tol=1e-6)
x = x0;
iter = 0;
fval = f(x);
while iter < max_iter
g = grad_f(x);
if norm(g) < tol
break;
end
% 选择线搜索方法
if strcmp(method, 'exact')
t = exact_line_search(f, grad_f, x, g);
elseif strcmp(method, 'backtrack')
t = backtracking_line_search(f, grad_f, x, g);
else
error('Unknown method');
end
x = x - t * g;
fval = f(x);
iter = iter + 1;
end
end
二、二次函数优化示例
1. 目标函数定义
% 二次函数 f(x) = 0.5*x'*G*x + b'*x
G = [4 1; 1 2]; % 正定矩阵
b = [1; -1];
f = @(x) 0.5*x'*G*x + b'*x;
grad_f = @(x) G*x + b;
2. 精确线搜索测试
x0 = [10; 10]; % 初始点
[x_opt, fval, iter] = gradient_descent(f, grad_f, x0, 'exact');
disp('精确线搜索结果:');
disp(['最优解: ', num2str(x_opt')]);
disp(['迭代次数: ', num2str(iter)]);
3. 回溯线搜索测试
[x_opt, fval, iter] = gradient_descent(f, grad_f, x0, 'backtrack');
disp('回溯线搜索结果:');
disp(['最优解: ', num2str(x_opt')]);
disp(['迭代次数: ', num2str(iter)]);
三、高维问题扩展
1. 随机梯度下降(SGD)
function [x_opt, fval, iter] = sgd(f, grad_f, x0, batch_size=32, ...)
n = length(x0);
for iter = 1:max_iter
idx = randperm(n, batch_size);
g = grad_f(x0(idx));
x0 = x0 - t*g;
end
end
2. 分布式计算实现
% 使用parfor进行并行梯度计算
parfor i = 1:num_workers
grad_part = compute_gradient_partial(data(i));
grad_total = grad_total + grad_part;
end
四、可视化工具
1. 收敛曲线绘制
figure;
semilogy(1:iter, fval_hist, '-o');
xlabel('迭代次数');
ylabel('目标函数值');
title('梯度下降收敛曲线');
2. 梯度方向可视化
quiver(x(1), x(2), -grad_f(x)(1), -grad_f(x)(2));
hold on;
plot(x_opt(1), x_opt(2), 'rx');
参考代码 梯度下降法优化函数 www.youwenfan.com/contentcni/64952.html
五、工程应用建议
-
初始步长选择
t_init = 2 / (norm(G)*2 + norm(b)); % 基于问题规模调整 -
终止条件优化
if norm(g) < 1e-6 && abs(fval - f_prev) < 1e-9 break; end -
GPU加速
grad_f = @(x) gpuArray(G)*gpuArray(x) + gpuArray(b);
六、完整测试案例
%% 二次函数优化测试
G = [4 1; 1 2];
b = [1; -1];
f = @(x) 0.5*x'*G*x + b'*x;
grad_f = @(x) G*x + b;
x0 = [10; 10];
methods = {'exact', 'backtrack'};
results = struct();
for m = 1:numel(methods)
tic;
[x_opt, fval, iter] = gradient_descent(f, grad_f, x0, methods{m});
results(m).time = toc;
results(m).x = x_opt;
results(m).fval = fval;
end
% 结果对比
disp('性能对比:');
for m = 1:numel(methods)
fprintf('%s方法: 迭代次数=%d, 耗时=%.4f秒, 最终值=%.6f\n',...
methods{m}, results(m).iter, results(m).time, results(m).fval);
end
浙公网安备 33010602011771号