杭州哪家做外贸网站,网站搭建app,个人如何注册电商平台,wordpress能做pc移动端一体一、前言 相关配置#xff1a;Matlab 2020a#xff08;版本的影响应该不大#xff0c;.m代码基本都能运行#xff0c;个人感觉就是Simulink对版本的要求高一些#xff09;
二、任务描述 基于近两节课的理论推导#xff0c;用代码实现线性回归#xff0c;并对预测结果进…一、前言 相关配置Matlab 2020a版本的影响应该不大.m代码基本都能运行个人感觉就是Simulink对版本的要求高一些
二、任务描述 基于近两节课的理论推导用代码实现线性回归并对预测结果进行分析。同时体会学习率、迭代次数对系统的影响收敛速度、代码运行速度等。
三、代码实现 我们将任务假设为房价的预测研究单变量的线性回归即输入特征只有一个房屋面积。使用一次函数来生成相关样本这里的一次函数为笔者随意设置并不与现实的情况相符合。
% ----------------------原始数据集---------------------- %
x linspace(0, 1000, 200); % 生成横坐标房屋面积数据
y 1.5 * x 100; % 生成房价
data [x; y]; % 组合成二维数据 这样生成的样本以50个样本为例连起来就是一条直线。然而现实情况是样本数据或多或少会存在“噪声”房价与房屋面积也不会呈现完美的一次函数关系。所以我们需要对样本增加“噪声”。代码示例如下
noise_level 30; % 定义噪声参数noise noise_level * randn(size(data)); % 生成与数据相同大小的高斯噪声
noisy_data data noise; % 将噪声添加到数据中noisy_x noisy_data(1,:); % 添加噪声后的特征房屋面积
noisy_y noisy_data(2,:); % 添加噪声后的结果房价 其中randn 函数用于生成符合标准正态分布均值为 0标准差为 1的随机数。增加“噪声”后的样本示例如下图所示。我们可以发现样本点出现了一定的变化呈现一种“随机”的状态。 在进行梯度下降迭代之前我们还需要将样本数据进行归一化。对自变量和因变量进行归一化或标准化使其值更为均衡有利于帮助模型更快收敛。笔者在之前的测试中发现若不进行归一化输出的截距θ0会为0或者其他奇奇怪怪的问题。 【特别注意】最终我们预测结果的那条线的相关参数需要进行反归一化才行
std_x (noisy_x - mean(noisy_x)) / std(noisy_x); % 标准化x
std_y (noisy_y - mean(noisy_y)) / std(noisy_y); % 标准化y 接下来就是进行梯度下降的迭代了。代码主要分为以下三步 ①、依据输入特征获得预测值预测的房价 ②、计算梯度获得当前的θ0和θ1实际情况是需要对θ0和θ1求偏导代码中直接给出了计算结果详见《机器学习-周志华》P54的式3.5和式3.6 ③、更新参数获取新的θ0和tθ1这里需要注意学习率α不宜设置的过大。过大的α可能会导致损失函数J无法收敛 ④、计算损失值 主循环代码如下所示
% ------------------------------主循环代码-------------------------------
% GPT的例程是固定一个迭代次数例如1000次次数到了就退出循环输出结果
% 笔者尝试固定一个损失值当损失小于固定值时才退出循环但运行效果不佳
% 故放弃了这种方案
% ----------------------------------------------------------------------
for i 1 : iteration_numy_pred theta1 * std_x theta0; % 预测值% 计算梯度d_theta1 (1/m) * (theta1 * sum(std_x.^2) - sum((std_y - theta0) .* std_x));d_theta0 theta0 - (1/m) * sum(std_y - theta1 * std_x);% 更新参数theta1 theta1 - alpha * d_theta1;theta0 theta0 - alpha * d_theta0;loss (1/m) * sum((y_pred - std_y).^2); % 计算损失J_history(i) loss;
end主循环结束运行的方式笔者认为可以有两种方法。第一种是如上图所示的通过设定迭代次数当迭代次数到了后退出循环。第二种是人为设定一个损失值当计算的损失值小于设定的损失值时退出循环。在测试中第二种方法效果并不好有时代码会长时间运行无法跳出循环遂放弃。 到这一步我们就完成“模型的训练”啦在画图之前别忘了我们还需要进行反归一化。
% 反归一化后才是真正的theta0和theta1
theta1 theta1 * (std(noisy_y) / std(noisy_x)); % 恢复原始斜率
theta0 mean(noisy_y) - theta1 * mean(noisy_x); % 恢复原始截距
四、输出结果与分析 下图为迭代500次的预测结果其中绿色的回归线与数据点基本吻合说明模型预测效果较好。 此外迭代500次的损失函数的收敛图如下图所示我们可以发现损失值随着迭代次数的增加逐渐减小呈现一种收敛的状态。 下图是迭代1000次的 损失函数的收敛图我们可以发现迭代次数超过500后损失值几乎不再发生变化本身“损失”就已经很小了所以无脑的增加迭代次数并不一定是好的适可而止在大模型训练中也能节约计算时间。 以下Matlab“命令窗口”打印的数据结果我们可以发现最终输出的线性回归方程与前文设置的一次方程相近似。
迭代次数500次
loss损失0.011024
最终线性回归方程y 1.49x 104.89
theta1 1.49, theta0 104.89通过绘制的图像我们也可以发现最终的损失函数J会有一个全局最小的点。(这只是一个简单的测试样例 五、程序代码
clc;
clear;
close all;% ----------------------原始数据集---------------------- %
x linspace(0, 1000, 200); % 生成横坐标房屋面积数据
y 1.5 * x 100; % 生成房价
data [x; y]; % 组合成二维数据% -------------------------变量------------------------ %
iteration_num 500; % 迭代次数
noise_level 30; % 定义噪声参数
theta1 0; % 初始化斜率
theta0 0; % 初始化截距
alpha 0.01; % 学习率
m length(y); % 样本数量
J_history zeros(iteration_num, 1); % 记录每次迭代的损失值noise noise_level * randn(size(data)); % 生成与数据相同大小的高斯噪声
noisy_data data noise; % 将噪声添加到数据中noisy_x noisy_data(1,:); % 添加噪声后的特征房屋面积
noisy_y noisy_data(2,:); % 添加噪声后的结果房价std_x (noisy_x - mean(noisy_x)) / std(noisy_x); % 标准化x
std_y (noisy_y - mean(noisy_y)) / std(noisy_y); % 标准化y% ------------------------------主循环代码-------------------------------
% GPT的例程是固定一个迭代次数例如1000次次数到了就退出循环输出结果
% 笔者尝试固定一个损失值当损失小于固定值时才退出循环但运行效果不佳
% 故放弃了这种方案
% ----------------------------------------------------------------------
for i 1 : iteration_numy_pred theta1 * std_x theta0; % 预测值% 计算梯度d_theta1 (1/m) * (theta1 * sum(std_x.^2) - sum((std_y - theta0) .* std_x));d_theta0 theta0 - (1/m) * sum(std_y - theta1 * std_x);% 更新参数theta1 theta1 - alpha * d_theta1;theta0 theta0 - alpha * d_theta0;loss (1/m) * sum((y_pred - std_y).^2); % 计算损失J_history(i) loss;
end% ------------------------------绘制图像1------------------------------- %
subplot(2, 1, 1); % 创建两个子图
plot(noisy_data(1,:), noisy_data(2,:), .b);
grid on; % 添加网格
xlim([0, 1000]); % 设置x轴范围
ylim([0, 1800]); % 设置y轴范围
hold on; % 保持图形防止被后续图形覆盖% 反归一化后才是真正的theta0和theta1
theta1 theta1 * (std(noisy_y) / std(noisy_x)); % 恢复原始斜率
theta0 mean(noisy_y) - theta1 * mean(noisy_x); % 恢复原始截距y_fit theta1 * noisy_x theta0; % 计算回归线的 y 值
plot(noisy_x, y_fit, -g, LineWidth, 2); % 绘制回归线title(运行结果); % 标题
xlabel(房屋面积); % 横坐标标签
ylabel(房屋价格); % 纵坐标标签
legend(数据点, 回归线); % 图例hold off;% ------------------------------绘制图像2------------------------------- %
subplot(2, 1, 2); % 创建两个子图
plot(1 : iteration_num, J_history, -r, LineWidth, 2);
grid on; % 添加网格
title(损失函数收敛图); % 标题
xlabel(迭代次数); % 横坐标标签
ylabel(损失值); % 纵坐标标签% ------------------------------输出结果------------------------------- %
fprintf(迭代次数%d次\n, iteration_num);
fprintf(loss损失%.6f\n, loss);
fprintf(最终线性回归方程y %.2fx %.2f\n, theta1, theta0);
fprintf(theta1 %.2f, theta0 %.2f\n, theta1, theta0);% -----------------------------END OF FILE---------------------------- %
六、加餐 其实是自己忘记了汗... 在更新公式中有一个学习率参数α我们尝试修改α来看看对模型的影响。 α 0.01 α 0.002 α 5 通过 以上测试我们可以发现α越小模型收敛的速度越慢需要通过增加迭代次数来达到预期的效果。而当α取值不当时模型可能无法收敛。因此选取合适学习率α以及迭代次数至关重要这影响到了代码运行的效率以及最终的预测结果。迭代次数越多代码循环的次数越多耗费的时间越长。
七、闲聊 这只是一次课堂作业的学习记录。很遗憾的是笔者未来的工作规划并不考虑机器学习方向自己还是比较喜欢做硬件所以大家并不需要因为这篇文章对我进行关注后续也不一定会更新有关机器学习方向的内容抱歉。 此外有关Matlab的代码笔者参考了GPT的例程主要的逻辑框架为GPT生成笔者只是对输入样本、一些运行参数、相关公式、整体代码风格以及输出图像的效果进行了修改特此声明。感叹GPT太强大了真的节约了很多的时间。
2024-10-20-18:50爽