楼主: bigxboss
779 0

[其他] 20251210 线性最小二乘法迭代拟合(梯度下降) [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-10-9
最后登录
2018-10-9

楼主
bigxboss 发表于 2025-12-11 12:58:04 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

线性最小二乘拟合通过梯度下降法实现参数优化,目标是寻找最优的斜率与截距,使得拟合直线 y = ax + b 尽可能贴近所有数据点 (xi, yi)。

1. 损失函数定义(均方误差)

为评估拟合效果,采用均方误差作为损失函数:

L(a, b) = (1 / 2n) ∑i=1n (a xi + b yi)

该值越小,表示模型拟合程度越高。其中引入因子 1/2 是为了在后续求导过程中简化表达式,不影响优化方向。

2. 梯度计算

梯度反映损失函数对各参数的变化率,用于指导参数更新方向:

  • 对斜率 a 的偏导数:
    L/a = (1/n) ∑i=1n (a xi + b yi) xi
  • 对截距 b 的偏导数:
    L/b = (1/n) ∑i=1n (a xi + b yi)

梯度指向误差上升最快的方向,因此参数应沿其反方向调整以降低损失。

3. 参数迭代更新(梯度下降)

每一轮迭代中,按如下规则更新参数:

aa η (L/a)
bb η (L/b)

其中 η > 0 表示学习率(例如 0.02),控制每次更新的步长大小,直接影响收敛速度与稳定性。

4. 迭代直至收敛

重复执行以下流程直到达到最大迭代次数或损失趋于稳定:

  • 计算当前预测值:i = a xi + b
  • 计算梯度
  • 更新斜率 a 和截距 b

随着迭代进行,损失函数 L(a, b) 逐步减小,拟合直线逐渐逼近最优解。

关键要点总结

  • 梯度下降是一种迭代优化方法,不依赖于解析解,适用于更广泛的问题场景;
  • 除以样本数 n 可得到平均误差,使结果不受数据量影响;
  • 即使数据严格位于一条直线上,仍需多次迭代才能接近真实参数值;
  • 学习率 η 需谨慎选择:过大可能导致震荡甚至发散,过小则收敛缓慢。

Matlab 实现代码

%% 梯度下降动画:最小二乘直线拟合(修复起点显示问题)
clear; close all; clc;
% 生成带噪声的线性数据
rng(0); % 可复现
n = 30;
x = linspace(0, 10, n)';
y_true = -2.5 * x + 1.0;          % 真实直线
y = y_true + randn(n,1) * 1;      % 添加高斯噪声

% 初始化参数
a = 1;      % 初始斜率
b = -20;    % 初始截距
lr = 0.02;  % 学习率(可调)
max_iter = 500;

% 存储历史用于绘制轨迹
a_hist = zeros(max_iter+1, 1);
b_hist = zeros(max_iter+1, 1);
loss_hist = zeros(max_iter+1, 1);
a_hist(1) = a;
b_hist(1) = b;
loss_hist(1) = sum((a*x + b - y).^2) / (2*n);

% 创建图形窗口
figure('Position', [100, 100, 1000, 400]);

% === 左图:数据与拟合直线 ===
subplot(1,2,1); hold on; box on;
scatter(x, y, 'filled', 'MarkerFaceColor', [0.2 0.6 0.8]);
title('梯度下降拟合过程', 'FontSize', 12);
xlabel('x'); ylabel('y');
xlim([min(x)-1, max(x)+1]); ylim([min(y)-2, max(y)+2]);
h_line = plot(x, a*x + b, 'r-', 'LineWidth', 2);
h_text = text(0.05, 0.95, '', 'Units','normalized', 'FontSize',12,...
    'VerticalAlignment','top', 'BackgroundColor',[1 1 1 0.7]);
% === 右图:参数空间轨迹(初始化坐标轴)===
subplot(1,2,2); hold on; box on;
title('参数更新轨迹 (a vs b)', 'FontSize', 12);
xlabel('斜率 a'); ylabel('截距 b');

% 在右图中标注初始点(使用红色大圆点突出显示起点)
subplot(1,2,2);
plot(a_hist(1), b_hist(1), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
drawnow;
pause(1.0);  % 暂停1秒,便于观察初始状态

% === 更新左图:拟合直线与信息文本 ===
set(h_line, 'YData', a*x + b);
set(h_text, 'String', sprintf('Iter: %d\na=%.3f, b=%.3f\nLoss=%.3f', ...
    0, a, b, loss_hist(1)));

% === 开始迭代优化过程 ===
for k = 1:max_iter
    % 前向传播:计算当前预测值
    y_pred = a * x + b;

    % 计算损失函数对参数的梯度
    da = sum((y_pred - y) .* x) / n;   % ?L/?a
    db = sum(y_pred - y) / n;          % ?L/?b

    % 使用梯度下降法更新参数
    a = a - lr * da;
    b = b - lr * db;

    % 记录每一步的参数与损失值
    a_hist(k+1) = a;
    b_hist(k+1) = b;
    loss_hist(k+1) = sum((a*x + b - y).^2) / (2*n);

    % 实时更新左侧图像中的拟合直线和文字说明
    set(h_line, 'YData', a*x + b);
    set(h_text, 'String', sprintf('Iter: %d\na=%.3f, b=%.3f\nLoss=%.3f', ...
        k, a, b, loss_hist(k+1)));

    % 更新右侧参数轨迹图
    subplot(1,2,2);
    cla;  % 清除当前坐标轴内容,避免图形叠加变粗
    hold on; box on;
    title('参数更新轨迹 (a vs b)', 'FontSize', 12);
    xlabel('斜率 a'); ylabel('截距 b');

    % 绘制从开始到当前迭代的完整参数路径
    plot(a_hist(1:k+1), b_hist(1:k+1), 'go-', ...
        'MarkerFaceColor', 'g', 'MarkerSize', 5);

    % 重新绘制起点高亮标记(保持红色醒目)
    plot(a_hist(1), b_hist(1), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');

    drawnow;
    pause(0.05); % 控制动画播放速度
end

% 输出最终优化结果并与真实值对比
fprintf('最终结果: a = %.4f, b = %.4f (真实值: a=-2.5, b=1.0)\n', a, b);

 
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:最小二乘法 最小二乘 梯度下降 Background Alignment

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2026-1-14 08:09