同步进行一波网上代码搬砖, 先来个入门的线性回归模型训练, 基于梯度下降法来, 优化用 MSE 来做. 理论部分就不讲了, 网上一大堆, 我自己也是理解好多年了, 什么 偏导数, 梯度(多远函数一阶偏导数组成的向量) , 方向导数, 反方向(梯度下降) 这些基本的高数知识, 假设大家是非常清楚原理的.

如不清楚原理, 那就没有办法了, 只能自己补, 毕竟 ML 这块, 如果不清楚其数学原理, 只会有框架和导包, 那得是多门的无聊和无趣呀. 这里是搬运代码的, 当然, 我肯定是有改动的,基于我的经验, 做个小笔记, 方便自己后面遇到时, 直接抄呀.

01 采样数据

这里呢, 假设已知一个线性模型, 就假设已经基本训练好了一个, 比如是这样的.

\(y=1.477x + 0.089\)

现在为了更好模拟真实样本的观测误差, 给模型添加一个误差变量 \(\epsilon\) (读作 \epsilon) , 然后想要搞成这样的.

\(y =1.477x + 0.089 + \epsilon, \epsilon-N(0, 0.01^2)\)

现在来随机采样 100次, 得到 n=100 的样本训练数据集

import numpy as np 

def data_sample(times=100):
"""数据集采样times次, 返回一个二维数组"""
for i in range(times):
# 随机采样输入 x, 一个数值 (均匀分布)
x = np.random.uniform(-10, 10)
# 采样高斯噪声(随机误差),正态分布
epsilon = np.random.normal(0, 0.01)
# 得到模型输出
y = 1.447 * x + 0.089 + epsilon
# 用生成器来生成或存储样本点
yield [x, y] # test
# 将数据转为 np.array 的二维数组
data = np.array(list(data_sample()))

data 是这样的, 2D数组, 一共100行记录, 每一行表示一个样本点 (x, y).

array([[  5.25161007,   7.6922458 ],
[ 9.00034456, 13.11119931],
[ 9.47485633, 13.80426132],
[ -4.3644416 , -6.2183884 ],
[ -3.35345323, -4.76625711],
[ -5.10494006, -7.30976062],
.....
[ -6.78834597, -9.73362456]]

02 计算误差 MSE

计算每个点 (xi, yi) 处的预测值 与 真实值 之差的平方 并 累加, 从而得到整个训练集上的均方误差损失值.

# y = w * x + b
def get_mse(w, b, points):
"""计算训练集的 MSE"""
# points 是一个二维数组, 每行表示一个样本
# 每个样本, 第一个数是 x, 第二个数是 y
loss = 0
for i in range(0,len(X)):
x = points[i, 0]
y = points[i, 1]
# 计算每个点的误差平方, 并进行累加
loss += (y - (w * x + b)) ** 2
# 用 总损失 / 总样本数 = 均方误差 mse
return loss / len(points)

样本是一个二维数组, 或者矩阵. 每一行, 表示一个样本, 每一列表示该样本的某个子特征

03 计算梯度

关于梯度, 即多元函数的偏导数向量, 这个方向是, 多元函数的最大导数方向 (变化率最大) 方向 (向量方向), 于是, 反方向, 则是函数变化率最小, 即极值点的地方呀, 就咱需要的, 所以称为, 梯度下降法嘛, 从数学上就非常好理解哦.

def step_gradient(b_current, w_current, points, lr):
# 计算误差函数在所有点的导数, 并更新 w, b
b_gradient = 0
w_gradinet = 0
n = len(points) # 样本数
for i in range(n):
# x, y 都是一个数值
x = points[i, 0]
y = points[i, 1]
# 损失函数对 b 的导数 g_b = 2/n * (wx+b-y) 数学推导的
b_gradient += (n/2) * ((w_current * x + b) - y)
# 损失函数对 w 的导数 g_w = 2/n (wx+b-y) x
w_gradinet += (n/2) * x * ((w_current * x + b) - y) # 根据梯度下降法, 更新 w, b
new_w = w_current - (lr * b_gradient)
new_b = b_current - (lr * b_gradient) return [new_w, new_b]

04 更新梯度 Epoch

根据第三步, 在算出误差函数在 w, b 的梯度后, 就可以通过 梯度下降法来更新 w,b 的值. 我们把对数据集的所有样本训练一次称为一个 Epoch, 共循环迭代 num_iterations 个 Epoch.

def gradient_descent(points, w, b, lr, max_iter):
"""梯度下降 Epoch"""
for step in range(max_iter):
# 计算梯度并更新一次
w, b = step_gradient(b, w, np.array(points),lr)
# 计算当前的 均方差 mse
loss = get_mes(w, b, points)
if step % 50 == 0:
# 每隔50次打印一次当前信息
print(f"iteration: {step} loss: {loss}, w:{w}, b:{b}") # 返回最后一次的 w,b
return [w, b]

05 主函数

def main():
# 加载训练数据, 即通过真实模型添加高斯噪声得到的
lr = 0.01 # 学习率
init_b = 0
init_w = 0
max_iter = 500 # 最大Epoch=100次
# 用梯度下降法进行训练
w, b = gradient_descent(data, init_w, init_b, lr, max_iter)
# 计算出最优的均方差 loss
loss = get_mse(w, b, dataa) print(f"Final loss: {loss}, w:{w}, b:{b}") # 运行主函数
main()
iteration: 0 loss: 52624.8637745707, w:-37.451784525811654, b:-37.451784525811654
iteration: 50 loss: 8.751081967754209e+134, w:-5.0141110054193505e+66, b:-5.0141110054193505e+66
iteration: 100 loss: 1.7286223665339186e+265, w:-7.047143783692584e+131, b:-7.047143783692584e+131
iteration: 150 loss: inf, w:-9.904494626138306e+196, b:-9.904494626138306e+196 iteration: 200 loss: inf, w:-1.3920393397706614e+262, b:-1.3920393397706614e+262 iteration: 250 loss: nan, w:nan, b:nan
iteration: 300 loss: nan, w:nan, b:nan
iteration: 350 loss: nan, w:nan, b:nan
iteration: 400 loss: nan, w:nan, b:nan
iteration: 450 loss: nan, w:nan, b:nan
************************************************************
Final loss: nan, w:nan, b:nan

可以看到, 在 Epoch 100多次, 后, 就已经收敛了. 当然正常来说, 应该给 loss 设置一个阈值的, 不然后面都 inf 了, 我还在 epoch, 这就有问题了. 这里就不改了, 总是习惯留下一些不完美, 这样才会记得更深. 其目的也是在与数理 ML 整个训练过程, 用入门级的 线性回归和 梯度下降法来整.

LR梯度下降法MSE演练的更多相关文章

  1. pytorch梯度下降法讲解(非常详细)

    pytorch随机梯度下降法1.梯度.偏微分以及梯度的区别和联系(1)导数是指一元函数对于自变量求导得到的数值,它是一个标量,反映了函数的变化趋势:(2)偏微分是多元函数对各个自变量求导得到的,它反映 ...

  2. 梯度下降法实现(Python语言描述)

    原文地址:传送门 import numpy as np import matplotlib.pyplot as plt %matplotlib inline plt.style.use(['ggplo ...

  3. 快速用梯度下降法实现一个Logistic Regression 分类器

    前阵子听说一个面试题:你实现一个logistic Regression需要多少分钟?搞数据挖掘的人都会觉得实现这个简单的分类器分分钟就搞定了吧? 因为我做数据挖掘的时候,从来都是顺手用用工具的,尤其是 ...

  4. (3)梯度下降法Gradient Descent

    梯度下降法 不是一个机器学习算法 是一种基于搜索的最优化方法 作用:最小化一个损失函数 梯度上升法:最大化一个效用函数 举个栗子 直线方程:导数代表斜率 曲线方程:导数代表切线斜率 导数可以代表方向, ...

  5. 线性回归(最小二乘法、批量梯度下降法、随机梯度下降法、局部加权线性回归) C++

    We turn next to the task of finding a weight vector w which minimizes the chosen function E(w). Beca ...

  6. 梯度下降法及一元线性回归的python实现

    梯度下降法及一元线性回归的python实现 一.梯度下降法形象解释 设想我们处在一座山的半山腰的位置,现在我们需要找到一条最快的下山路径,请问应该怎么走?根据生活经验,我们会用一种十分贪心的策略,即在 ...

  7. 机器学习---用python实现最小二乘线性回归算法并用随机梯度下降法求解 (Machine Learning Least Squares Linear Regression Application SGD)

    在<机器学习---线性回归(Machine Learning Linear Regression)>一文中,我们主要介绍了最小二乘线性回归算法以及简单地介绍了梯度下降法.现在,让我们来实践 ...

  8. optim.SDG 或者其他、实现随机梯度下降法

    optim.SDG 或者其他.实现随机梯度下降法 待办 实现随机梯度下降算法的参数优化方式 另外还有class torch.optim.ASGD(params, lr=0.01, lambd=0.00 ...

  9. [Machine Learning] 梯度下降法的三种形式BGD、SGD以及MBGD

    在应用机器学习算法时,我们通常采用梯度下降法来对采用的算法进行训练.其实,常用的梯度下降法还具体包含有三种不同的形式,它们也各自有着不同的优缺点. 下面我们以线性回归算法来对三种梯度下降法进行比较. ...

  10. 机器学习基础——梯度下降法(Gradient Descent)

    机器学习基础--梯度下降法(Gradient Descent) 看了coursea的机器学习课,知道了梯度下降法.一开始只是对其做了下简单的了解.随着内容的深入,发现梯度下降法在很多算法中都用的到,除 ...

随机推荐

  1. startup_stm32f10x_xx.s 启动代码文件的选择

    网上查到的各个文件的解释是: startup_stm32f10x_cl.s 互联型的器件startup_stm32f10x_hd.s 大容量startup_stm32f10x_hd_vl.s 大容量s ...

  2. Typecho添加一个当前页面加载完成速度时间

    判断当前页面加载是否快速,通常是直接在浏览器中访问网站,看自己的直观感受是否快速.而客观的方法则是计算具体的页面加载时间并显示出来给看. 1.在当前主题的functions.php文件添加下面的代码: ...

  3. 我的公众号接入了DeepSeek-R1模型,成为了一个会深度思考的强大.NET AI智能体!

    前言 前不久腾讯元器宣布接入满血版 Deepseek R1 模型,模型免费使用且不限量,为智能体开发提供更多样化的模型选择,带来更丰富的智能体功能和玩法. 今天咱们一起来把我公众号的.NET AI智能 ...

  4. Abaqus压电材料分析

    目录 1. ABAQUS压电材料定义[快速版] 2. 压电材料的主要特性参数 3. Abaqus 压电分析 1 电响应 2 initial condition & BCs 4 Load 5 M ...

  5. go cobra实例讲解

    概述 cobra 库是 golang 的一个开源第三方库,能够快速便捷的建立命令行应用程序. 优势:cobra 可以快速建立CLI程序,使我们更专注于命令需要处理的具体的业务逻辑. 举两个例子: hu ...

  6. laravel proc_get_status() has been disabled for security reasons

    解决办法: 在php.ini中,找到disable_functions选项,看看后面是否有proc_open函数被禁用了,去掉proc_get_status,proc_open即可

  7. 使用project制定项目计划可以分为六个步骤

    使用project制定项目计划可以分为六个步骤,如下图(1): 图(1)-project制定项目计划步骤 下面我们就以project2010为例,按上图所示步骤对如何制定项目计划进行详细说明: 一.创 ...

  8. SQL Server 5105 和 1802 错误的触发方式和解决方式之一

    一般导致这两个错误的原因是:文件路径错误 还有的说,可能是文件权限问题,详情见权限错误纠正方式 错误代码 create database teaching on primary ( name = te ...

  9. study Python3 【1】

    用VSCode来编辑Python代码,作为IDE使用,有点头晕. https://www.runoob.com/python3/python-vscode-setup.html有介绍.还有更好的博客介 ...

  10. 活动中台系统慢 SQL 治理实践

    作者:vivo 互联网服务器团队- Zhang Mengtao 活动中台系统作为中台项目非常注重系统性能和用户体验,数据库系统性能问题会对应用程序的性能和用户体验产生负面影响.慢查询可能导致应用程序响 ...