【深度学习】吴恩达课程笔记(四)——优化算法

news2024/11/19 17:41:19

笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~

【吴恩达课程笔记专栏】
【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础
【深度学习】吴恩达课程笔记(二)——浅层神经网络、深层神经网络
【深度学习】吴恩达课程笔记(三)——参数VS超参数、深度学习的实践层面

吴恩达课程笔记——优化算法

  • 优化算法介绍
  • 批量梯度下降(Batch Gradient Descent)
    • 目的
    • 步骤
    • 优点
    • 缺点
  • 随机梯度下降(Stochastic Gradient Descent, SGD)
    • 目的
    • 步骤
    • 优点
    • 缺点
  • 小批量梯度下降(Mini-batch Gradient Descent)
    • 目的
    • 步骤
    • 优点
    • 缺点
    • 理解
    • 如何选择mini-batch size
  • 指数加权平均数(Exponentially Weighted Averages)
    • 目的
    • 步骤
    • 优点
    • 缺点
    • 具体加权过程举例
  • 指数加权平均的偏差修正
  • 动量梯度下降法 (Gradient descent of Momentum)
    • 目的
    • 基本原理
  • RMSprop
    • 目的
    • 优点
    • 基本原理
  • Adam 优化算法(Adam optimization algorithm)
    • 简介
    • 工作方式
    • 优点
    • 算法
  • 学习率衰减(Learning rate decay)
    • 做法
    • 几种公式
  • 局部最优问题
  • Adam 优化算法(Adam optimization algorithm)
    • 简介
    • 工作方式
    • 优点
    • 算法
  • 学习率衰减(Learning rate decay)
    • 做法
    • 几种公式
  • 局部最优问题

优化算法介绍

当涉及深度学习优化算法时,我们通常会面临一个目标:最小化一个损失函数。这个损失函数衡量了模型预测与实际值之间的差距。为了找到最佳的模型参数,我们需要使用优化算法来调整这些参数,以便最小化损失函数。

以下是一些常用的深度学习优化算法:

  1. 梯度下降(Gradient Descent):通过计算成本函数相对于参数的梯度,并沿着梯度的反方向更新参数,以最小化成本函数。
  2. 随机梯度下降(Stochastic Gradient Descent, SGD):与梯度下降类似,但是每次迭代中只使用一个样本来计算梯度,这在大型数据集上更有效。
  3. 小批量梯度下降(Mini-batch Gradient Descent):结合了批量梯度下降和随机梯度下降的优点,每次迭代使用一小批样本来计算梯度。
  4. 指数加权平均数( Exponentially weighted averages):常用于计算梯度的指数加权平均或者计算参数的指数加权平均。
  5. 动量梯度下降法 (Gradient descent of Momentum) :梯度下降算法的一种改进版本,它结合了梯度下降和动量的概念。
  6. RMSProp:通过考虑梯度的平方的指数衰减平均值来调整学习率,以应对Adagrad的学习率急剧下降问题。
  7. Adam 优化算法(Adam optimization algorithm) :在训练神经网络时有效地调整参数,并能够适应不同参数的变化情况,结合了动量梯度下降法和RMSProp算法。
  8. 学习率衰减(Learning rate decay) :在训练神经网络时逐渐降低学习率的过程。

这些算法都有各自的优劣势,适用于不同类型的深度学习任务。在实际应用中,通常需要根据具体问题和数据集的特点来选择合适的优化算法。

批量梯度下降(Batch Gradient Descent)

目的

批量梯度下降是为了优化模型参数,使得损失函数达到最小值,从而实现训练数据的拟合和模型的泛化能力。

步骤

  1. 初始化参数:随机初始化模型参数或采用预训练的参数作为初始值。

  2. 对于整个训练样本集合进行如下操作

    • 计算梯度:计算损失函数关于所有训练样本的参数的梯度,即
      ∇ J ( θ ) = 1 m ∑ i = 1 m ∇ J ( θ ; x ( i ) , y ( i ) ) \nabla J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \nabla J(\theta; x^{(i)}, y^{(i)}) J(θ)=m1i=1mJ(θ;x(i),y(i))

    • 更新参数:利用所有训练样本的梯度信息,按照梯度下降的更新规则来更新模型参数:
      θ = θ − η ⋅ ∇ J ( θ ) \theta = \theta - \eta \cdot \nabla J(\theta) θ=θηJ(θ)
      其中, ( η ) 是学习率, ( m ) 是训练样本的数量。

优点

  • 可以保证收敛性,即在合理的学习率下,批量梯度下降一定可以找到全局最优解或局部最优解。

缺点

  • 当训练样本很大时,计算所有训练样本的梯度会非常耗时,尤其在内存有限的情况下。
  • 对于大规模数据集,批量梯度下降的计算效率较低。

随机梯度下降(Stochastic Gradient Descent, SGD)

目的

随机梯度下降(Stochastic Gradient Descent, SGD)是梯度下降法的一种变种

通过每次迭代仅利用单个训练样本的梯度信息,来更新模型参数,从而减少计算开销,并加快收敛速度。

步骤

  1. 初始化参数:随机初始化模型参数或采用预训练的参数作为初始值。

  2. 对于每个训练样本 (x(i), y(i)) 进行如下操作

    • 计算梯度:计算损失函数关于当前样本的参数的梯度,即

      ∇ J ( θ ; x ( i ) , y ( i ) ) \nabla J(\theta; x^{(i)}, y^{(i)}) J(θ;x(i),y(i))

    • 更新参数:利用当前样本的梯度信息,按照梯度下降的更新规则来更新模型参数:

      θ = θ − η ⋅ ∇ J ( θ ; x ( i ) , y ( i ) ) \theta = \theta - \eta \cdot \nabla J(\theta; x^{(i)}, y^{(i)}) θ=θηJ(θ;x(i),y(i))

      其中,( η )是学习率。

优点

  • 减少计算开销:由于每次仅利用单个样本来更新参数,相比批量梯度下降,SGD在计算上更为高效。
  • 适用于大规模数据集:特别适用于大规模数据集,因为每次迭代只需要处理一个样本。

缺点

  • 不稳定性:由于每次迭代仅利用单个样本,使得更新方向带有较大的随机性,可能导致收敛过程不稳定。
  • 学习率调整困难:学习率的选择对于SGD的影响较大,需要谨慎调整。

小批量梯度下降(Mini-batch Gradient Descent)

目的

小批量梯度下降是为了优化模型参数,使得损失函数达到最小值,从而实现训练数据的拟合和模型的泛化能力。

步骤

  1. 初始化参数:随机初始化模型参数或采用预训练的参数作为初始值。

  2. 对于每个小批量样本(x(i), y(i)) 进行如下操作

    • 计算梯度:计算损失函数关于当前小批量样本的参数的梯度,即
      1 m ∑ i = 1 m ∇ J ( θ ; x ( i ) , y ( i ) ) \frac{1}{m} \sum_{i=1}^{m} \nabla J(\theta; x^{(i)}, y^{(i)}) m1i=1mJ(θ;x(i),y(i))

    • 更新参数:利用当前小批量样本的梯度信息,按照梯度下降的更新规则来更新模型参数:
      θ = θ − η ⋅ 1 m ∑ i = 1 m ∇ J ( θ ; x ( i ) , y ( i ) ) \theta = \theta - \eta \cdot \frac{1}{m} \sum_{i=1}^{m} \nabla J(\theta; x^{(i)}, y^{(i)}) θ=θηm1i=1mJ(θ;x(i),y(i))
      其中, ( η ) 是学习率, ( m ) 是小批量样本的大小。

优点

  • 小批量梯度下降结合了梯度下降和随机梯度下降的优点,可以更快地收敛到局部最优解。
  • 可以充分利用矩阵运算的并行性,提高计算效率。

缺点

  • 需要调节的超参数更多,如学习率 ( η ) 和小批量样本的大小 ( m )。
  • 需要对数据进行分批处理,增加了实现的复杂性。

理解

定义梯度下降时使用一次全部样本集合为一代

  1. batch梯度下降的 J 会不断下降;mini-batch梯度下降的 J 不一定会不断下降,但是整体呈现下降趋势。

在这里插入图片描述

  1. 两者都需要多次遍历全部数据集才会有效果。在mini-batch中,如果只经历一代,那么梯度下降的效果虽然比batch一代好,但总体效果仍是微小的。

  2. 使用mini-batch时,每重新开始遍历一次数据集,应当把数据集中的数据重新打乱分配到mini-batch中,体现出随机性

如何选择mini-batch size

  1. 小训练集:使用batch gradient decent(m less than 2000)
  2. 通常的minibatch size:64、128、256、512、1024

指数加权平均数(Exponentially Weighted Averages)

目的

指数加权平均数用于对时间序列数据进行平滑处理,以便观察数据的长期趋势。

步骤

假设给定一个序列 ( x1, x2, …, xt ),其指数加权平均数 ( vt ) 的计算方式为:

v t = β v t − 1 + ( 1 − β ) x t v_t = \beta v_{t-1} + (1-\beta) x_t vt=βvt1+(1β)xt
( 0 < 𝛽 < 1 ) 被称为平滑因子,较大的平滑因子意味着新观测值对平均数的影响更大,从而使得平均数更快地适应最新的观测值;而较小的平滑因子则意味着平均数更加稳定、更不容易受到新观测值的影响。

( v0 ) 可以被初始化为 0 或者 x1 ,为了在开始时确定初始的指数加权平均数值

优点

  • 对不同时刻的数据赋予不同的权重,更加灵活地适应数据变化。
  • 计算高效,每次更新只需要一次乘法和一次加法运算。

缺点

  • 对于某些特定类型的数据,可能对异常值(outliers)过于敏感,从而影响平均值的准确性。

具体加权过程举例

在这里插入图片描述
假设英国去年第t天的气温是θt
在这里插入图片描述
要用一条曲线拟合温度变化,可以进行如下操作
v 0 = 0 v t = β v t − 1 + ( 1 − β ) θ t v_0=0 \\ v_t=\beta v_{t-1}+(1-\beta)\theta_t v0=0vt=βvt1+(1β)θt

其中 vt 是第t天附近的 1/(1-𝛽) 天的平均天气。

为什么这么规定?

( 1 − ε ) 1 / ε 约等于 1 e (数学中一个挺重要的数) 这说明 1 1 − β 天之外的数所占的权重总共不到 1 e ,不那么值得关注了 (1-ε)^{1/ε}约等于\frac{1}{e}(数学中一个挺重要的数)\\ 这说明\frac{1}{1-\beta}天之外的数所占的权重总共不到\frac{1}{e},不那么值得关注了 1ε1/ε约等于e1(数学中一个挺重要的数)这说明1β1天之外的数所占的权重总共不到e1,不那么值得关注了

β = 0.9 ( 1 − 0.1 ) 1 0.1 = 0. 9 10 β = 0.98 ( 1 − 0.02 ) 1 0.02 = 0.9 8 50 \beta = 0.9\\ (1-0.1)^{\frac{1}{0.1}} = 0.9^{10} \\ \beta = 0.98 \\ (1-0.02)^{\frac{1}{0.02}} = 0.98^{50} β=0.9(10.1)0.11=0.910β=0.98(10.02)0.021=0.9850

可以看出 𝛽 越大,平均的天数越大,拟合得越粗略。
在这里插入图片描述
红色:𝛽=0.9;绿色:𝛽=0.98

指数加权平均的偏差修正

在这里插入图片描述
由于v0=0,v1=𝛽 v0 + (1-𝛽) θ1 = (1-𝛽)θ1,前几个vi的值会非常的小,如图中紫线。当迭代到一定数量之后,拟合才变得正常(紫线逼近绿线)。

偏差修正的目的是为了消除初始时刻的平均值对整体平均值的影响。偏差修正可以通过以下公式实现:
v t ^ = v t 1 − α t v t ^ 表示经过偏差修正后的平均值 v t 表示未经修正的平均值 β 为平滑因子 t 表示时间步 \hat{v_t} = \frac{v_t}{1 - \alpha^t} \\ \hat{v_t} 表示经过偏差修正后的平均值\\ v_t 表示未经修正的平均值\\ \beta 为平滑因子\\ t 表示时间步\\ vt^=1αtvtvt^表示经过偏差修正后的平均值vt表示未经修正的平均值β为平滑因子t表示时间步
通过偏差修正,可以有效地减小最初几个数据点对平均值的影响,得到更加准确和稳定的指数加权平均值。

动量梯度下降法 (Gradient descent of Momentum)

目的

加速梯度下降过程

基本原理

传统的梯度下降法在更新参数时只考虑当前的梯度值,而动量梯度下降法引入了一个额外的动量项,用于模拟物理中的动量效应。

在每次参数更新时,动量梯度下降法会根据当前梯度和上一次的动量来计算一个更新量,并将该更新量应用于参数。更新量由两部分组成:一部分是当前梯度的方向,另一部分是上一次动量的方向。
在这里插入图片描述
蓝线是一般梯度下降的成本函数值迭代情况,红线是动量梯度下降法中成本函数迭代境况。

我们使用指数加权平均来计算新的dW和db。在竖直方向上,由于平均值接近0,所以动量梯度下降的竖直方向迭代值接近0 。在水平方向上,动量梯度下降的迭代值则为正常水平。
d w = β ⋅ d w t − 1 + ( 1 − β ) ⋅ ∂ J ∂ w d b = β ⋅ d b t − 1 + ( 1 − β ) ⋅ ∂ J ∂ b w = w − α ⋅ d w b = b − α ⋅ d b dw = \beta \cdot dw_{t-1} + (1 - \beta) \cdot \frac{\partial J}{\partial w}\\ db = \beta \cdot db_{t-1} + (1 - \beta) \cdot \frac{\partial J}{\partial b}\\ w = w - \alpha \cdot dw\\ b = b - \alpha \cdot db\\ dw=βdwt1+(1β)wJdb=βdbt1+(1β)bJw=wαdwb=bαdb

β 是动量系数 , 通常取 0.9 α 是学习率 J 是损失函数 d w t − 1 和 d b t − 1 表示上一次的权重和偏置更新量 ∂ J ∂ w 和 ∂ J ∂ b 分别是损失函数对权重和偏置的偏导数 w 和 b 分别表示更新后的权重和偏置 \beta 是动量系数,通常取0.9\\ \alpha 是学习率\\ J 是损失函数\\ dw_{t-1} 和 db_{t-1} 表示上一次的权重和偏置更新量\\ \frac{\partial J}{\partial w} 和 \frac{\partial J}{\partial b} 分别是损失函数对权重和偏置的偏导数\\ w 和 b 分别表示更新后的权重和偏置 β是动量系数,通常取0.9α是学习率J是损失函数dwt1dbt1表示上一次的权重和偏置更新量wJbJ分别是损失函数对权重和偏置的偏导数wb分别表示更新后的权重和偏置

RMSprop

目的

解决传统梯度下降法中学习率衰减过快的问题。RMSprop通过对梯度的平方进行指数加权移动平均来调整学习率,从而加速模型的训练。

优点

使用它的时候可以适当加大学习率

基本原理

在这里插入图片描述
如图,我们不想要绿线,而想要蓝线。

我们需要计算一个额外变量S,S等于目前数据附近水平方向或竖直方向的dX的方差。

我们在更新数据(W、b)的时候,把原来要减掉的dX除以这个方差,那么方差大的方向变化量就减少,方差小的方向变化量就仍处于正常水平甚至增大。

Adam 优化算法(Adam optimization algorithm)

简介

adam是训练神经网络中最有效的优化算法之一。它结合了momentum和RMSprop。

工作方式

  1. 计算上一个梯度的指数加权平均,存储在v中。
  2. 计算上一个梯度指数加权平均的平方,存储在s中。
  3. 使用adam的规则更新参数。

优点

  1. 通常比较节省内存(尽管还是比GD和momentum多)
  2. 即使在低学习率条件下也能运行得很好

算法

{ v d W [ l ] = β 1 v d W [ l ] + ( 1 − β 1 ) ∂ J ∂ W [ l ] v d W [ l ] c o r r e c t e d = v d W [ l ] 1 − ( β 1 ) t s d W [ l ] = β 2 s d W [ l ] + ( 1 − β 2 ) ( ∂ J ∂ W [ l ] ) 2 s d W [ l ] c o r r e c t e d = s d W [ l ] 1 − ( β 1 ) t W [ l ] = W [ l ] − α v d W [ l ] c o r r e c t e d s d W [ l ] c o r r e c t e d + ε l = 1 , . . . , L \begin{cases} v_{dW^{[l]}} = \beta_1 v_{dW^{[l]}} + (1 - \beta_1) \frac{\partial \mathcal{J} }{ \partial W^{[l]} } \\ v^{corrected}_{dW^{[l]}} = \frac{v_{dW^{[l]}}}{1 - (\beta_1)^t} \\ s_{dW^{[l]}} = \beta_2 s_{dW^{[l]}} + (1 - \beta_2) (\frac{\partial \mathcal{J} }{\partial W^{[l]} })^2 \\ s^{corrected}_{dW^{[l]}} = \frac{s_{dW^{[l]}}}{1 - (\beta_1)^t} \\ W^{[l]} = W^{[l]} - \alpha \frac{v^{corrected}_{dW^{[l]}}}{\sqrt{s^{corrected}_{dW^{[l]}}} + \varepsilon} \end{cases} \\ l = 1, ..., L vdW[l]=β1vdW[l]+(1β1)W[l]JvdW[l]corrected=1(β1)tvdW[l]sdW[l]=β2sdW[l]+(1β2)(W[l]J)2sdW[l]corrected=1(β1)tsdW[l]W[l]=W[l]αsdW[l]corrected +εvdW[l]correctedl=1,...,L
其中:

  • t是adam进行到的步数
  • L是神经网络的层数
  • 𝛽1(建议使用0.9)和 𝛽2(建议使用0.999)是控制两个指数加权平均的
  • α 是学习率
  • ε 是一个用来放置分母为0的值很小的数

学习率衰减(Learning rate decay)

做法

在不同的代(epoch)上使用递减的学习率

几种公式

α = 1 1 + d e c a y r a t e ∗ e p o c h n u m ∗ α 0 α = a e p o c h n u m ∗ α 0 α = k e p o c h n u m ∗ α 0 手动调整 α 的值 \alpha=\frac{1}{1+decayrate*epochnum}*\alpha_0 \\ \alpha=a^{epochnum}*\alpha_0 \\ \alpha=\frac{k}{\sqrt{epochnum}}*\alpha_0 \\ 手动调整\alpha的值 α=1+decayrateepochnum1α0α=aepochnumα0α=epochnum kα0手动调整α的值

局部最优问题

  1. 在神经网络规模较大、参数较多的时候,实际上很难达到局部最优点,更有可能达到的是鞍点。因此梯度下降被困在局部最优点不是很大的问题。
  2. 鞍点会减缓学习速度,而momentum、RMSprop、Adam正式可以解决这种问题

如图,我们不想要绿线,而想要蓝线。

我们需要计算一个额外变量S,S等于目前数据附近水平方向或竖直方向的dX的方差。

我们在更新数据(W、b)的时候,把原来要减掉的dX除以这个方差,那么方差大的方向变化量就减少,方差小的方向变化量就仍处于正常水平甚至增大。

Adam 优化算法(Adam optimization algorithm)

简介

adam是训练神经网络中最有效的优化算法之一。它结合了momentum和RMSprop。

工作方式

  1. 计算上一个梯度的指数加权平均,存储在v中。
  2. 计算上一个梯度指数加权平均的平方,存储在s中。
  3. 使用adam的规则更新参数。

优点

  1. 通常比较节省内存(尽管还是比GD和momentum多)
  2. 即使在低学习率条件下也能运行得很好

算法

{ v d W [ l ] = β 1 v d W [ l ] + ( 1 − β 1 ) ∂ J ∂ W [ l ] v d W [ l ] c o r r e c t e d = v d W [ l ] 1 − ( β 1 ) t s d W [ l ] = β 2 s d W [ l ] + ( 1 − β 2 ) ( ∂ J ∂ W [ l ] ) 2 s d W [ l ] c o r r e c t e d = s d W [ l ] 1 − ( β 1 ) t W [ l ] = W [ l ] − α v d W [ l ] c o r r e c t e d s d W [ l ] c o r r e c t e d + ε l = 1 , . . . , L \begin{cases} v_{dW^{[l]}} = \beta_1 v_{dW^{[l]}} + (1 - \beta_1) \frac{\partial \mathcal{J} }{ \partial W^{[l]} } \\ v^{corrected}_{dW^{[l]}} = \frac{v_{dW^{[l]}}}{1 - (\beta_1)^t} \\ s_{dW^{[l]}} = \beta_2 s_{dW^{[l]}} + (1 - \beta_2) (\frac{\partial \mathcal{J} }{\partial W^{[l]} })^2 \\ s^{corrected}_{dW^{[l]}} = \frac{s_{dW^{[l]}}}{1 - (\beta_1)^t} \\ W^{[l]} = W^{[l]} - \alpha \frac{v^{corrected}_{dW^{[l]}}}{\sqrt{s^{corrected}_{dW^{[l]}}} + \varepsilon} \end{cases} \\ l = 1, ..., L vdW[l]=β1vdW[l]+(1β1)W[l]JvdW[l]corrected=1(β1)tvdW[l]sdW[l]=β2sdW[l]+(1β2)(W[l]J)2sdW[l]corrected=1(β1)tsdW[l]W[l]=W[l]αsdW[l]corrected +εvdW[l]correctedl=1,...,L
其中:

  • t是adam进行到的步数
  • L是神经网络的层数
  • 𝛽1(建议使用0.9)和 𝛽2(建议使用0.999)是控制两个指数加权平均的
  • α 是学习率
  • ε 是一个用来放置分母为0的值很小的数

学习率衰减(Learning rate decay)

做法

在不同的代(epoch)上使用递减的学习率

几种公式

α = 1 1 + d e c a y r a t e ∗ e p o c h n u m ∗ α 0 α = a e p o c h n u m ∗ α 0 α = k e p o c h n u m ∗ α 0 手动调整 α 的值 \alpha=\frac{1}{1+decayrate*epochnum}*\alpha_0 \\ \alpha=a^{epochnum}*\alpha_0 \\ \alpha=\frac{k}{\sqrt{epochnum}}*\alpha_0 \\ 手动调整\alpha的值 α=1+decayrateepochnum1α0α=aepochnumα0α=epochnum kα0手动调整α的值

局部最优问题

  1. 在神经网络规模较大、参数较多的时候,实际上很难达到局部最优点,更有可能达到的是鞍点。因此梯度下降被困在局部最优点不是很大的问题。
  2. 鞍点会减缓学习速度,而momentum、RMSprop、Adam正式可以解决这种问题

在这里插入图片描述

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

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

相关文章

如何从 iCloud 恢复永久删除的照片?答案在这里!

在数字时代&#xff0c;丢失珍贵的照片可能会令人痛苦。然而&#xff0c;了解如何从 iCloud 恢复永久删除的照片可以带来一线希望。无论是意外删除还是技术故障&#xff0c;本指南都提供了 2023 年的最新方法来找回您的珍贵记忆。发现分步解决方案并轻松重新访问您的照片库。不…

智能供应链中的预测算法:理论与实践

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 引言 智能供应链已经成…

制作属于你的视觉小说,ComfyUI工作流#N3期AIGC训练营

什么是视觉小说&#xff1f; Visual Novel 最初这种形式被称为“有声小说” 视觉小说是一种源自日本的电子游戏类型&#xff0c;它以图像和文本为主要表现形式&#xff0c;通常包含大量的对话和故事情节。 &#xff08;大量对话&#xff09; 在视觉小说中&#xff0c;玩家可以通…

AJAX入门Day01笔记

Day01_Ajax入门 知识点自测 如下对象取值的方式哪个正确? let obj {name: 黑马 }A: obj.a B: obj()a 答案 A选项正确 哪个赋值会让浏览器解析成标签显示? let ul document.querySelector(#ul) let str <span>我是span标签</span>A: ul.innerText str B: ul…

HTML+CSS+JavaScript实战(一个简易的视频播放器)

效果如下&#xff1a; 思路很常规&#xff0c;无需注释即可看懂&#xff08;其实是懒得敲 bushi&#xff09; 没有注释也能跑&#xff0c;so直接上源码~ 感谢 夏柔站长 提供的免费API index.html <!DOCTYPE html> <html lang"en"> <head><meta …

UE4动作游戏实例RPG Action解析三:实现效果,三连击Combo,射线检测,显示血条,火球术

一、三连Combo 实现武器三连击,要求: 1.下一段Combo可以随机选择, 2.在一定的时机才能再次检测输入 3. 等当前片段播放完才播放下一片段 1.1、蒙太奇设置 通过右键-新建蒙太奇片段,在蒙太奇里创建三个片段,并且移除相关连接,这样默认只会播放第一个片段 不同片段播…

一分钟搞懂什么是this指针(未涉及静态成员和函数)

前言 我们在学习类的过程中&#xff0c;一定听说过this指针&#xff0c;但是并不知道它跟谁相似&#xff0c;又有什么用途&#xff0c;所以接下来&#xff0c;让我们一起去学习this指针吧&#xff01; 一、this指针的引入 我们先来看下面两段代码&#xff0c;它们输出的是什么&…

Rust实战教程:构建您的第一个应用

大家好&#xff01;我是lincyang。 今天&#xff0c;我们将一起动手实践&#xff0c;通过构建一个简单的Rust应用来深入理解这门语言。 我们的项目是一个命令行文本文件分析器&#xff0c;它不仅能读取和显示文件内容&#xff0c;还会提供一些基础的文本分析&#xff0c;如计算…

C# Onnx 轻量实时的M-LSD直线检测

目录 介绍 效果 效果1 效果2 效果3 效果4 模型信息 项目 代码 下载 其他 介绍 github地址&#xff1a;https://github.com/navervision/mlsd M-LSD: Towards Light-weight and Real-time Line Segment Detection Official Tensorflow implementation of "M-…

什么是Vue.js中的单向数据流(one-way data flow)?为什么它重要?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

【QT系列教程】之二创建项目和helloworld案例

文章目录 一、QT创建项目1.1、创建项目1.2、选择创建项目属性1.3、选择路径和项目名称1.4、选择构建项目类型1.5、布局方式1.6、翻译文件&#xff0c;根据自己需求选择1.7、选择套件1.8、项目管理&#xff0c;自行配置1.9、配置完成&#xff0c;系统自动更新配置 二、QT界面介绍…

图论16-拓扑排序

文章目录 1 拓扑排序2 拓扑排序的普通实现2.1 算法实现 - 度数为0入队列2.2 拓扑排序中的环检测 3 深度优先遍历的后续遍历3.1 使用环检测类先判断是否有环3.2 调用无向图的深度优先后续遍历方法&#xff0c;进行DFS 1 拓扑排序 对一个有向无环图G进行拓扑排序&#xff0c;是将…

守护 C 盘,Python 相关库设置

前言 pip 安装依赖和 conda 创建环境有多方便&#xff0c;那 C 盘就塞得就有多满。以前我不管使用什么工具&#xff0c;最多就设置个安装位置&#xff0c;其他都是默认。直到最近 C 盘飙红了&#xff0c;我去盘符里的 AppData 里一看&#xff0c;pip 的缓存和 conda 以前创建的…

2023年咨询实务速记突破【专题总结】

需要完整资料的可以联系我获取

matlab语言的由来与发展历程

MATLAB语言的由来可以追溯到1970年代后期。当时&#xff0c;Cleve Moler教授在New Mexico大学计算机系担任系主任&#xff0c;他为了LINPACK和EISPACK两个FORTRAN程序集开发项目提供易学、易用、易改且易交互的矩阵软件而形成了最初的MATLAB。 1984年&#xff0c;MATLAB推出了…

模拟接口数据之使用Mock方法实现(vite)

文章目录 前言一、安装依赖mockjs 安装vite-plugin-mock 安装新增mock脚本 二、vite插件配置vite-plugin-mockvite.config.ts 引入vite-plugin-mock 三、新建mock数据新建mock目录env目录新建.env.mock文件 四、使用mock数据定义接口调用接口 如有启发&#xff0c;可点赞收藏哟…

java 中arrayList 中去除重复项

ArrayList 中去除重复对象 Testpublic void removeRepeatItem() {ArrayList<String> arrayList new ArrayList<>();arrayList.add("apple");arrayList.add("banbana");arrayList.add("apple");arrayList.add("apple");S…

Supervisor管理器

如果宝塔版本是低于 7.9 可以选用supervisor 管理器&#xff0c;宝塔7.9及以上版本此工具可能出BUG&#xff0c;请选择 堡塔应用管理器跳过本页&#xff0c;看堡塔应用管理器 Supervisor 管理器 和 堡塔应用管理器 二选一使用 步骤总结&#xff1a; 一、切换PHP命令行版本和站…

滚雪球学Java(64):LinkedHashSet原理及实现解析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

2.5 Windows驱动开发:DRIVER_OBJECT对象结构

在Windows内核中&#xff0c;每个设备驱动程序都需要一个DRIVER_OBJECT对象&#xff0c;该对象由系统创建并传递给驱动程序的DriverEntry函数。驱动程序使用此对象来注册与设备对象和其他系统对象的交互&#xff0c;并在操作系统需要与驱动程序进行交互时使用此对象。DRIVER_OB…