吴恩达深度学习笔记:优化算法 (Optimization algorithms)2.1-2.2

news2024/11/13 15:01:43

目录

  • 第二门课: 改善深层神经网络:超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)
    • 第二周:优化算法 (Optimization algorithms)
      • 2.1 Mini-batch 梯度下降(Mini-batch gradient descent)
      • 2.2 理解 mini-batch 梯度下降法(Understanding mini-batch gradient descent)

第二门课: 改善深层神经网络:超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)

第二周:优化算法 (Optimization algorithms)

2.1 Mini-batch 梯度下降(Mini-batch gradient descent)

本周将学习优化算法,这能让你的神经网络运行得更快。机器学习的应用是一个高度依赖经验的过程,伴随着大量迭代的过程,你需要训练诸多模型,才能找到合适的那一个,所以,优化算法能够帮助你快速训练模型。

其中一个难点在于,深度学习没有在大数据领域发挥最大的效果,我们可以利用一个巨大的数据集来训练神经网络,而在巨大的数据集基础上进行训练速度很慢。因此,你会发现,使用快速的优化算法,使用好用的优化算法能够大大提高你和团队的效率,那么,我们首先来谈谈 mini-batch 梯度下降法。

在这里插入图片描述
你之前学过,向量化能够让你有效地对所有𝑚个样本进行计算,允许你处理整个训练集,而无需某个明确的公式。

所以我们要把训练样本放大巨大的矩阵𝑋当中去,𝑋 = [ x ( 1 ) x ( 2 ) x ( 3 ) … … x ( m ) ) x^{(1)} x^{(2)} x^{(3)} … … x^{(m)}) x(1)x(2)x(3)……x(m))]。𝑌也是如此,𝑌 = [ y ( 1 ) y ( 2 ) y ( 3 ) … … y ( m ) y^{(1)} y^{(2)} y^{(3)} … … y^{(m)} y(1)y(2)y(3)……y(m)]。

所以𝑋的维数是(𝑛𝑥, 𝑚),𝑌的维数是(1, 𝑚),向量化能够让你相对较快地处理所有𝑚个样本。如果𝑚很大的话,处理速度仍然缓慢。比如说,如果𝑚是 500 万或 5000 万或者更大的一个数,在对整个训练集执行梯度下降法时,你要做的是,你必须处理整个训练集,然后才能进行一步梯度下降法,然后你需要再重新处理 500 万个训练样本,才能进行下一步梯度下降法。所以如果你在处理完整个 500 万个样本的训练集之前,先让梯度下降法处理一部分,你的算法速度会更快,准确地说,这是你可以做的一些事情。

你可以把训练集分割为小一点的子集训练,这些子集被取名为 mini-batch,假设每一个子集中只有 1000 个样本,那么把其中的 x ( 1 ) x^{(1)} x(1) x ( 1000 ) x^{(1000)} x(1000)取出来,将其称为第一个子训练集,也叫做 mini-batch,然后你再取出接下来的 1000 个样本,从 x ( 1001 ) x^{(1001)} x(1001) x ( 2000 ) x^{(2000)} x(2000),然后再取 1000个样本,以此类推。

接下来我要说一个新的符号,把 x ( 1 ) x^{(1)} x(1) x ( 1000 ) x^{(1000)} x(1000)称为 X 1 X^{{1}} X1 x ( 1001 ) x^{(1001)} x(1001) x ( 2000 ) x^{(2000)} x(2000)称为 X 2 X^{{2}} X2,如果你的训练样本一共有 500 万个,每个 mini-batch 都有 1000 个样本,也就是说,你有 5000 个mini-batch,因为 5000 乘以 1000 就是 5000 万。

你共有 5000 个 mini-batch,所以最后得到是 X 5000 X^{{5000}} X5000,对𝑌也要进行相同处理,你也要相应地拆分𝑌的训练集,所以这是 Y 1 Y^{{1}} Y1,然后从 y ( 1001 ) y^{(1001)} y(1001) y ( 2000 ) y^{(2000)} y(2000),这个叫 Y 2 Y^{{2}} Y2,一直到 Y 5000 Y^{{5000}} Y5000。mini-batch的数量𝑡组成了 X t X^{{t}} Xt Y t Y^{{t}} Yt,这就是1000个训练样本,包含相应的输入输出对。

在这里插入图片描述
在继续课程之前,先确定一下我的符号,之前我们使用了上角小括号(𝑖)表示训练集里的值,所以 x ( i ) x^{(i)} x(i)是第𝑖个训练样本。我们用了上角中括号[𝑙]来表示神经网络的层数, z [ l ] z^{[l]} z[l]表示神经网络中第𝑙层的𝑧值,我们现在引入了大括号𝑡来代表不同的mini-batch,所以我们有 X t X^{{t}} Xt Y t Y^{{t}} Yt,检查一下自己是否理解无误。
在这里插入图片描述
X t X^{{t}} Xt Y t Y^{{t}} Yt的维数:如果 X 1 X^{{1}} X1是一个有 1000 个样本的训练集,或者说是 1000 个样本的𝑥值,所以维数应该是(𝑛𝑥, 1000), X 2 X^{{2}} X2的维数应该是(𝑛𝑥, 1000),以此类推。因此所有的子集维数都是(𝑛𝑥, 1000),而这些( Y t Y^{{t}} Yt的维数都是(1,1000)。

解释一下这个算法的名称,batch 梯度下降法指的是我们之前讲过的梯度下降法算法,就是同时处理整个训练集,这个名字就是来源于能够同时看到整个 batch 训练集的样本被处理,这个名字不怎么样,但就是这样叫它。

相比之下,mini-batch 梯度下降法,指的是我们在下一张幻灯片中会讲到的算法,你每次同时处理的单个的 mini-batch X t X^{{t}} Xt Y t Y^{{t}} Yt,而不是同时处理全部的𝑋和𝑌训练集。

那么究竟 mini-batch 梯度下降法的原理是什么?在训练集上运行 mini-batch 梯度下降法,你运行 for t=1……5000,因为我们有 5000 个各有 1000 个样本的组,在 for 循环里你要做得基本就是对 X t X^{{t}} Xt Y t Y^{{t}} Yt执行一步梯度下降法。假设你有一个拥有1000个样本的训练集,而且假设你已经很熟悉一次性处理完的方法,你要用向量化去几乎同时处理 1000 个样本。

在这里插入图片描述
首先对输入也就是 X t X^{{t}} Xt,执行前向传播,然后执行 z [ 1 ] = W [ 1 ] X + b [ 1 ] z^{[1]} = W^{[1]}X + b^{[1]} z[1]=W[1]X+b[1],之前我们这里只有,但是现在你正在处理整个训练集,你在处理第一个 mini-batch,在处理 mini-batch 时它变成了 X t X^{{t}} Xt,即 z [ 1 ] = W [ 1 ] X ( t ) + b [ 1 ] z^{[1]} = W^{[1]}X^{(t)} + b^{[1]} z[1]=W[1]X(t)+b[1],然后执行 A [ 1 ] k = g [ 1 ] ( Z [ 1 ] ) A^{[1]k} = g^{[1]}(Z^{[1]}) A[1]k=g[1](Z[1]),之所以用大写的𝑍是因为这是一个向量内涵,以此类推,直到 A [ L ] = g [ L ] ( Z [ L ] ) A^{[L]} = g^{[L]}(Z^{[L]}) A[L]=g[L](Z[L]),这就是你的预测值。注意这里你需要用到一个向量化的执行命令,这个向量化的执行命令,一次性处理 1000 个而不是 500 万个样本。

接下来你要计算损失成本函数𝐽,因为子集规模是 1000, J = 1 1000 ∑ i = 1 l L ( y ^ ( i ) , y ( i ) ) J =\frac{1}{1000}\sum_{i=1}^l{L(\hat{y}^{(i)},y^{(i)})} J=10001i=1lL(y^(i),y(i)) ,说明一下,这 L ( y ^ ( i ) , y ( i ) ) L(\hat{y}^{(i)},y^{(i)}) L(y^(i),y(i))指的是来自于 mini-batch X t X^{{t}} Xt Y t Y^{{t}} Yt中的样本。

如果你用到了正则化,你也可以使用正则化的术语:

J = 1 1000 ∑ i = 1 l L ( y ^ ( i ) , y ( i ) ) + λ 2 ∗ 1000 ∑ l ∣ ∣ w [ l ] ∣ ∣ F 2 J =\frac{1}{1000}\sum_{i=1}^l{L(\hat{y}^{(i)},y^{(i)})} + \frac{λ}{2*1000}\sum_{l}{||w^{[l]}||_F^2} J=10001i=1lL(y^(i),y(i))+21000λl∣∣w[l]F2,因为这是一个 mini-batch 的损失,所以我将𝐽损失记为上角标𝑡,放在大括号里( J = 1 1000 ∑ i = 1 l L ( y ^ ( i ) , y ( i ) ) + λ 2 ∗ 1000 ∑ l ∣ ∣ w [ l ] ∣ ∣ F 2 J =\frac{1}{1000}\sum_{i=1}^l{L(\hat{y}^{(i)},y^{(i)})} + \frac{λ}{2*1000}\sum_{l}{||w^{[l]}||_F^2} J=10001i=1lL(y^(i),y(i))+21000λl∣∣w[l]F2)。

你也会注意到,我们做的一切似曾相识,其实跟之前我们执行梯度下降法如出一辙,除了你现在的对象不是𝑋,𝑌,而是 X t X^{{t}} Xt Y t Y^{{t}} Yt。接下来,你执行反向传播来计算𝐽{𝑡}的梯度,你只是使用 X t X^{{t}} Xt Y t Y^{{t}} Yt,然后你更新加权值,𝑊实际上是 W [ l ] W^{[l]} W[l],更新为 W [ l ] : = W [ l ] − α d W [ l ] W^{[l]}: = W^{[l]} − αdW^{[l]} W[l]:=W[l]αdW[l],对𝑏做相同处理, b [ l ] : = b [ l ] − α d b [ l ] b[l]: = b^{[l]} − αdb^{[l]} b[l]:=b[l]αdb[l]

这是使用 mini-batch 梯度下降法训练样本的一步,我写下的代码也可被称为进行“一代”(1 epoch)的训练。一代这个词意味着只是一次遍历了训练集。

在这里插入图片描述
使用 batch 梯度下降法,一次遍历训练集只能让你做一个梯度下降,使用 mini-batch 梯度下降法,一次遍历训练集,能让你做 5000 个梯度下降。当然正常来说你想要多次遍历训练集,还需要为另一个 while 循环设置另一个 for 循环。所以你可以一直处理遍历训练集,直到最后你能收敛到一个合适的精度。

如果你有一个丢失的训练集,mini-batch 梯度下降法比 batch 梯度下降法运行地更快,所以几乎每个研习深度学习的人在训练巨大的数据集时都会用到,下一个视频中,我们将进一步深度讨论 mini-batch 梯度下降法,你也会因此更好地理解它的作用和原理。

2.2 理解 mini-batch 梯度下降法(Understanding mini-batch gradient descent)

在上周视频中,你知道了如何利用 mini-batch 梯度下降法来开始处理训练集和开始梯度下降,即使你只处理了部分训练集,即使你是第一次处理,本视频中,我们将进一步学习如何执行梯度下降法,更好地理解其作用和原理。
在这里插入图片描述
使用 batch 梯度下降法时,每次迭代你都需要历遍整个训练集,可以预期每次迭代成本都会下降,所以如果成本函数𝐽是迭代次数的一个函数,它应该会随着每次迭代而减少,如果𝐽在某次迭代中增加了,那肯定出了问题,也许你的学习率太大。

使用 mini-batch 梯度下降法,如果你作出成本函数在整个过程中的图,则并不是每次迭代都是下降的,特别是在每次迭代中,你要处理的是 X t X^{{t}} Xt Y t Y^{{t}} Yt,如果要作出成本函数 J t J^{{t}} Jt的图,而 J t J^{{t}} Jt只和 X t X^{{t}} Xt, Y t Y^{{t}} Yt有关,也就是每次迭代下你都在训练不同的样本集或者说训练不同的 mini-batch,如果你要作出成本函数𝐽的图,你很可能会看到这样的结果,走向朝下,但有更多的噪声,所以如果你作出 Y t Y^{{t}} Yt的图,因为在训练 mini-batch 梯度下降法时,会经过多代,你可能会看到这样的曲线。没有每次迭代都下降是不要紧的,但走势应该向下,噪声产生的原因在于也许 X t X^{{t}} Xt Y t Y^{{t}} Yt是比较容易计算的 mini-batch,因此成本会低一些。不过也许出于偶然, X 2 X^{{2}} X2 Y 2 Y^{{2}} Y2是比较难运算的 mini-batch,或许你需要一些残缺的样本,这样一来,成本会更高一些,所以才会出现这些摆动,因为你是在运行 mini-batch 梯度下降法作出成本函数图。

你需要决定的变量之一是 mini-batch 的大小,𝑚就是训练集的大小,极端情况下:

如果 mini-batch 的大小等于𝑚,其实就是 batch 梯度下降法,在这种极端情况下,你就有了 mini-batch X 1 X^{{1}} X1 Y 1 Y^{{1}} Y1,并且该 mini-batch 等于整个训练集,所以把 mini-batch 大小设为𝑚可以得到 batch 梯度下降法。

在这里插入图片描述
另一个极端情况,假设 mini-batch 大小为 1,就有了新的算法,叫做随机梯度下降法,每个样本都是独立的 mini-batch,当你看第一个 mini-batch,也就是 X 1 X^{{1}} X1 Y 1 Y^{{1}} Y1,如果 mini-batch 大小为 1,它就是你的第一个训练样本,这就是你的第一个训练样本。接着再看第二个 mini-batch,也就是第二个训练样本,采取梯度下降步骤,然后是第三个训练样本,以此类推,一次只处理一个。
在这里插入图片描述
看在两种极端下成本函数的优化情况,如果这是你想要最小化的成本函数的轮廓,最小值在那里,batch 梯度下降法从某处开始,相对噪声低些,幅度也大一些,你可以继续找最小值。

相反,在随机梯度下降法中,从某一点开始,我们重新选取一个起始点,每次迭代,你只对一个样本进行梯度下降,大部分时候你向着全局最小值靠近,有时候你会远离最小值,因为那个样本恰好给你指的方向不对,因此随机梯度下降法是有很多噪声的,平均来看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动,但它并不会在达到最小值并停留在此。

实际上你选择的 mini-batch 大小在二者之间,大小在 1 和𝑚之间,而 1 太小了,𝑚太大了,原因在于如果使用 batch 梯度下降法,mini-batch 的大小为𝑚,每个迭代需要处理大量训练样本,该算法的主要弊端在于特别是在训练样本数量巨大的时候,单次迭代耗时太长。如果训练样本不大,batch 梯度下降法运行地很好。

在这里插入图片描述
相反,如果使用随机梯度下降法,如果你只要处理一个样本,那这个方法很好,这样做没有问题,通过减小学习率,噪声会被改善或有所减小,但随机梯度下降法的一大缺点是,你会失去所有向量化带给你的加速,因为一次性只处理了一个训练样本,这样效率过于低下,所以实践中最好选择不大不小的 mini-batch 尺寸,实际上学习率达到最快。你会发现两个好处,一方面,你得到了大量向量化,上个视频中我们用过的例子中,如果 mini-batch 大小为1000 个样本,你就可以对 1000 个样本向量化,比你一次性处理多个样本快得多。另一方面,你不需要等待整个训练集被处理完就可以开始进行后续工作,再用一下上个视频的数字,每次训练集允许我们采取 5000 个梯度下降步骤,所以实际上一些位于中间的 mini-batch 大小效果最好。

在这里插入图片描述
用 mini-batch 梯度下降法,我们从这里开始,一次迭代这样做,两次,三次,四次,它不会总朝向最小值靠近,但它比随机梯度下降要更持续地靠近最小值的方向,它也不一定在很小的范围内收敛或者波动,如果出现这个问题,可以慢慢减少学习率,我们在下个视频会讲到学习率衰减,也就是如何减小学习率。

如果 mini-batch 大小既不是 1 也不是𝑚,应该取中间值,那应该怎么选择呢?其实是有指导原则的。

首先,如果训练集较小,直接使用 batch 梯度下降法,样本集较小就没必要使用 minibatch 梯度下降法,你可以快速处理整个训练集,所以使用 batch 梯度下降法也很好,这里的少是说小于 2000 个样本,这样比较适合使用 batch 梯度下降法。不然,样本数目较大的话,一般的 mini-batch 大小为 64 到 512,考虑到电脑内存设置和使用的方式,如果 minibatch 大小是 2 的𝑛次方,代码会运行地快一些,64 就是 2 的 6 次方,以此类推,128 是 2 的7 次方,256 是 2 的 8 次方,512 是 2 的 9 次方。所以我经常把 mini-batch 大小设成 2 的次方。在上一个视频里,我的 mini-batch 大小设为了 1000,建议你可以试一下 1024,也就是2 的 10 次方。也有 mini-batch 的大小为 1024,不过比较少见,64 到 512 的 mini-batch 比较常见。

最后需要注意的是在你的 mini-batch 中,要确保𝑋{𝑡}和𝑌{𝑡}要符合 CPU/GPU 内存,取决于你的应用方向以及训练集的大小。如果你处理的 mini-batch 和 CPU/GPU 内存不相符,不管你用什么方法处理数据,你会注意到算法的表现急转直下变得惨不忍睹,所以我希望你对一般人们使用的 mini-batch 大小有一个直观了解。事实上 mini-batch 大小是另一个重要的变量,你需要做一个快速尝试,才能找到能够最有效地减少成本函数的那个,我一般会尝试几个不同的值,几个不同的 2 次方,然后看能否找到一个让梯度下降优化算法最高效的大小。希望这些能够指导你如何开始找到这一数值。

你学会了如何执行 mini-batch 梯度下降,令算法运行得更快,特别是在训练样本数目较大的情况下。不过还有个更高效的算法,比梯度下降法和 mini-batch 梯度下降法都要高效的多,我们在接下来的视频中将为大家一一讲解。

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

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

相关文章

07-Fortran基础--Fortran指针(Pointer)的使用

07-Fortran基础--Fortran指针Pointer的使用 0 引言1 指针(Poionter)的有关内容1.1 一般类型指针1.2 数组指针1.3 派生类(type)指针1.4 函数指针 2 可运行code 0 引言 Fortran是一种广泛使用的编程语言,特别适合科学计算和数值分析。Fortran 9…

【设计模式】JAVA Design Patterns——Abstract-document(抽象文档模式)

🔍 目的 使用动态属性,并在保持类型安全的同时实现非类型化语言的灵活性。 🔍 解释 抽象文档模式使您能够处理其他非静态属性。 此模式使用特征的概念来实现类型安全,并将不同类的属性分离为一组接口 真实世界例子 考虑由多个部…

指针在函数的应用(C++)

一、传递地址 实参传递进函数体内后,生成的是实参的副本,在函数内改变副本的值并不影响实参。指针传递参数时,指针变量产生了副本,但副本与原变量指向的内存区域是同一个。改变指针副本指向的变量,就是改变原指针变量指…

Java 插入数据到Elasticsearch中进行各种类型文档的内容检索

源码下载&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1D3yszkTzjwQz0vFRozQl2g?pwdz6kb 提取码&#xff1a;z6kb 实现思路 1.搭建一个新的springboot项目&#xff0c;不会的请看我这篇博客&#xff1a;springboot项目搭建 2.添加maven依赖 <dependency><…

项目管理-案例重点知识(成本管理)

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 三、成本管理 案例重点 成本管理 案例重点内容&#xff1a; &#xff08;1&#xff09;成本管理计划内容 &#xff08;2&#xff09;估算…

汇聚荣科技:拼多多上架商品后需要做页面推广吗?

在电商平台上&#xff0c;商品的曝光率和销量往往成正比。那么&#xff0c;当您在拼多多上架了新品&#xff0c;是不是就意味着坐等订单呢?答案显然是否定的。商品一旦上架&#xff0c;接下来需要做的就是通过有效的页面推广来增加商品的可见度&#xff0c;吸引潜在买家的注意…

23.HashMap的put方法流程

一、put方法的流程图 二、put方法的执行步骤 首先&#xff0c;根据key值计算哈希值。然后判断table数组是否为空或者数组长度是否为0&#xff0c;是的话则要扩容&#xff0c;resize&#xff08;&#xff09;。接着&#xff0c;根据哈希值计算数组下标。如果这个下标位置为空&a…

fastadmin对登录token的处理

fastadmin对token的操作 最近开发遇到一个场景&#xff0c;需要绕过验证获取登录&#xff0c;所以恶补了一下这个知识点&#xff0c;这个主要就是控制fastadmin的token的问题 代码分步实现 class Xcxuser extends Api {//关于鉴权protected $noNeedLogin [login,getopenid,…

踩坑小结:Linux安装python环境 、安装OpenSSL

一、查看python版本 查看发现&#xff0c;linux上自带了python&#xff0c;不过是2.x版本的。 二、下载python3 2.1 下载 www.python.org/downloads/s… 可在当前目录下找到相对应的版本或者最新版本下载 也可以直接下载 Python 3.10.4 下载完在服务器上选择一个目录存放…

ffmpeg使用xfade的转场特效

ffmpeg使用xfade的转场特效 1. 介绍2. ffmpeg里面的xfade3. 使用 1. 介绍 参考文档 ffmpeg是一个音视频编辑工具&#xff0c;具体的。。。。我才搞接触&#xff0c;所以不懂。 xfade是一种视频转场滤镜&#xff0c;用于在两个视频片段之间创建平滑的过渡效果。xfade的转场效果…

扭亏为盈的赛力斯,真正进入稳态了吗?

“72小时内大定破1万台”。5月15日&#xff0c;问界新M5开启全国大规模交付&#xff0c;从当前取得的成绩来看&#xff0c;赛力斯的“富贵”似乎还将延续。 其实&#xff0c;此前基于问界新M7等车型的爆火&#xff0c;赛力斯已经找到了创收轨道。财报显示&#xff0c;2024年一…

戒烟网站|基于SSM+vue的戒烟网站系统的设计与实现(源码+数据库+文档)

戒烟网站 目录 基于SSM&#xff0b;vue的戒烟网站系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1网站功能模块 2管理员功能模块 3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主…

每日5题Day3 - LeetCode 11 - 15

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int maxArea(int[] height) {//这道题比较特殊&#xff0c;因为两边是任意…

OPC-UA open62541 C++测试代码

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 这是之前写的open62541测试代码…

电脑版的学浪课程下载方法

想在你的电脑上无限制地访问你最爱的学浪课程吗&#xff1f;现在&#xff0c;让我揭秘如何用几个简单步骤&#xff0c;轻松下载任何学浪课程到你的电脑&#xff0c;让学习不再受时间和地点的限制&#xff0c;随时随地都是你的课堂。 下载学浪视频的工具&#xff0c;我已经打包…

计算机网络实验3:路由器安全防控配置

实验目的和要求 理解标准IP访问控制列表的原理及功能理解CHAP、DHCP配置原理了解家用式无线路由配置方法实验项目内容 标准IP访问控制列表配置 CHAP验证路由器上配置DHCP网络地址转换NAT配置无线路由实现实验环境 1. 硬件&#xff1a;PC机&#xff1b; 2. 软件&#xff1a;W…

SQL复习

SQL基础 包括&#xff1a; 数据查询&#xff1a;SELECT数据定义语言&#xff1a;CREATE、ALTER和DROP数据操纵语言&#xff1a;INSERT、UPDATE、DELETE数据控制语言&#xff1a;GRANT、REVOKE 特点&#xff1a; 综合统一高度非过程化面向集合既是独立的也是嵌入式语言 三…

垃圾分类管理系统java项目

文章目录 垃圾分类管理系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目&#xff08;9.9&#xffe5;带走&#xff09; 垃圾分类管理系统 一、项目演示 垃圾分类管理系统 二、项目介绍 系统角色&#xff1a;管理员、用户 1、登录、注册功能…

【Arduino】Free RTOS系统

目录 1、任务创建 2、任务删除 3、延迟函数 4、示例&#xff1a; ESP32的SDK包中内置了FreeRTOS&#xff0c;在FreeRTOS中&#xff0c;线程&#xff08;Thread&#xff09;和任务&#xff08;Task&#xff09;的概念是相同的。每个任务就是一个线程&#xff0c;有着自己的一…

Go框架三件套:Gorm的基本操作

1.概述 这里的Go框架三件套是指 Web、RPC、ORM框架&#xff0c;具体如下: Gorm框架 gorm框架是一个已经迭代了10年的功能强大的ORM框架&#xff0c;在字节内部被广泛使用并且拥有非常丰富的开源扩展。 Kitex框架 Kitex是字节内部的Golang微服务RPC框架&#xff0c;具有高性能…