神经网络中的算法优化(皮毛讲解)

抛砖引玉

在深度学习中,优化算法是训练神经网络时至关重要的一部分。
优化算法的目标是最小化(或最大化)一个损失函数,通常通过调整神经网络的参数来实现。
这个过程可以通过梯度下降法来完成,其中梯度指的是损失函数关于参数的偏导数。
本文将介绍一阶优化算法和二阶优化算法,并详细讲解常用的梯度下降法,包括梯度下降法、随机梯度下降法、动量法、AdaGrad、RMSProp和Adam。
在这里插入图片描述

一阶优化算法

一阶优化算法主要根据损失函数的一阶导数(梯度)来更新模型参数。常见的一阶优化算法包括梯度下降法、随机梯度下降法、动量法等。

1. 梯度下降法(Gradient Descent)

梯度下降法是最基本的优化算法之一,它通过计算损失函数关于参数的梯度,并沿着梯度的反方向更新参数,从而使损失函数不断减小。
在这里插入图片描述
在这里插入图片描述
因为这里的损失函数是在整个数据集上进行计算得到的均值,所以每更新一次模型参数,就要对整个数据集进行一个计算,可想而知这样非常的慢,并且当数据集变得非常大的时候,如此多的数据没法都load到内存中。

void gradient_descent(float *params, float *gradients, float learning_rate, int n){for (int i = 0; i < n; i++){params[i] -= learning_rate * gradients[i];}
}

在这里插入图片描述

2. 随机梯度下降法(Stochastic Gradient Descent)

在这里插入图片描述
随机梯度下降法和梯度下降法其实是走的两个极端,梯度下降法是每次更新都计算整个数据集的loss,而随机梯度下降法每次更新都只用了一对样本,即上面公式中的一对样本(在这里插入图片描述由于每个样本都会对模型进行更新,所以模型更新的特别频繁,参数就会变成高方差,损失函数的波动也会有很大强度的变化。有时候,这是好事,因为这样的可以帮助我们探索新的更新方向,找到更加好的局部极值点。但是,由于频繁的更新和波动,会导致模型的损失收敛的非常不稳定。

在这里插入图片描述
上图就是随机梯度下降法更新过程中loss值的变化,可以发现loss值的变化非常大,这就是模型超调了,整个模型比较不稳定

随机梯度下降法是梯度下降法的一种变种,它在每次迭代中随机选取一部分样本来计算梯度,从而加快了训练速度。

void stochastic_gradient_descent(float *params, float *gradients, float learning_rate, int n) 
{for (int i = 0; i < n; i++) {params[i] -= learning_rate * gradients[i];}
}

在这里插入图片描述

3. 动量法(Momentum)

带momentum(动量)的梯度下降法也是一种很常用的的优化算法。这种方法因为引入了momentum量,所以能够对梯度下降法起到加速的作用。

打个比方,一个球顺着斜坡往下滚动,会因为地心引力的原因而一直加速,速度越来越快的往坡低滚去。梯度下降法中的Momentum量就和地心引力的作用很类似,能够让梯度下降法沿着下降的方向逐渐扩大幅度。起到对梯度下降法进行加速的作用。在这里插入图片描述
从上述公式(1)可以看出,当当前的梯度方向在这里插入图片描述的正负号)和在这里插入图片描述的方向相同时,在这里插入图片描述
所以参数 θ 的变化幅度会增大,从而加快梯度下降法的幅度;而当方向不同时,会逐步减小当前更新的幅度。这样可以有效的对梯度下降法进行加速,同时提高模型的稳定性。

动量法通过引入动量项来加速收敛过程,它模拟了物体运动时的惯性,可以减少梯度更新的波动,从而加快了训练速度。

void momentum(float *params, float *gradients, float learning_rate, float momentum_rate, float *velocities, int n) {for (int i = 0; i < n; i++) {velocities[i] = momentum_rate * velocities[i] + learning_rate * gradients[i];params[i] -= velocities[i];}
}

二阶优化算法

二阶优化算法基于损失函数的二阶导数(Hessian矩阵)来更新模型参数。常见的二阶优化算法包括AdaGrad、RMSProp和Adam。

1. AdaGrad

在mini batch梯度下降法中,因为对所有的参数均使用相同的学习率,而当有的参数的梯度很大,有的很小时,显然不合适。另外,对于不同的样本,如果有的样本出现的较为频繁,导致其对应的一些参数更新较为频繁,而有的样本出现的频率很低,导致一些参数更新频率很低时,再采用相同的学习率有时候也不太合适。我们更加希望那些出现更新频率比较低的参数能够有更大的更新幅度。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

AdaGrad算法通过动态调整学习率来提高收敛速度,它根据参数的历史梯度调整学习率,对于频繁出现的参数会降低学习率,对于不经常出现的参数会增加学习率。

void adagrad(float *params, float *gradients, float learning_rate, float epsilon, float *accumulators, int n){for (int i = 0; i < n; i++){accumulators[i] += gradients[i] * gradients[i];params[i] -= learning_rate * gradients[i] / (sqrt(accumulators[i]) + epsilon);}
}

2. RMSProp

RMSProp算法是对AdaGrad算法的改进,它通过引入一个衰减系数来控制历史梯度的衰减速度,从而减少了学习率的波动。

void rmsprop(float *params, float *gradients, float learning_rate, float decay_rate, float epsilon, float *accumulators, int n) 
{for (int i = 0; i < n; i++) {accumulators[i] = decay_rate * accumulators[i] + (1 - decay_rate) * gradients[i] * gradients[i];params[i] -= learning_rate * gradients[i] / (sqrt(accumulators[i]) + epsilon);}
}

3. Adam

前面我们从最经典的梯度下降法开始,介绍了几个改进版的梯度下降法。
Momentum方法通过添加动量,提高收敛速度;
Nesterov方法在进行当前更新前,先进行一次预演,从而找到一个更加适合当前情况的梯度方向和幅度;
Adagrad让不同的参数拥有不同的学习率,并且通过引入梯度的平方和作为衰减项,而在训练过程中自动降低学习率;
AdaDelta则对Adagrad进行改进,让模型在训练后期也能够有较为适合的学习率。
在这里插入图片描述

Adam算法是一种结合了动量法和RMSProp算法的优化算法,它不仅考虑了梯度的一阶矩(均值),还考虑了梯度的二阶矩(方差),从而更加准确地更新参数。

void adam(float *params, float *gradients, float learning_rate, float beta1, float beta2, float epsilon, float *m, float *v, int t, int n) {for (int i = 0; i < n; i++) {m[i] = beta1 * m[i] + (1 - beta1) * gradients[i];v[i] = beta2 * v[i] + (1 - beta2) * gradients[i] * gradients[i];float m_hat = m[i] / (1 - pow(beta1, t));float v_hat = v[i] / (1 - pow(beta2, t));params[i] -= learning_rate * m_hat / (sqrt(v_hat) + epsilon);}
}

代码实现

下面是一个简单示例,演示了如何使用上述优化算法训练一个简单的线性回归模型。

#include <iostream>
#include <cmath>void gradient_descent(float *params, float *gradients, float learning_rate, int n) 
{for (int i = 0; i < n; i++){params[i] -= learning_rate * gradients[i];}
}void stochastic_gradient_descent(float *params, float *gradients, float learning_rate, int n){for (int i = 0; i < n;```cppi++) {params[i] -= learning_rate * gradients[i];}
}void momentum(float *params, float *gradients, float learning_rate, float momentum_rate, float *velocities, int n) 
{for (int i = 0; i < n; i++){velocities[i] = momentum_rate * velocities[i] + learning_rate * gradients[i];params[i] -= velocities[i];}
}void adagrad(float *params, float *gradients, float learning_rate, float epsilon, float *accumulators, int n){for (int i = 0; i < n; i++){accumulators[i] += gradients[i] * gradients[i];params[i] -= learning_rate * gradients[i] / (sqrt(accumulators[i]) + epsilon);}
}void rmsprop(float *params, float *gradients, float learning_rate, float decay_rate, float epsilon, float *accumulators, int n){for (int i = 0; i < n; i++) {accumulators[i] = decay_rate * accumulators[i] + (1 - decay_rate) * gradients[i] * gradients[i];params[i] -= learning_rate * gradients[i] / (sqrt(accumulators[i]) + epsilon);}
}void adam(float *params, float *gradients, float learning_rate, float beta1, float beta2, float epsilon, float *m, float *v, int t, int n) 
{for (int i = 0; i < n; i++){m[i] = beta1 * m[i] + (1 - beta1) * gradients[i];v[i] = beta2 * v[i] + (1 - beta2) * gradients[i] * gradients[i];float m_hat = m[i] / (1 - pow(beta1, t));float v_hat = v[i] / (1 - pow(beta2, t));params[i] -= learning_rate * m_hat / (sqrt(v_hat) + epsilon);}
}int main(){// 参数初始化float params[2] = {0};float gradients[2] = {0};float velocities[2] = {0};float accumulators[2] = {0};float m[2] = {0};float v[2] = {0};// 数据初始化float x[5] = {1, 2, 3, 4, 5};float y[5] = {2, 4, 6, 8, 10};// 学习率float learning_rate = 0.01;// 动量因子float momentum_rate = 0.9;// AdaGrad参数float epsilon_adagrad = 1e-8;// RMSProp参数float decay_rate_rmsprop = 0.9;float epsilon_rmsprop = 1e-8;// Adam参数float beta1_adam = 0.9;float beta2_adam = 0.999;float epsilon_adam = 1e-8;// 训练int epochs = 100;int n = 2;for (int epoch = 1; epoch <= epochs; epoch++) {float loss = 0;for (int i = 0; i < 5; i++) {float prediction = params[0] * x[i] + params[1];float error = prediction - y[i];loss += error * error;gradients[0] = 2 * error * x[i];gradients[1] = 2 * error;// 使用各种优化算法更新参数// gradient_descent(params, gradients, learning_rate, n);// stochastic_gradient_descent(params, gradients, learning_rate, n);// momentum(params, gradients, learning_rate, momentum_rate, velocities, n);// adagrad(params, gradients, learning_rate, epsilon_adagrad, accumulators, n);// rmsprop(params, gradients, learning_rate, decay_rate_rmsprop, epsilon_rmsprop, accumulators, n);adam(params, gradients, learning_rate, beta1_adam, beta2_adam, epsilon_adam, m, v, epoch, n);}loss /= 5;std::cout << "Epoch " << epoch << ", Loss = " << loss << ", Params = " << params[0] << ", " << params[1] << std::endl;}return 0;
}

这段代码演演示了实现梯度下降法、随机梯度下降法、动量法、AdaGrad、RMSProp和Adam等优化算法来训练一个简单的线性回归模型
在这里插入图片描述

总结 Gradient Descent Algorithm

Gradient Descent is one of the fundamental optimization algorithms used in machine learning and deep learning. It is used to minimize a loss function by iteratively adjusting the parameters of a model. The basic idea behind Gradient Descent is to compute the gradient of the loss function with respect to the model’s parameters and update the parameters in the opposite direction of the gradient to minimize the loss.

Algorithm Steps:

  1. Initialize Parameters: Start by initializing the parameters of the model with random values.

  2. Compute Gradients: Compute the gradient of the loss function with respect to each parameter of the model using backpropagation.

  3. Update Parameters: Update the parameters of the model using the following update rule:

  4. 在这里插入图片描述在这里插入图片描述

  5. Repeat: Repeat steps 2 and 3 until the loss converges to a minimum or for a fixed number of iterations.

Pseudocode:

function gradient_descent(params, gradients, learning_rate):for each parameter theta in params:theta = theta - learning_rate * gradient

Implementation in C++:

void gradient_descent(float *params, float *gradients, float learning_rate, int n) {for (int i = 0; i < n; i++) {params[i] -= learning_rate * gradients[i];}
}

Conclusion:

Gradient Descent is a powerful optimization algorithm used to train machine learning and deep learning models. It is simple to implement and computationally efficient, making it the go-to choice for optimizing a wide range of models.


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

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

相关文章

利用“AnaTraf“网络流量分析仪轻松诊断和优化网络

网络性能监测和诊断(NPMD)是网络管理和优化的重要环节,准确快速地定位和排除网络故障对于保障业务正常运转至关重要。作为一款专业的网络流量分析设备,AnaTraf网络流量分析仪凭借其强大的流量分析和故障诊断功能,为网络管理者提供了一个高效的网络优化解决方案。 全面掌握网络…

计算机网络实验1:交换机基本配置管理

实验目的和要求 安装Packer Tracer&#xff0c;了解Packer Tracer的基本操作掌握交换机基本命令集实验项目内容 认识Packet Tracer软件 交换机的基本配置与管理 交换机的端口配置与管理 交换机的端口聚合配置 交换机划分Vlan配置 实验环境 硬件&#xff1a;PC机&#x…

体验MouseBoost PRO,让Mac操作更高效

还在为Mac的右键功能而烦恼吗&#xff1f;试试MouseBoost PRO for Mac吧&#xff01;这款强大的鼠标右键增强软件&#xff0c;能让你通过简单操作即可激活多种实用功能&#xff0c;让你的工作变得更加轻松。其高度定制化的设计&#xff0c;更能满足你的个性化需求。赶快下载体验…

【ubuntu】ubuntu-18.04开机卡在Starting User Manager for UID 120....问题解决方案

错误截图 解决方案 启动系统&#xff0c;开机界面单击按键esc键&#xff0c;注意需要将鼠标定位到菜单界面&#xff0c;移动键盘上下键选择Advanced options for Ubuntu 进入如下菜单&#xff0c;选择recovery mode 回车之后会弹出如下界面&#xff0c;选择如下root&#xff0…

瀚高数据库(HighGoDB)Windows安装使用

1.下载 2.安装 瀚高数据库下载与安装&#xff08;Windows版&#xff09;-CSDN博客 3.连接工具 4.建库、建表操作 瀚高数据库管理工具-CSDN博客 *报错Cant access non-default database&#xff0c;需要右键数据库-设为活动对象 5.导入外部数据&#xff08;迁移、对比&…

生信人写程序1. Perl语言模板及配置

生物信息领域常用语言 个人认为&#xff1a;是否能熟悉使用Shell(项目流程搭建)R(数据统计与可视化)Perl/Python/Java…(胶水语言&#xff0c;数据格式转换&#xff0c;软件间衔接)三门语言是一位合格生物信息工程师的标准。 生物信息常用语言非常广泛&#xff0c;我常用的有…

爱普生推出5G基站可用耐高温高稳定性温补晶振

爱普生推出了六款新的温补晶振型号:TG7050CKN&#xff0c;TG7050SKNTG7050CMN&#xff0c;TG7050SMN&#xff0c;TG-5510CA&#xff0c;TG-5511CA。这几款的特点就是耐高温温度可达105℃C高温&#xff0c;而且都是高稳定性温补晶振&#xff0c;而且都是7050尺寸&#xff0c;这个…

AVL 树的理解和简单实现

目录 1. AVL 树 1.1. AVL 树的概念 1.2. AVL 树的性质 2. AVL 树的框架如下 2. AVL树的 插入 2.1. 平衡因子的更新 2.2.1. 平衡因子更新的第一种情况 2.2.2. 平衡因子更新的第二种情况 2.2.3. 平衡因子更新的第三种情况 2.2.4. 平衡因子更新的代码框架如下 2.2. AV…

Centos 中如何汉化man命令

刚学Linux&#xff0c;记不住命令和选项&#xff0c;很依赖里面的 man 查看命令&#xff0c;但因为着实看不懂&#xff0c;有没有什么办法把man查看命令的信息改成中文 在CentOS 7中&#xff0c;你可以通过安装man-pages-zh包来获取中文的man手册。以下是具体的步骤&#xff1a…

Java入门基础学习笔记1——初识java

1、为什么学习java&#xff1f; 几乎统治了服务端的开发&#xff1b;几乎所有的互联网企业都使用&#xff1b;100%国内大中型企业都用&#xff1b;全球100亿的设备运行java。开发岗位薪资高。 Java的流行度很高&#xff0c;商用占有率很高。 可移植性。 2、Java的背景知识 …

(动画详解)LeetCode面试题 02.04.分割链表

&#x1f496;&#x1f496;&#x1f496;欢迎来到我的博客&#xff0c;我是anmory&#x1f496;&#x1f496;&#x1f496; 又和大家见面了 欢迎来到动画详解LeetCode系列 用通俗易懂的动画的动画使leetcode算法题可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读…

Jsp+Servlet实现图片上传和点击放大预览功能(提供Gitee源码)

前言&#xff1a;在最近老项目的开发中&#xff0c;需要做一个图片上传和点击放大的功能&#xff0c;在Vue和SpringBoot框架都有现成封装好的组件和工具类&#xff0c;对于一些上世纪的项目就没这么方便了&#xff0c;所以需要自己用原生的代码去编写&#xff0c;这里分享一下我…

中国当代最具影响力的人物颜廷利:死神(死亡)并不可怕,可怕的是…

中国当代最具影响力的人物颜廷利&#xff1a;死神&#xff08;死亡&#xff09;并不可怕&#xff0c;可怕的是… 在中国优秀传统文化之中&#xff0c;汉语‘巳’字与‘四’同音&#xff0c;在阿拉伯数字里面&#xff0c;通常用‘4’来表示&#xff1b; 作为汉语‘九’字&#x…

第三步->手撕spring源码之基于Cglib实现实例化策略

为什么深入研究spring源码&#xff1f; 其实每一个程序员每天的工作都是一贯的CRUD 实现业务和需求完成的操作。几年这样的操作让我感觉在这方面要提神能力 光靠CRUD是绝对不可能的事情 CRUD只是满足你作为一个搬砖人而已。编程能力提升&#xff1f;其实更多的编程能力的提升是…

【408真题】2009-03

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…

如何远程控制另一部手机:远程控制使用方法

在现今高科技的社会中&#xff0c;远程控制手机的需求在某些情境下变得越来越重要。不论是为了协助远在他乡的家人解决问题&#xff0c;还是为了确保孩子的在线安全&#xff0c;了解如何实现这一功能都是有益的。本文将为您简要介绍几种远程控制手机的方法及其使用要点。 KKVi…

第五届电子通讯与人工智能学术会议(ICECAI 2024, 5/31-6/2)

目录 1. 会议官方2. 会议新闻中华人民共和国教育部新闻 3. 出版历史4. 大会简介5. 主办单位与嘉宾主办单位承办单位主讲嘉宾组委会 6. 征稿主题7. 论文出版8. 参会说明 1. 会议官方 2024 5th International Conference on Electronic communication and Artificial Intelligenc…

算法提高之字串变换

算法提高之字串变换 核心思想&#xff1a;双向广搜 双向bfs 建立两个队列 一起bfs到中间态 #include <iostream>#include <cstring>#include <algorithm>#include <queue>#include <unordered_map>using namespace std;const int N 6;int n;…

网络工程师----第二十四天

计算机基础 第一章&#xff1a;概述 互联网的组成&#xff1a; &#xff08;1&#xff09;边缘部分&#xff1a;由所有连接在互联网上的主机组成。这部分是用户直接使用的&#xff0c;用来进行通信&#xff08;传送数据、音频或视频&#xff09;和资源共享。 &#xff08;2…

[论文笔记]Corrective Retrieval Augmented Generation

引言 今天带来论文Corrective Retrieval Augmented Generation的笔记&#xff0c;这是一篇优化RAG的工作。 大型语言模型(LLMs) inevitable(不可避免)会出现幻觉&#xff0c;因为生成的文本的准确性不能仅仅由其参数化知识来确保。尽管检索增强生成(RAG)是LLMs的一个可行补充…