机器学习(神经网络基础篇)——个人理解篇6(概念+代码)

1 在声明一个类中,构建一个属于类的函数,前面为什要加上“self”?

就像下面这一串代码:

 class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std=0.01):# 
初始化权重self.params = {}self.params['W1'] = weight_init_std * \np.random.randn(input_size, hidden_size)self.params['b1'] = np.zeros(hidden_size)self.params['W2'] = weight_init_std * \np.random.randn(hidden_size, output_size)self.params['b2'] = np.zeros(output_size)def predict(self, x):W1, W2 = self.params['W1'], self.params['W2']b1, b2 = self.params['b1'], self.params['b2']a1 = np.dot(x, W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2y = softmax(a2)return y

解释:

在Python中,self 是一个指向当前类实例自身的引用参数,它的作用类似于“我”或“这个对象”。它的存在是为了让类的方法(函数)能够访问和操作这个实例的属性(变量)和其他方法。

专业解释:

1 访问实例属性
在 predict 方法中,你需要访问当前实例的权重参数 self.params['W1']、self.params['b1'] 等。没有 self,方法就不知道去哪里找这些参数。
2 区分不同实例
如果有多个神经网络实例(比如 net1 和 net2),它们的权重参数是独立的。通过 self,每个实例的方法只会操作自己的参数,不会互相干扰。

通俗解释:
想象你有一个机器人(类 TwoLayerNet),它身上有多个按钮(属性如 params)和功能(方法如 predict)。当你按下某个功能按钮时,机器人需要知道:“这个功能是针对 我自身 的哪些属性操作的?”这时 self 就是告诉机器人:“操作的是当前这个机器人自己的按钮,而不是其他机器人的。”

总结:self 是类方法的“自我标识符”,让方法知道应该操作哪个实例的数据。没有它,类的方法就无法区分不同实例的属性。

2   神经网络中的参数优化,你知道哪些?有什么优缺点?(纯个人总结)

所谓优化,实质上是找使得损失函数的值最小的一组参数。举一个生活中的例子:

2.1   用调热水澡水温类比神经网络参数优化

想象你正在调整淋浴的冷热水龙头,目标是找到 ​最舒适的水温。这个过程与神经网络的参数优化惊人地相似:

1. 初始状态(参数初始化)​
  • 场景​:第一次打开淋浴,随机拧动冷热龙头(初始权重和偏置随机设置)。
  • 结果​:水温要么太冷(预测错误),要么太烫(损失函数值大)。
2. 试水温(前向传播)​
  • 动作​:伸手试水温,感受冷热程度。
  • 对应​:
    • 输入数据 = 当前冷热水比例(参数)
    • 输出结果 = 实际水温(预测值)
    • 目标 = 理想水温(标签)
    • 误差 = 水温偏差(损失函数值)
3. 调整龙头(反向传播与梯度下降)​
  • 冷热不均(计算梯度)​​:

    • 若水太冷 → ​需要更多热水​(梯度指向增加热水权重的方向)。
    • 若水太热 → ​需要更多冷水​(梯度指向减少热水权重的方向)。
    • 调整幅度 = 手拧龙头的力度(学习率)。
  • 具体操作​:

    • 微调热水龙头开大一点(参数更新公式:W = W - 学习率 × 梯度)。
    • 下次再试水温(下一轮训练)。
4. 反复调试(迭代优化)​
  • 过程​:
    太冷 → 加热水 → 试水 → 太烫 → 减热水 → 试水 → 接近舒适 → 微调...
  • 对应​:
    通过多次迭代(epoch),参数(冷热水比例)逐渐收敛到最佳值(损失函数最小化)。
5. 成功(模型收敛)​
  • 结果​:水温稳定在理想温度(模型准确预测)。
  • 关键因素​:
    • 学习率​:手拧龙头的幅度太大(学习率高)→ 水温反复震荡;幅度太小(学习率低)→ 调整过慢。
    • 耐心(迭代次数)​​:足够多的调试次数才能找到平衡点。

2.2     SGD(随机下降)介绍

1   核心公式:

这里把需要更新的权重参数记为W,把损失函数关于W的梯度记为。 η表示学习率,实际上会取0.01或0.001这些事先决定好的值。上式中的←表示用右边的值更新左边的值。(可以理解为朝向梯度下降的方向前进)

2   SGD缺点:

首先来求的最值问题。

左图表示的函数是向x轴方向延伸的“碗”状函数。 右图是等高线呈向x轴方向延伸的椭圆状。

此函数对应的梯度如下图:

这个梯度的特征是,y轴方向上大,x轴方向上小。换句话说, 就是y轴方向的坡度大,而x轴方向的坡度小。假设从(x , y )=(-7, 2)处 (初始值)开始搜索,结果如下图所示:

如图,虽然最后能找到“最优点”,但是过程很曲折,,SGD呈“之”字形移动。这是一个相当低效的路径,在Y轴上跨度比较大,但是在水平方向上看,每次平移的:“步伐”总是很小。

为了改正SGD的缺点,下面将介绍Momentum、AdaGrad、Adam这3 种方法来取代SGD。

2.3  Momentum(同SGD相比,引入了阻力下的初始速度)

Momentum是“动量”的意思,和物理有关。

1   我个人的理解:

将二维空间图像的梯度进行正交分解,在梯度跨度大的方向(比如Y轴)对梯度的跨度进行适当的“动态调整”,在梯度跨度小的方向(比如X轴)对梯度的跨度施加外力作用,“迫使”梯度跨度逐渐增加。

2  核心公式:

和前面的SGD一样,W表示要更新的权重参数,表示损失函数关 于W的梯度,η表示学习率。这里新出现了一个变量v,对应物理上的速度。

例如下图:

αv这一项,在物体不受任何力时,该项承担使物体逐渐减 速的任务(α设定为0.9之类的值),对应物理上的地面摩擦或空气阻力。

class Momentum:def __init__(self, lr , moment):self.lr = lrself.moment = momentself.v = Nonedef update (self, para , grad):if self.v is None:self.v = {}for key , val in para.items():self.v[key] = np.zeros_like(val)for key in para.keys():para[key] = self.moment * self.v[key] - self.lr - grad[key]para[key] =+ self.v[key]

实例变量v会保存物体的速度。初始化时,v中什么都不保存,但当第 一次调用update()时,v会以字典型变量的形式保存与参数结构相同的数据。

假设采用Momentum解决函数最优化的问题,相应的 优化路径如下:

    

和SGD相比,我们发现 “之”字形的“程度”减轻了。这是因为虽然x轴方向上受到的力非常小,但 是一直在同一方向上受力,所以朝同一个方向会有一定的加速。反过来,虽 然y轴方向上受到的力很大,但是因为交互地受到正方向和反方向的力,它 们会互相抵消,所以y轴方向上的速度不稳定。因此,和SGD时的情形相比, 可以更快地朝x轴方向靠近,减弱“之”字形的变动程度。

2.4    AdaGrad

在神经网络的学习中,学习率(数学式中记为η)的值很重要。学习率过小, 会导致学习花费过多时间;反过来,学习率过大,则会导致学习发散而不能 正确进行。

有一种被称为学习率衰减(learning rate decay)的方法,即随着学习的进行,使学习率逐渐减小。

AdaGrad会为参数的每个元素适当地调整学习率。

1  核心公式:

和前面的SGD一样,W表示要更新的权重参数, 表示损失函数关 于W的梯度,η表示学习率。这里新出现了变量h,它保 存了以前的所有梯度值的平方和(表示对应矩阵元素的乘法)。 然后,在更新参数时,通过乘以,就可以调整学习的尺度。这意味着, 参数的元素中变动较大(被大幅更新)的元素的学习率将变小。也就是说, 可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。

AdaGrad代码实现过程:

class AdaGrad:def __init_(self, lr = 0.01):self.lr = lrself.h = Nonedef update(self, para, grad):if self.h is None:self.h = {}for key, val in para.items():self.h[key] = np.zeros_like(val)for key in para.keys():self.h[key] += grad[key] * grad[key]para[key] -= self.lr * grad[key] / (np.sqrt(self.h[key]) + 1e-7)

假设采用AdaGrad解决函数最优化的问题,相应的 优化路径如下:

函数的取值高效地向着最小值移动。由于y轴方 向上的梯度较大,因此刚开始变动较大,但是后面会根据这个较大的变动按 比例进行调整,减小更新的步伐。因此,y轴方向上的更新程度被减弱,“之” 字形的变动程度有所衰减.

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

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

相关文章

Cribl 对Windows-xml log 进行 -Removing filed-06

Removing Fields Description​ The Eval Function can be used to add or remove fields. In this example we will remove the extracted fields while preserving _raw, _time,index,source, sourcetype. Steps - Adding an Eval Function

chili3d调试6 添加左侧面板

注释前 一个一个注释看对应哪个窗口 无事发生 子方法不是显示的窗口 注释掉看看 没了 注释这个看看 零件页面没了 这个浏览器居然完全不用关的,刷新就重载了 注释看看 无工具栏版本 sidebar: 往框框里面加入 div({ className: style.input }, user_…

Linux学习——了解和熟悉Linux系统的远程终端登录

Linux学习——了解和熟悉Linux系统的远程终端登录 一.配置Ubuntu系统的网络和用户 1、设置虚拟机网络为桥接模式 打开VMWare,选择编辑虚拟机设置,在网络适配器设置中,选择“桥接模式”,保存设置并启动Ubuntu。 2、配置Ubuntu的…

【JAVA EE初阶】多线程(1)

这样的代码,虽然也能打印hello thread,但是没有创建新的线程,而是直接在main方法所在的主线程中执行了run的逻辑 start方法,是调用系统api,真正在操作系统内部创建一个线程。这个新的线程会以run作为入口方法&#xff…

javase 学习

一、Java 三大版本 javaSE 标准版 (桌面程序; 控制台开发) javaME 嵌入式开发(手机、小家电)基本不用,已经淘汰了 javaEE E业级发开(web端、 服务器开发) 二、Jdk ,jre jvm 三…

【Linux】Linux 操作系统 - 05 , 软件包管理器和 vim 编辑器的使用 !

文章目录 前言一、软件包管理器1 . 软件安装2 . 包管理器3 . Linux 生态 二、软件安装 、卸载三、vim 的使用1 . 什么是 vim ?2 . vim 多模式3 . 命令模式 - 命令4 . 底行模式 - 命令5. 插入模式6 . 替换模式7 . V-BLOCK 模式8 . 技巧补充 总结 前言 本篇笔者将会对软件包管理…

python基础知识点(1)

python语句 一行写一条语句 一行内写多行语句,使用分号分隔建议每行写一句,且结束时不写分号写在[ ]、{ }内的跨行语句,被视为一行语句\ 是续行符,实现分行书写功能 反斜杠表示下一行和本行是同一行 代码块与缩进 代码块复合语句&#xf…

C#/.NET/.NET Core技术前沿周刊 | 第 35 期(2025年4.14-4.20)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。 欢迎投稿、推荐…

HTML表单与数据验证设计

HTML 表单与数据验证设计:构建可靠的用户数据采集系统 引言 互联网的核心是数据交互,而HTML表单是这一交互的主要入口。作为前端工程师,设计高质量的表单不仅关乎用户体验,更直接影响数据收集的准确性和系统安全。 在我的学习实…

基于STM32的Keil环境搭建与点灯

本人使用的STM32开发板为正点原子的STM32F103ZE,在此记录完整的搭建与点灯过程。 一、Keil的安装与配置 安装Keil 首先进入Keil下载官网:https://www.keil.com/download/product/ 点击MDK-ARM,并填写相关信息,之后开始下载最新版…

React-useRef

如果我们想在hooks里面获同步取最新的值&#xff0c;那么则可以使用useRef, 关键源码如下&#xff1a; function mountRef<T>(initialValue: T): {|current: T|} {const hook mountWorkInProgressHook();const ref {current: initialValue};hook.memoizedState ref;re…

幽灵依赖与常见依赖管理

文章目录 前言1. 演示&#xff1a;检测和修复幽灵依赖步骤1&#xff1a;安装 depcheck步骤2&#xff1a;在项目根目录运行 depcheck可能的输出步骤3&#xff1a;修复幽灵依赖 2. 依赖管理的好习惯 1. 场景设定现在有如下依赖需求&#xff1a; 2. 依赖冲突的表现3. 解决依赖冲突…

如何使用人工智能大模型,免费快速写工作总结?

如何使用人工智能大模型&#xff0c;免费快速写工作总结&#xff1f; 详细学习视频https://edu.csdn.net/learn/40406/666581

[Java实战经验]异常处理最佳实践

一些好的异常处理实践。 目录 异常设计自定义异常为异常设计错误代码&#xff08;状态码&#xff09;设计粒度全局异常处理异常日志信息保留 异常处理时机资源管理try-with-resources异常中的事务 异常设计 自定义异常 自定义异常设计&#xff0c;如业务异常定义BusinessExce…

Makefile 入门指南

Makefile 入门指南 最简单的例子 单文件编译 假设我们有一个main.cpp文件&#xff0c;最简单的Makefile如下&#xff1a; # 最简单的单文件编译 # 目标:依赖文件 main: main.cpp# 编译命令g main.cpp -o main使用步骤&#xff1a; 将上述内容保存为名为Makefile的文件&…

PyTorch数据操作基础教程:从张量创建到高级运算

本文通过示例代码全面讲解PyTorch中张量的基本操作&#xff0c;包含创建、运算、广播机制、索引切片等核心功能&#xff0c;并提供完整的代码和输出结果。 1. 张量创建与基本属性 import torch# 创建连续数值张量 x torch.arange(12, dtypetorch.float32) print("原始张…

【Redis】Redis中的常见数据类型(一)

文章目录 前言一、Redis前置知识1. 全局命令2、数据结构和内部编码3. 单线程架构 二、String 字符串1. 常见命令2. 计数命令3.其他命令4. 内部编码5. 典型使用场景 三、Hash哈希1. 命令2.内部编码3. 使用场景4. 缓存方式对比 结语 前言 Redis 提供了 5 种数据结构&#xff0c;…

Windows 中使用 `netstat` 命令查看端口占用

在 Windows 系统中&#xff0c;可以通过 netstat 命令来查看当前系统的网络连接以及端口的占用情况。以下是关于该命令的具体说明&#xff1a; #### 使用方法 1. **查看所有端口及其状态** 可以通过以下命令查看系统中的所有活动连接和监听端口&#xff1a; bash net…

23种设计模式-结构型模式之装饰器模式(Java版本)

Java 装饰器模式&#xff08;Decorator Pattern&#xff09;详解 &#x1f381; 什么是装饰器模式&#xff1f; 装饰器模式是一种结构型设计模式&#xff0c;允许向一个对象动态添加新的功能&#xff0c;而不改变其结构。 &#x1f9f1; 你可以想象成在原有功能上“包裹”一…

解决模拟器打开小红书设备异常问题

解决模拟器打开小红书设备异常问题 解决模拟器打开小红书设备异常问题和无法打开问题 解决模拟器打开小红书设备异常问题和无法打开问题 问题描述 最近有用户反馈在模拟器上无法正常登录和打开小红书APP&#xff0c;系统提示"设备异常"错误。本文将详细介绍如何通过…