Python----机器学习(线性回归:自求导的方法实现)

news2025/4/7 21:11:43

一、线性回归方程

目标:

         线性回归的目标是找到最佳的系数\beta _{0},\beta _{1},\beta _{2}......\beta _{n}来使模型与观察到的数据尽可能拟合。

应用:

        预测:给定自变量的值,预测因变量的值。

        回归分析:确定自变量对因变量的影响程度 

        线性回归是统计学和机器学习中最简单且最常用的技术之一,它提供了一个基本的框架来理解和分析变量之间的关系,并用于许多实际应用中,如经济学、金融学、医学、社会科学等领域。

二、参数和超参数 

2.1、参数

        模型中可调整的变量,它们用来捕捉数据中的模式和特征。这些参数在模型训练过程中被不断调整以最小化损失函数或优化某种目标。

        权重(Weights):用来表示不同输入特征与神经元之间的连接强度

        偏置(Biases):用于调整每个神经元的激活阈值,使模型能够更好地拟合数据

2.2、超参数 

        超参数(Hyperparameters)是机器学习和深度学习模型中的一类参数, 它们不是通过训练数据学习得到的,而是在训练过程之前需要手动设置的参数。

        与模型的权重和偏置等参数不同,超参数并不直接控制模型的学习过程。 相反,超参数是在训练之前选择或调整的一组参数,用于定义模型的架 构、优化算法、学习率、正则化强度、迭代次数等。它们的选择往往是基 于经验、启发式规则、交叉验证等方法。

        常见的超参数包括但不限于以下几个例子:

                1. 学习率(Learning Rate):用于控制优化算法中每次更新参数时的步 长。较小的学习率会导致训练收敛较慢,而较大的学习率可能导致训练 不稳定或震荡。

                2. 正则化参数(Regularization Parameter):用于控制正则化的强度, 如L1正则化和L2正则化。较大的正则化参数会增强正则化效果,有助 于防止过拟合。

                3. 迭代次数(Number of Iterations):用于控制训练的迭代次数。迭代次数太小可能导致模型未完全学习数据的特征,而迭代次数太大可能导 致过拟合。

                4. 批量大小(Batch Size):用于控制每次训练时用于更新参数的样本数 量。批量大小的选择会影响训练速度和内存消耗。

                5. 神经网络层数和每层的神经元数量(Number of Layers and Neurons per Layer):用于定义神经网络的结构。

                6. 激活函数(Activation Function):用于控制神经网络每个神经元的输 出范围,如Sigmoid、ReLU等。

        选择合适的超参数对于模型的性能和泛化能力至关重要。通常,人们需要 通过多次试验和交叉验证等方法来调整超参数,以找到最优的组合,从而 获得最好的模型性能。调整超参数是机器学习和深度学习模型开发中一个 重要的步骤,也是一个相对耗时的过程。

三、反向传播

四、设计思路 

散点输入

data = np.array([
    [-0.5, 7.7],
    [1.8, 98.5],
    [0.9, 57.8],
    [0.4, 39.2],
    [-1.4, -15.7],
    [-1.4, -37.3],
    [-1.8, -49.1],
    [1.5, 75.6],
    [0.4, 34.0],
    [0.8, 62.3]
])
x_data = data[:, 0]
y_data = data[:, 1]

参数初始化

w = 0
b = 0
learning_rate = 0.01

损失函数

def loss_fun(X, Y, w, b):
    _y_hat = X * w + b
    loss = np.mean((2 * (_y_hat - Y) ** 2))
    return loss

散点图

for n in range(1, 501):  # 进行 500 次迭代训练  
    # a = wx + b  # 根据当前参数计算预测值  
    y_hat = w * x_data + b  # 计算根据参数得到的预测值  

    # da/dw = x  # w 对预测值的影响(斜率)  
    # e = (y - a) ** 2  # 计算损失(误差的平方)  
    # de/da = -2 * (y - a)  # 计算损失对预测值的导数(梯度)  

    # de/dw = de/da * da/dw  # 链式法则计算损失对 w 的梯度  
    # de/dw = -2 * (y - a) * x  # 损失对 w 的梯度  
    gradient_w = np.mean(2 * (y_hat - y_data) * x_data)  # 计算 w 的梯度均值  

    # de/db = de/da * da/db  # 同样的逻辑应用于 b  
    # de/db = -2 * (y - a)  # 损失对 b 的梯度  
    gradient_b = np.mean(2 * (y_hat - y_data))  # 计算 b 的梯度均值  

    # 梯度下降更新参数:   
    w = w - learning_rate * gradient_w  # 更新权重 w  
    b = b - learning_rate * gradient_b  # 更新偏置 b  

    if n % 10 == 0 or n == 1:  # 每 10 次迭代或第一次迭代时  
        plt.cla()  # 清空当前图形  
        min_x = x_data.min()  # 获取 x 数据的最小值  
        max_x = x_data.max()  # 获取 x 数据的最大值  
        min_y = w * min_x + b  # 根据当前的 w 和 b 计算最小 y 值  
        max_y = w * max_x + b  # 根据当前的 w 和 b 计算最大 y 值  
        
        plt.scatter(x_data, y_data, marker='o', color='b')  # 绘制散点图  
        plt.plot([min_x, max_x], [min_y, max_y], color='r')  # 绘制拟合线  

        plt.xlabel('X')  # 设置 x 轴标签  
        plt.ylabel('Y')  # 设置 y 轴标签  
        plt.pause(1)  # 暂停 1 秒以更新图形  

plt.show()  # 最后显示图形  

损失图

# 创建网格用于绘制等高线
w_values = np.linspace(-20, 80, 100)
b_values = np.linspace(-20, 80, 100)
W, B = np.meshgrid(w_values, b_values)
loss_value = np.zeros_like(W)

# 计算每对 (w, b) 的损失值
for i in range(len(w_values)):
    for j in range(len(b_values)):
        loss_value[j, i] = loss_fun(x_data, y_data, w_values[i], b_values[j])

# 训练过程
path = []  # 路径记录 w 和 b 的值
for n in range(1, 501):
    path.append((w, b))  # 记录当前参数值
    y_hat = w * x_data + b  # 预测值

    # 计算梯度
    gradient_w = np.mean(2 * (y_hat - y_data) * x_data)
    gradient_b = np.mean(2 * (y_hat - y_data))

    # 梯度下降法更新参数
    w -= learning_rate * gradient_w
    b -= learning_rate * gradient_b

    # 每 10 次迭代或第一次迭代时绘制
    if n % 10 == 0 or n == 1:
        plt.clf()  # 清空当前图形
        plt.contourf(W, B, loss_value, levels=20, cmap='viridis')  # 绘制等高线图
        plt.colorbar()  # 显示颜色条
        plt.scatter(w, b, c='r', label='当前参数')  # 绘制当前参数点
        plt.plot(*zip(*path), c='r', label='路径')  # 绘制路径
        plt.title(f'迭代次数: {n}')
        plt.xlabel('w')
        plt.ylabel('b')
        plt.legend()

plt.show() 

 W,B等离线

完整代码 

import numpy as np  
from matplotlib import pyplot as plt  
from matplotlib import gridspec  

# 1. 散点输入  
data = np.array([  
    [-0.5, 7.7],  
    [1.8, 98.5],  
    [0.9, 57.8],  
    [0.4, 39.2],  
    [-1.4, -15.7],  
    [-1.4, -37.3],  
    [-1.8, -49.1],  
    [1.5, 75.6],  
    [0.4, 34.0],  
    [0.8, 62.3]  
])  
x_data = data[:, 0]  # 获取输入数据的 x 值  
y_data = data[:, 1]  # 获取输入数据的 y 值  

# 2. 参数初始化  
w = 0  # 权重初始值  
b = 0  # 偏置初始值  
learning_rate = 0.01  # 学习率,用于更新参数的步长  

# 3. 损失函数  
def loss_fun(X, Y, w, b):  
    _y_hat = X * w + b  # 根据当前权重和偏置计算预测值  
    loss = np.mean((2 * (_y_hat - Y) ** 2))  # 计算均方误差损失  
    return loss  

fig = plt.figure(figsize=(12, 6))  
g = gridspec.GridSpec(2, 2)  # 创建一个 2x2 的网格  

ax2 = fig.add_subplot(g[0, 0])  # 上左子图用于散点图  
ax2.set_xlabel('X')  # 设置 x 轴标签  
ax2.set_ylabel('Y')  # 设置 y 轴标签  

ax3 = fig.add_subplot(g[1, 0])  # 下左子图用于参数可视化  
ax3.set_xlabel('w')  # 设置 w 轴标签  
ax3.set_ylabel('b')  # 设置 b 轴标签  

ax1 = fig.add_subplot(g[:, 1], projection='3d')  # 右侧 3D 子图用于损失可视化  
w_values = np.linspace(-20, 80, 100)  # 生成 w 的取值范围  
b_values = np.linspace(-20, 80, 100)  # 生成 b 的取值范围  
W, B = np.meshgrid(w_values, b_values)  # 创建网格以计算损失值  
loss_value = np.zeros_like(W)  # 初始化损失值数组  

# 计算每对 (w, b) 的损失值  
for i, w in enumerate(w_values):  
    for j, b in enumerate(b_values):  
        loss_value[j, i] = loss_fun(x_data, y_data, w, b)  # 计算并保存损失值  

# 绘制损失表面  
ax1.plot_surface(W, B, loss_value, alpha=0.8, cmap='viridis')  # 绘制 3D 表面  
ax1.set_xlabel('w')  # 设置 x 轴标签  
ax1.set_ylabel('b')  # 设置 y 轴标签  
ax1.set_zlabel('loss')  # 设置 z 轴标签  

path = []  # 用于记录 w 和 b 的值以绘制路径  

# 4. 开始迭代  
for n in range(1, 501):  
    path.append((w, b))  # 记录当前 w 和 b 的值  
    # 5、反向传播,手动计算损失函数关于自变量(模型参数)的梯度  
    # a=wx+b  
    y_hat = w * x_data + b  # 计算预测值  
    # da/dw=x  
    # e=(y-a)**2  
    # de/da=-2(y-a)  
    
    # de/dw=de/da * da/dw  
    # de/dw=-2(y-a)*x  
    gradient_w = np.mean(2 * (y_hat - y_data) * x_data)  # 计算关于 w 的梯度  
    # de/db=de/da * da/db  
    # de/db=-2(y-a)  
    gradient_b = np.mean(2 * (y_hat - y_data))  # 计算关于 b 的梯度  
    
    # 梯度下降  
    w = w - learning_rate * gradient_w  # 更新 w  
    b = b - learning_rate * gradient_b  # 更新 b  

    # 6. 显示频率设置  
    if n % 10 == 0 or n == 1:  # 每10次迭代或者第一次迭代显示一次  
        x_min = x_data.min()  # 获取 x 值的最小值  
        x_max = x_data.max()  # 获取 x 值的最大值  
        y_min = w * x_min + b  # 根据当前的 w 和 b 计算最小 y 值  
        y_max = w * x_max + b  # 根据当前的 w 和 b 计算最大 y 值  
        ax2.cla()  # 清除之前的图形  
        ax2.scatter(x_data, y_data)  # 绘制散点图  
        ax2.plot([x_min, x_max], [y_min, y_max], c='r')  # 绘制拟合线  

        ax3.contourf(W, B, loss_value, levels=20)  # 绘制等高线图  
        ax3.scatter(w, b, c='r')  # 绘制当前参数点  

        ax1.scatter(w, b, loss_fun(x_data, y_data, w, b))  # 在3D图中添加当前损失点  

        if len(path) > 0:  
            path_w, path_b = zip(*path)  # 分离记录的 w 和 b  
            ax3.plot(path_w, path_b, c='r')  # 绘制路径  
            
            # 在 3D 图中绘制路径  
            ax1.plot(path_w, path_b,   
                      [loss_fun(x_data, y_data, w_val, b_val) for w_val, b_val in zip(path_w, path_b)], c='r')  

        plt.pause(1)  # 暂停 1 秒

plt.show()  # 显示最终图形  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springcache+xxljob实现定时刷新缓存

目录 SpringCache详解 SpringCache概述 核心原理 接口抽象与多态 AOP动态代理 核心注解以及使用 公共属性 cacheNames KeyGenerator:key生成器 key condition:缓存的条件,对入参进行判断 注解 xxl-job详解 SpringcacheRedis实现…

vue2拖拉拽做个模拟公式工具

1. 成图 2. 介绍 就是简单拖拉拽来做个规则运算器&#xff0c;具体运算规则、校验规则自己加。 3. 代码 HTML代码 <template><div class"red-cont"><div class"red-top"><divclass"red-top-left"><div class&quo…

Windows查重工具,强烈推荐大家收藏!

我大家在用电脑的时候&#xff0c;是不是发现用得越久&#xff0c;电脑里的软件和文件就越多&#xff1f; 今天我给大家带来的这两款重复文件查找神器&#xff0c;简直就是电脑里的“清洁小能手”&#xff0c;能帮你把那些重复的文件和文件夹找出来。 Easy DupLicate Finder 重…

使用python完成手写数字识别

入门图像识别的第一个案例,看到好多小伙伴分享,也把自己当初的思路捋捋,写成一篇博客,作为记录和分享,也欢迎各位交流讨论。 实现思路 数据集:MNIST(包含60,000个训练样本和10,000个测试样本) 深度学习框架:Keras(基于TensorFlow) 模型架构:卷积神经网络(CNN) 实…

OpenLayers:如何控制Overlay的层级?

我最近在使用Overlay的时候遇到了一个问题&#xff0c;我向地图中添加了两种不同的Overlay&#xff08;下图中的蓝色标牌和粉色标牌&#xff09;&#xff0c;我希望粉色标牌可以显示在最上层&#xff0c;可偏偏蓝色标牌却将其遮挡住了。于是我对Overlay的层级开始起了兴趣&…

《Golang高性能网络编程:构建低延迟服务器应用》

在本文中&#xff0c;我们将深入探讨Golang高性能网络编程&#xff0c;帮助您构建低延迟服务器应用。我们将介绍Golang的网络编程特性、优化技巧和实际案例&#xff0c;让您更好地理解和应用Golang在网络编程领域的优势。 高性能网络编程简介 什么是Golang高性能网络编程 高性能…

数据结构C语言练习(设计循环队列)

一、循环队列简介 循环队列是一种线性数据结构&#xff0c;基于 FIFO&#xff08;先进先出&#xff09;原则&#xff0c;将队尾连接到队首形成循环。其核心优势是能复用队列之前用过的空间&#xff0c;避免普通队列 “假溢出” 问题。实现时&#xff0c;通常申请 k1 大小的数组…

vscode代码片段的设置与使用

在 Visual Studio Code (VS Code) 中&#xff0c;可以通过自定义**代码片段&#xff08;Snippets&#xff09;**快速插入常用代码模板。以下是详细设置步骤&#xff1a; 步骤 1&#xff1a;打开代码片段设置 按下快捷键 Ctrl Shift P&#xff08;Windows/Linux&#xff09;或…

uniapp -- 列表垂直方向拖拽drag组件

背景 需要在小程序中实现拖拽排序功能,所以就用到了m-drag拖拽组件,在开发的过程中,发现该组件在特殊的场景下会有些问题,并对其进行了拓展。 效果 组件代码 <template><!-- 创建一个垂直滚动视图,类名为m-drag --><scroll

一款非常小的软件,操作起来非常丝滑!

今天我想给大家分享一款超级实用的小软件&#xff0c;它是一款电脑上用的倒计时和关机助手。 关机助手 帮你自动关机 这款关机助手特别小巧&#xff0c;完全不需要安装&#xff0c;文件大小才60KB&#xff0c;比一个小小的文件还小。你只需要把它下载下来&#xff0c;双击打开…

FrameWork基础案例解析(四)

文章目录 单独拉取framework开机与开机动画横屏Android.mk语法单独编译SDKmake 忽略warning单独修改和编译Camera2单独编译Launcher3Android Studio 导入、修改、编译Settings导入 Android Studio 导入、修改、编译Launcher3android 开机默认进入指定Launcher植入自己的apk到系…

通过 C# 提取PDF文档中的图片

当 PDF 文件中包含有价值的图片&#xff0c;如艺术画作、设计素材、报告图表等&#xff0c;提取图片可以将这些图像资源进行单独保存&#xff0c;方便后续在不同的项目中使用&#xff0c;避免每次都要从 PDF 中查找。本文将介绍如何使用C#通过代码从PDF文档中提取图片&#xff…

国标GB28181视频监控平台EasyCVR保驾护航休闲娱乐“九小场所”安全运营

凭借降低人力资源、节约物资成本的优势&#xff0c;在多个场景得到广泛应用。如今&#xff0c;棋牌室、洗浴中心、酒店这类人员频繁流动和密集的场所&#xff0c;已成为安全管理的重点。​ 尽管部分棋牌室已安装了监控设备&#xff0c;但是设备功能单一&#xff0c;只能实现一…

GoLand 2024.3 中文 GO语言开发工具

GoLand 2024.3 中文 GO语言开发工具 文章目录 GoLand 2024.3 中文 GO语言开发工具一、介绍二、效果三、下载 一、介绍 JetBrains GoLand 2024 &#xff0c;是一款GO语言开发工具&#xff0c;全行代码补全&#xff1a;能使用本地运行的上下文感知深度学习模型&#xff0c;可以自…

CentOS 7 强制升级Docker 24.x终极指南(解决MySQL8镜像兼容性问题)

CentOS 7 强制升级Docker 24.x终极指南&#xff08;解决MySQL8镜像兼容性问题&#xff09; 旧版本&#xff1a; 新版本docker&#xff1a; 一、问题背景与方案选型 1.1 典型报错分析 The designated data directory /var/lib/mysql/ is unusable根本原因&#xff1a;旧版…

【区块链安全 | 第十九篇】类型之映射类型

文章目录 映射类型可迭代映射 映射类型 映射类型使用语法 mapping(KeyType KeyName? > ValueType ValueName?)&#xff0c;映射类型的变量声明使用语法 mapping(KeyType KeyName? > ValueType ValueName?) VariableName。 KeyType 可以是任何内置值类型、bytes、st…

Flask与 FastAPI 对比:哪个更适合你的 Web 开发?

在开发 Web 应用时&#xff0c;Python 中有许多流行的 Web 框架可以选择&#xff0c;其中 Flask 和 FastAPI 是两款广受欢迎的框架。它们各有特色&#xff0c;适用于不同的应用场景。本文将从多个角度对比这两个框架&#xff0c;帮助你更好地选择适合的框架来构建你的 Web 应用…

QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理

目录 1.简介 2.原理概述 3.实现分析 3.1.通过方法名调用方法的实现分析 3.2.通过可调用对象调用方法的实现分析 4.使用场景 5.总结 1.简介 QMetaObject::invokeMethod 是 Qt 框架中的一个静态方法&#xff0c;用于在运行时调用对象的成员函数。这个方法提供了一种动态调…

【无人机】无人机PX4飞控系统高级软件架构

目录 1、概述&#xff08;图解&#xff09; 一、数据存储层&#xff08;Storage&#xff09; 二、外部通信层&#xff08;External Connectivity&#xff09; 三、核心通信枢纽&#xff08;Message Bus&#xff09; 四、硬件驱动层&#xff08;Drivers&#xff09; 五、飞…

【SPP】蓝牙链路控制(LC)在SPP中互操作性深度解析

在蓝牙协议栈的精密分层体系中&#xff0c;其链路控制&#xff08;Link Control, LC&#xff09;层作为基带层的核心组件&#xff0c;承载着物理信道管理、连接建立与维护等关键任务。其互操作性要求直接决定了不同厂商设备能否实现无缝通信。本文将以蓝牙技术规范中的LC互操作…