从零开始学习深度学习库-3:更多优化器

系列文章:
从零开始学习深度学习库-1:前馈网络
从零开始学习深度学习库-2:反向传播

欢迎来到本系列的第三部分,在这里,我们将从零开始构建一个深度学习库。

在这篇文章中,我们将向我们的库中添加更多的优化函数和损失函数。

这里是这个系列的Github仓库:https://github.com/ashwins-code

优化函数

优化函数的目标是调整网络参数以最小化神经网络的损失。

它通过计算参数相对于损失的梯度,并使用这个梯度来更新参数来实现这一点。

不同的损失函数以不同的方式使用梯度,这会加速训练过程!
在这里插入图片描述
如果我们将损失函数绘制成图形,如上图所示,优化器的目标是改变神经网络的参数,以产生最小的损失值,即图中最低的凹陷处。

优化器在训练过程中的路径由黑色球体表示。

动量

动量是一种优化函数,它扩展了梯度下降算法(我们在上一篇文章中讨论过)。

它旨在加速训练过程,这意味着它可以在更少的迭代中最小化损失。如果我们考虑我们的“黑球”,动量会使这个黑球快速加速朝向最低点,就像从山顶上滚下一个球。

动量累积了在前几个迭代中计算出的梯度,这有助于它确定为了最小化损失而应该前进的方向。

它用于更新参数的公式如下
d t = β ⋅ d t − 1 + l ⋅ g p t + 1 = p t − d t d_t = \beta \cdot d_{t-1} + l \cdot g \\ p_{t+1} = p_t - d_t dt=βdt1+lgpt+1=ptdt

p t p_t pt 是在时刻 t t t 的参数值
d t d_t dt 是在时刻 t t t 需要前进的“方向”,由之前时刻的梯度计算得出。它初始化为0。
l l l 是学习率
β \beta β 是一个预先确定的值(通常选择为0.9)
g g g 是参数相对于该损失的梯度

这里是我们对这个优化器的Python实现

#optim.py

#...
class Momentum:
    def __init__(self, lr = 0.01, beta=0.9):
        self.lr = lr
        self.beta = beta

    def momentum_average(self, prev, grad):
        return (self.beta * prev) + (self.lr * grad)

    def __call__(self, model, loss):
        grad = loss.backward()

        for layer in tqdm.tqdm(model.layers[::-1]):
            grad = layer.backward(grad)

            if isinstance(layer, layers.Layer):
                if not hasattr(layer, "momentum"):
                    layer.momentum = {
                        "w": 0,
                        "b": 0
                    }
                layer.momentum["w"] = self.momentum_average(layer.momentum["w"], layer.w_gradient)
                layer.momentum["b"] = self.momentum_average(layer.momentum["b"], layer.b_gradient)

                layer.w -= layer.momentum["w"]
                layer.b -= layer.momentum["b"]

Adam

Adam(Adaptive Moment Estimation)是一种用于深度学习中的梯度下降优化算法,它被广泛用于更新神经网络的权重。Adam结合了两种扩展的梯度下降算法:Momentum 和 RMSProp。

在Momentum算法中,引入了概念“动量”,可以看作是物理中的惯性,让优化算法能够在相关方向上加速学习,并且能够减少震荡。

RMSProp(Root Mean Square Propagation)算法则是一种适应性学习率方法,它会调整每个参数的学习率,通过使用参数最近梯度的平方的移动平均来做。

Adam算法结合了这两个算法的优点:

1.它计算每个参数的梯度的指数移动平均,类似于Momentum中的做法,这帮助算法在最优解方向上加速。
2.它也计算了这些梯度的平方的指数移动平均,类似于RMSProp中的做法,这使得算法能够适应每个参数的响应能力。

Adam 还包括了偏置修正,这是为了在算法的初始阶段对梯度的估计和梯度平方的估计进行校准,使得它们更加准确。

由于这些特点,Adam通常被认为是一个效果好且计算效率高的优化算法,尤其适用于大规模和高维度的优化问题。Adam的另一个优势是它的超参数通常需要的调整较少,它的默认值往往就能在很多问题上表现良好。

这里是更新方程式…
v t = β 1 ⋅ v t − 1 + ( 1 − β 1 ) ⋅ g s t = β 2 ⋅ s t − 1 + ( 1 − β 2 ) ⋅ g 2 Δ p t = l ⋅ v t s t + ϵ p t + 1 = p t − Δ p t v_t = \beta_1 \cdot v_{t-1} + (1 - \beta_1) \cdot g \\ s_t = \beta_2 \cdot s_{t-1} + (1 - \beta_2) \cdot g^2 \\ \Delta p_t = l \cdot \frac{v_t}{\sqrt{s_t} + \epsilon} \\ p_{t+1} = p_t - \Delta p_t vt=β1vt1+(1β1)gst=β2st1+(1β2)g2Δpt=lst +ϵvtpt+1=ptΔpt

p t p_t pt 是在时刻 t t t 的参数值
v t v_t vt 是先前梯度的指数移动平均值。它初始化为0。
s t s_t st 是先前梯度的指数移动平方平均值。它初始化为0。
l l l 是学习率
β 1 \beta_1 β1 是一个预先确定的值(通常选择为0.9)
β 2 \beta_2 β2 是一个预先确定的值(通常选择为0.999)
g g g 是参数相对于该损失的梯度
ϵ \epsilon ϵ 是一个预先确定的值,用来避免除以0。通常设为 1 0 − 10 10^{-10} 1010

这是我们的Python实现:

#optim.py

#...
class Adam:
    def __init__(self, lr = 0.01, beta1=0.9, beta2=0.999, epsilon=10**-8):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.epsilon = epsilon

    def rms_average(self, prev, grad):
        return (self.beta2 * prev) + (1 - self.beta2) * (grad ** 2)

    def momentum_average(self, prev, grad):
        return (self.beta1 * prev) + ((1 - self.beta1) * grad)

    def __call__(self, model, loss):
        grad = loss.backward()

        for layer in tqdm.tqdm(model.layers[::-1]):
            grad = layer.backward(grad)

            if isinstance(layer, layers.Layer):
                if not hasattr(layer, "adam"):
                    layer.adam = {
                        "w": 0,
                        "b": 0,
                        "w2": 0,
                        "b2": 0
                    }

                layer.adam["w"] = self.momentum_average(layer.adam["w"], layer.w_gradient)
                layer.adam["b"] = self.momentum_average(layer.adam["b"], layer.b_gradient)
                layer.adam["w2"] = self.rms_average(layer.adam["w2"], layer.w_gradient)
                layer.adam["b2"] = self.rms_average(layer.adam["b2"], layer.b_gradient)

                w_adjust = layer.adam["w"] / (1 - self.beta1)
                b_adjust = layer.adam["b"] / (1 - self.beta1)
                w2_adjust = layer.adam["w2"] / (1 - self.beta2)
                b2_adjust = layer.adam["b2"] / (1 - self.beta2)

                layer.w -= self.lr * (w_adjust / np.sqrt(w2_adjust) + self.epsilon)
                layer.b -= self.lr * (b_adjust /  np.sqrt(b2_adjust) + self.epsilon)

使用我们的新优化器!

这就是我们如何在我们的库中使用新优化器来训练模型,解决我们在上一篇文章中描述的相同问题(异或门)。

import layers
import loss
import optim
import numpy as np


x = np.array([[0, 1], [0, 0], [1, 1], [1, 0]])
y = np.array([[0, 1], [1, 0], [1, 0], [0, 1]]) 

net = layers.Model([
    layers.Linear(8),
    layers.Linear(4),
    layers.Sigmoid(),
    layers.Linear(2),
    layers.Softmax()
])

net.train(x, y, optim=optim.RMSProp(lr=0.02), loss=loss.MSE(), epochs=200)

print (net(x))
epoch 190 loss 0.00013359948998165245
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 191 loss 0.00012832321751534635
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 192 loss 0.0001232564322705172
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 193 loss 0.00011839076882215646
100%|██████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 5018.31it/s]
epoch 194 loss 0.00011371819900553786
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 195 loss 0.00010923101808808603
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 196 loss 0.00010492183152425807
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 197 loss 0.00010078354226798005
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 198 loss 9.680933861835338e-05
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 199 loss 9.299268257548828e-05
100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?it/s]
epoch 200 loss 8.932729868441197e-05
[[0.00832775 0.99167225]
 [0.98903246 0.01096754]
 [0.99082742 0.00917258]
 [0.00833392 0.99166608]]

正如你所看到的,与上一篇文章相比,由于我们的新优化器,我们的模型训练得更好了!

感谢阅读!在下一篇文章中,我们将把目前为止的库应用到一个更高级的问题上(手写数字识别!)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构从入门到精通——堆

堆 前言一、二叉树的顺序结构及实现 (堆&#xff09;1.1二叉树的顺序结构1.2堆的概念及结构 二、堆的练习题答案 三、堆的实现3.1堆向下调整算法3.2堆的创建3.3建堆时间复杂度3.4堆的插入3.5堆的删除3.6堆的代码实现 四、堆的具体实现代码Heap.hHeap.cTest.c堆的初始化堆的销毁…

基于单片机的温度控制系统设计

基于单片机的温度控制系统设计 摘要: 最近这些年&#xff0c;随着科学技术的不断发展和进步&#xff0c;单片机技术通过在各行各业中的应用也日臻完善。而温度测控系统也因单片机所特有的强大处理能力、功耗低以及体积小等优点向着小型化和智能化发展。本设计以STC89C52单片机…

Linux服务器之间免密登录

文章目录 1. 原理2. 密钥文件作用解释3. 实操 1. 原理 2. 密钥文件作用解释 #mermaid-svg-uJJwWJXgqGtbNwNB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uJJwWJXgqGtbNwNB .error-icon{fill:#552222;}#mermaid-s…

AttributeError: module ‘tensorflow‘ has no attribute ‘placeholder‘解决办法

1.报错代码 self.inputs_base_structure_left tf.placeholder(dtypetf.float32, shape[None, 2048, 2], name"inputs_left") # initial a inputs to siamese_network2. 报错原因 AttributeError: module tensorflow has no attribute placeholder 这个错误发生的…

基于Java+SpringBoot+vue的智能农场管理系统详细设计和实现

基于JavaSpringBootvue的智能农场管理系统详细设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文…

KKVIEW: 远程控制软件哪个好用

远程控制软件哪个好用 随着科技的发展和工作方式的改变&#xff0c;远程控制软件越来越受到人们的关注和需求。无论是在家中远程办公&#xff0c;还是技术支持人员为远程用户提供帮助&#xff0c;选择一款高效稳定的远程控制软件至关重要。在众多选择中&#xff0c;有几款远程…

做外贸如何打动老是邮件不回复的客户

有人说&#xff1a;进入公司半年&#xff0c;都没有碰到什么大客户&#xff0c;小客户接了没利润&#xff0c;不想接&#xff0c;很难找到自己的定位&#xff0c;不知道如何去开发客户。 这是一个范围很大的问题&#xff0c;每个行业不一样&#xff0c;做外贸很多时候都是相通…

ET框架新起一个服务及实现服务之间的消息通讯

1.配置文件StartSceneConfig 2. SceneFactory switch (scene.SceneType) {case SceneType.Activity:break; } 定义SceneType枚举类型 public enum SceneType: uint {Activity 66, } 3.在InnerMessage.proto文件中定义消息 //ResponseType Activity2Other_Test message Ot…

Unity3d Shader篇(十五)— 激光扫描效果

文章目录 前言一、什么是X射线或激光扫描效果&#xff1f;1. X射线或激光扫描效果原理2. X射线或激光扫描效果优缺点优点&#xff1a;缺点&#xff1a; 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四…

Labelme

文章目录 前言一、遇到问题二、排查问题1.分析问题2.验证问题2.1对比两者&#xff0c;格式是一致的&#xff0c;唯一不同之处是imagePath 不一样&#xff0c;labelme 生成的是图片的名称&#xff0c;不包含路径&#xff1b;而自动生成的是完整路径的图片名称。2.2再次思考两者的…

elasticsearch8.12 分词器安装

分词器的主要作用将用户输入的一段文本&#xff0c;按照一定逻辑&#xff0c;分析成多个词语的一种工具 分词器下载地址 analysis-ik Releases infinilabs/analysis-ik GitHub 一个简便 安装方式 安装完成之后 会提示重启&#xff0c;重启es即可 ./bin/elasticsearch-pl…

【AI论文阅读笔记】ResNet残差网络

论文地址&#xff1a;https://arxiv.org/abs/1512.03385 摘要 重新定义了网络的学习方式 让网络直接学习输入信息与输出信息的差异(即残差) 比赛第一名1 介绍 不同级别的特征可以通过网络堆叠的方式来进行丰富 梯度爆炸、梯度消失解决办法&#xff1a;1.网络参数的初始标准化…

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…

C++——类和对象(2)

1. 类的6个默认成员函数 当一个类中什么都没有&#xff0c;编译器会帮类自动生成6个默认成员函数例如&#xff1a; class Date {}; 此篇文章主要围绕构造函数与析构函数进行讲解。 2. 构造函数 2.1 概念 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> usi…

如何零基础入门Prometheus

本公众号的精品教程《玩转Prometheus监控》是一套零基础的入门教程&#xff0c;基于多年实战经验编写而成&#xff0c;内容完整覆盖了产品的核心技术要点&#xff0c;适合想入门和进阶技术的朋友学习。 整个系列总共24篇课程&#xff0c;由基础知识开始&#xff0c;逐步进阶学…

复现文件上传漏洞

一、搭建upload-labs环境 将下载好的upload-labs的压缩包&#xff0c;将此压缩包解压到WWW中&#xff0c;并将名称修改为upload&#xff0c;同时也要在upload文件中建立一个upload的文件。 然后在浏览器网址栏输入&#xff1a;127.0.0.1/upload进入靶场。 第一关 选择上传文件…

webpack5零基础入门-8清空前次打包文件与处理图标字体资源

1.配置output中的clean属性为true output: {/**文件输出路径 绝对路径*///__dirname 表示当前文件的文件夹目录path: path.resolve(__dirname, dist),//所有文件的输出目录/**文件名 */filename: static/js/dist.js,//入口文件输出文件名clean: true,//在打包前将path整个目录内…

【学习笔记】红队视角下的windows应急响应

1. 上线的方法 exe上线→开360晶核的情况比较困难 2&#xff09;白加黑 接下来的讲解就是基于白加黑上线&#xff0c;看如何应对应急 2. 演示 360环境启动 shell whoami →死 -beacon 如何去查杀 看外联&#xff1a; netstat -ano 提取IP 威胁情报api调用→查是否是恶意…

【Qt】QListView 显示富文本,设置文本内容颜色

【Qt】QListView 显示富文本&#xff0c;设置文本内容颜色 文章目录 I - 控件使用II - 显示富文本III - 注意事项 I - 控件使用 Qt 的 MVC 架构为 MV &#xff0c;Controller 部分继承到了 View 里&#xff0c;View(视图) 设置 Model(模型)&#xff0c;Model 设置数据 这里使用…

设备维修带来的无限价值——易点易动设备管理系统的优势

在化工工厂中&#xff0c;设备的正常运行是保障生产顺利进行的关键。然而&#xff0c;设备难免会出现故障和损坏&#xff0c;而及时有效的设备维修对于提高生产效率和降低成本至关重要。为了解决这一问题&#xff0c;易点易动设备管理系统应运而生&#xff0c;以其卓越的功能和…