You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我基于MATLAB实现的简易线性回归梯度下降算法不收敛?

梯度下降不收敛的原因及修复方案

你的代码核心逻辑没问题,但几个关键细节导致了收敛失败:

1. 未对特征做归一化/标准化

梯度下降对特征的数值尺度极度敏感。你用到的x和y(事故数据集的第14、4列)数值范围可能差异极大,比如x是千级、y是百级,这会导致w和b的梯度更新幅度失衡,要么震荡要么收敛极慢。

修复方案:在使用数据前添加标准化步骤,比如Z-score标准化:

x = (x - mean(x)) / std(x);
y = (y - mean(y)) / std(y);

或者最小-最大归一化:

x = (x - min(x)) / (max(x) - min(x));
y = (y - min(y)) / (max(y) - min(y));

2. 迭代次数过少

仅设置100次迭代远远不够,尤其是当学习率alpha较小时,梯度下降需要大量迭代才能逼近最优解。

修复方案:增加迭代次数,同时记录每次迭代的代价函数值,直观观察收敛趋势:

max_iter = 10000;
J_history = zeros(max_iter, 1); % 存储每次迭代的均方误差
for i = 1:max_iter
    y_est = w*x + b;
    J_history(i) = mean((y-y_est).^2);
    temp_w = w + alpha*(mean(x.*(y - w*x - b)));
    temp_b = b + alpha*(mean(y - w*x - b));
    w = temp_w;
    b = temp_b;
end
% 绘制代价曲线观察收敛情况
plot(J_history);
xlabel('迭代次数');
ylabel('均方误差J');

3. 学习率alpha的选择逻辑错误

你尝试的不同alpha无效,本质是因为未做归一化。归一化后可以重新调整学习率:

  • 若代价函数J震荡甚至上升,说明alpha过大,需缩小(比如从0.1调到0.01)
  • 若J下降极慢,说明alpha过小,需增大(比如从0.000001调到0.01)

完整修复代码示例

%% Linear regression
close all; clear; clc;

dataset = load('accidents');
data = dataset.hwydata;
x = data(:,14);
y = data(:,4);

% 数据标准化
x = (x - mean(x)) / std(x);
y = (y - mean(y)) / std(y);

%% Gradient descent
w = 0;
b = 0;
alpha = 0.01; % 归一化后可尝试该学习率
max_iter = 10000;
J_history = zeros(max_iter, 1);

for i = 1:max_iter
    y_est = w*x + b;
    J_history(i) = mean((y - y_est).^2);
    % 参数更新
    temp_w = w + alpha * mean(x .* (y - y_est));
    temp_b = b + alpha * mean(y - y_est);
    w = temp_w;
    b = temp_b;
end

% 可视化代价变化
figure;
plot(J_history);
xlabel('迭代次数');
ylabel('均方误差 J');
title('梯度下降代价函数变化');

% 可视化拟合结果
figure;
scatter(x, y, 10, 'b', 'filled');
hold on;
plot(x, w*x + b, 'r', 'LineWidth', 2);
xlabel('标准化后的x');
ylabel('标准化后的y');
title('线性回归拟合结果');
hold off;

内容的提问来源于stack exchange,提问作者wanderer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:05:01