深入浅出梯度下降算法:快速抵达函数最小值的方法
引言
梯度是机器学习和优化领域中不可或缺的概念,它为我们提供了理解和调整多维空间中函数行为的工具。本文将详细介绍梯度的定义、性质,并通过具体的一元和多元函数案例展示如何使用梯度下降算法找到最佳参数。
一、梯度的基础知识
1.1 定义与计算
梯度是一个向量,表示一个多变量函数在某一点处的最大变化率的方向以及变化率的大小。对于一个可微函数 f ( x 1 , x 2 , . . . , x n ) f(x_1, x_2, ..., x_n) f(x1,x2,...,xn),其梯度 ∇ f \nabla f ∇f 是由各个自变量的偏导数组成的向量:
∇ f = ( ∂ f ∂ x 1 , ∂ f ∂ x 2 , . . . , ∂ f ∂ x n ) \nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n} \right) ∇f=(∂x1∂f,∂x2∂f,...,∂xn∂f)
1.2 梯度的方向
梯度是一个向量,它表示一个多变量函数在某一点处的最大变化率的方向以及变化率的大小。梯度指向的是函数值增加最快的方向。因此,如果我们希望减小函数值,我们应该沿着梯度的反方向移动。这正是梯度下降算法的核心思想。理解梯度的方向对于优化问题至关重要。下面我们将详细展开讨论梯度方向在一元函数、多元函数以及神经网络中的具体表现。
1.2.1 一元函数中的梯度方向
对于一维情况,梯度实际上就是一个标量值,它告诉我们函数在该点是增加还是减少:
- 梯度为正值:如果导数(即梯度) d y d x > 0 \frac{dy}{dx} > 0 dxdy>0,那么函数值随着 x x x 的增加而增加。这意味着梯度指向正方向,即沿着 x x x 轴的正方向移动会使得函数值增大。
- 梯度为负值:如果导数(即梯度) d y d x < 0 \frac{dy}{dx} < 0 dxdy<0,那么函数值随着 x x x 的增加而减小。这意味着梯度指向负方向,即沿着 x x x 轴的负方向移动会使得函数值增大。
- 梯度为零:如果导数(即梯度) d y d x = 0 \frac{dy}{dx} = 0 dxdy=0,那么在这一点上函数值既不增加也不减少,可能是极值点或平稳点。
例如,考虑二次函数 y = x 2 y = x^2 y=x2:
- 在 x > 0 x > 0 x>0 时,梯度为正值( 2 x > 0 2x > 0 2x>0),表明函数在这个区域沿 x x x 正方向增长最快。
- 在 x < 0 x < 0 x<0 时,梯度为负值( 2 x < 0 2x < 0 2x<0),表明函数在这个区域沿 x x x 负方向增长最快。
- 在 x = 0 x = 0 x=0 时,梯度为零,这是全局最小值点。
为了减小 y y y 的值,我们应该沿着梯度的反方向移动:
- 在 x > 0 x > 0 x>0 时,梯度为正值,所以我们应该向左移动(减小 x x x)。
- 在 x < 0 x < 0 x<0 时,梯度为负值,所以我们应该向右移动(增加 x x x)。
- 在 x = 0 x = 0 x=0 时,梯度为零,这里已经是最低点了。
1.2.2 多元函数中的梯度方向
对于多变量函数 f ( x 1 , x 2 , . . . , x n ) f(x_1, x_2, ..., x_n) f(x1,x2,...,xn),梯度是一个向量 ∇ f \nabla f ∇f,由各个自变量的偏导数组成:
∇ f = ( ∂ f ∂ x 1 , ∂ f ∂ x 2 , . . . , ∂ f ∂ x n ) \nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n} \right) ∇f=(∂x1∂f,∂x2∂f,...,∂xn∂f)
梯度指向的是函数值增加最快的方向。因此,如果我们希望减小函数值,我们应该沿着梯度的反方向移动。这同样适用于每个参数的更新:
- 梯度为正向量:如果某个分量 ∂ f ∂ x i > 0 \frac{\partial f}{\partial x_i} > 0 ∂xi∂f>0,那么函数值随着 x i x_i xi 的增加而增加。这意味着梯度在 x i x_i xi 方向上是正的,沿着这个方向移动会使得函数值增大。
- 梯度为负向量:如果某个分量 ∂ f ∂ x i < 0 \frac{\partial f}{\partial x_i} < 0 ∂xi∂f<0,那么函数值随着 x i x_i xi 的增加而减小。这意味着梯度在 x i x_i xi 方向上是负的,沿着这个方向移动会使得函数值增大。
- 梯度为零向量:如果所有分量均为零,那么在这一点上函数值既不增加也不减少,可能是极值点或平稳点。
例如,考虑二维二次函数 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2:
- 在点 ( 1 , 1 ) (1, 1) (1,1),梯度为 ( 2 , 2 ) (2, 2) (2,2),表明从这一点出发,沿 ( 2 , 2 ) (2, 2) (2,2) 方向移动会使 f ( x , y ) f(x, y) f(x,y) 值迅速增大。反方向 ( − 2 , − 2 ) (-2, -2) (−2,−2) 则使 f ( x , y ) f(x, y) f(x,y) 值迅速减小。
- 在点 ( − 1 , − 1 ) (-1, -1) (−1,−1),梯度为 ( − 2 , − 2 ) (-2, -2) (−2,−2),表明从这一点出发,沿 ( − 2 , − 2 ) (-2, -2) (−2,−2) 方向移动会使 f ( x , y ) f(x, y) f(x,y) 值迅速增大。反方向 ( 2 , 2 ) (2, 2) (2,2) 则使 f ( x , y ) f(x, y) f(x,y) 值迅速减小。
- 在点 ( 0 , 0 ) (0, 0) (0,0),梯度为 ( 0 , 0 ) (0, 0) (0,0),这里是全局最小值点,没有明确的增长或减少方向。
1.2.3 神经网络中的梯度方向
在神经网络中,梯度方向用于指导参数(权重和偏置)的更新,以最小化损失函数。梯度本身是一个向量,它指向了损失函数值增加最快的方向。因此,在优化过程中,我们沿着梯度的反方向调整参数,以减小损失函数值。
梯度方向的具体表现
-
权重矩阵 W ( l ) W^{(l)} W(l) 的梯度:
- 对于每一层的权重矩阵 W ( l ) W^{(l)} W(l),其梯度 ∇ W ( l ) L \nabla_{W^{(l)}} L ∇W(l)L 表示该层权重对损失函数的影响。
- 如果某个权重的梯度为正,意味着增加该权重会使损失增大;反之,减少该权重会使损失减小。
- 因此,为了减小损失,我们应沿着梯度的反方向更新权重: W new ( l ) = W old ( l ) − α ⋅ ∇ W ( l ) L W^{(l)}_{\text{new}} = W^{(l)}_{\text{old}} - \alpha \cdot \nabla_{W^{(l)}} L Wnew(l)=Wold(l)−α⋅∇W(l)L
-
偏置向量 b ( l ) b^{(l)} b(l) 的梯度:
- 类似地,对于每一层的偏置向量 b ( l ) b^{(l)} b(l),其梯度 ∇ b ( l ) L \nabla_{b^{(l)}} L ∇b(l)L 表示该层偏置对损失函数的影响。
- 如果某个偏置的梯度为正,意味着增加该偏置会使损失增大;反之,减少该偏置会使损失减小。
- 为了减小损失,我们应沿着梯度的反方向更新偏置: b new ( l ) = b old ( l ) − α ⋅ ∇ b ( l ) L b^{(l)}_{\text{new}} = b^{(l)}_{\text{old}} - \alpha \cdot \nabla_{b^{(l)}} L bnew(l)=bold(l)−α⋅∇b(l)L
反向传播与梯度计算
反向传播算法是计算神经网络中梯度的关键步骤。它通过链式法则逐层计算每个参数对损失函数的影响:
-
输出层:
- 计算输出层误差 δ ( L ) \delta^{(L)} δ(L):
δ ( L ) = a ( L ) − y \delta^{(L)} = a^{(L)} - y δ(L)=a(L)−y - 计算输出层权重和偏置的梯度:
∇ W ( L ) L = δ ( L ) ⋅ ( a ( L − 1 ) ) T \nabla_{W^{(L)}} L = \delta^{(L)} \cdot (a^{(L-1)})^T ∇W(L)L=δ(L)⋅(a(L−1))T
∇ b ( L ) L = δ ( L ) \nabla_{b^{(L)}} L = \delta^{(L)} ∇b(L)L=δ(L)
- 计算输出层误差 δ ( L ) \delta^{(L)} δ(L):
-
隐藏层:
- 计算隐藏层误差 δ ( l ) \delta^{(l)} δ(l):
δ ( l ) = ( δ ( l + 1 ) ⋅ ( W ( l + 1 ) ) T ) ⊙ f ′ ( z ( l ) ) \delta^{(l)} = (\delta^{(l+1)} \cdot (W^{(l+1)})^T) \odot f'(z^{(l)}) δ(l)=(δ(l+1)⋅(W(l+1))T)⊙f′(z(l))
其中 f ′ f' f′ 是激活函数的导数。 - 计算隐藏层权重和偏置的梯度:
∇ W ( l ) L = δ ( l ) ⋅ ( a ( l − 1 ) ) T \nabla_{W^{(l)}} L = \delta^{(l)} \cdot (a^{(l-1)})^T ∇W(l)L=δ(l)⋅(a(l−1))T
∇ b ( l ) L = δ ( l ) \nabla_{b^{(l)}} L = \delta^{(l)} ∇b(l)L=δ(l)
- 计算隐藏层误差 δ ( l ) \delta^{(l)} δ(l):
梯度方向的直观理解
- 权重更新:如果某个权重的梯度为正值,这意味着增加该权重会使损失增大,所以我们应该减小该权重。相反,如果梯度为负值,则应该增加该权重。
- 偏置更新:同样的逻辑适用于偏置,根据梯度的符号调整偏置值,以减小损失。
通过不断的迭代,网络的权重和偏置将逐渐收敛到最优解,从而使损失函数最小化,预测性能最大化。在神经网络中,梯度方向直接指导了参数更新的方向。
总结
无论是处理简单的一元二次函数、复杂的多元函数,还是神经网络中的复杂优化问题,梯度都为我们提供了一条通向最优解的道路。通过了解梯度的方向和反方向,我们可以有效地使用梯度下降算法来找到函数的最低点。每一次迭代中,我们根据当前的损失计算梯度,并沿着梯度的反方向调整参数,最终使模型更好地拟合训练数据。
1.3 梯度下降的一般性公式
梯度下降是一种用于最小化损失函数的迭代优化算法。其核心思想是通过逐步调整参数,使损失函数的值不断减小,直到收敛到局部或全局最小值。梯度下降的基本步骤如下:
- 初始化参数:选择一组初始参数 θ 0 \theta_0 θ0。
- 计算梯度:在当前参数 θ n \theta_n θn 处计算损失函数 J ( θ ) J(\theta) J(θ) 的梯度 ∇ θ J ( θ n ) \nabla_\theta J(\theta_n) ∇θJ(θn)。
- 更新参数:根据梯度的反方向更新参数:
θ n + 1 = θ n − α ⋅ ∇ θ J ( θ n ) \theta_{n+1} = \theta_n - \alpha \cdot \nabla_\theta J(\theta_n) θn+1=θn−α⋅∇θJ(θn)
其中 α \alpha α 是学习率,决定了每次更新步长的大小。 - 重复迭代:重复上述步骤,直到满足某个停止条件(如梯度接近零或达到最大迭代次数)。
梯度下降的具体形式取决于使用的数据集和模型。以下是几种常见的梯度下降变体:
- 批量梯度下降(Batch Gradient Descent):每次迭代使用整个训练集来计算梯度。
- 随机梯度下降(Stochastic Gradient Descent, SGD):每次迭代仅使用一个样本(或一个小批次)来计算梯度,从而加快收敛速度但可能引入更多噪声。
- 小批量梯度下降(Mini-batch Gradient Descent):每次迭代使用一小批样本(通常几十个)来计算梯度,结合了批量和随机梯度下降的优点。
二、一元二次函数的梯度下降
2.1 函数及其导数
考虑简单的二次函数 y = x 2 y = x^2 y=x2。可以计算其导数(即梯度):
d y d x = 2 x \frac{dy}{dx} = 2x dxdy=2x
这个导数告诉我们,在任意点 x x x 处,函数 y y y 的变化率是多少。
2.2 梯度下降的具体过程
假设想找到使 y = x 2 y = x^2 y=x2 最小化的 x x x 值,将使用梯度下降算法来进行优化。
-
初始化:选择初始猜测 x 0 = 3 x_0 = 3 x0=3,学习率 α = 0.1 \alpha = 0.1 α=0.1。
-
迭代过程:按照以下步骤进行迭代:
- 计算梯度:在当前点 x n x_n xn 计算导数: d y d x ( x n ) = 2 x n \frac{dy}{dx}(x_n) = 2x_n dxdy(xn)=2xn
- 更新参数:根据梯度的反方向更新 x x x:
x n + 1 = x n − α ⋅ d y d x ( x n ) x_{n+1} = x_n - \alpha \cdot \frac{dy}{dx}(x_n) xn+1=xn−α⋅dxdy(xn) - 重复:重复上述步骤直到收敛或达到预定的迭代次数。
具体
🌰🌰
-
第一次迭代:
- 当前位置 x 0 = 3 x_0 = 3 x0=3
- 计算梯度: d y d x ( x 0 ) = 2 ∗ 3 = 6 \frac{dy}{dx}(x_0) = 2*3 = 6 dxdy(x0)=2∗3=6
- 更新 x x x: x 1 = x 0 − 0.1 ∗ 6 = 3 − 0.6 = 2.4 x_1 = x_0 - 0.1 * 6 = 3 - 0.6 = 2.4 x1=x0−0.1∗6=3−0.6=2.4
-
第二次迭代:
- 当前位置 x 1 = 2.4 x_1 = 2.4 x1=2.4
- 计算梯度: d y d x ( x 1 ) = 2 ∗ 2.4 = 4.8 \frac{dy}{dx}(x_1) = 2*2.4 = 4.8 dxdy(x1)=2∗2.4=4.8
- 更新 x x x: x 2 = x 1 − 0.1 ∗ 4.8 = 2.4 − 0.48 = 1.92 x_2 = x_1 - 0.1 * 4.8 = 2.4 - 0.48 = 1.92 x2=x1−0.1∗4.8=2.4−0.48=1.92
-
第三次迭代:
- 当前位置 x 2 = 1.92 x_2 = 1.92 x2=1.92
- 计算梯度: d y d x ( x 2 ) = 2 ∗ 1.92 = 3.84 \frac{dy}{dx}(x_2) = 2*1.92 = 3.84 dxdy(x2)=2∗1.92=3.84
- 更新 x x x: x 3 = x 2 − 0.1 ∗ 3.84 = 1.92 − 0.384 = 1.536 x_3 = x_2 - 0.1 * 3.84 = 1.92 - 0.384 = 1.536 x3=x2−0.1∗3.84=1.92−0.384=1.536
随着迭代次数的增加, x x x 将逐渐接近最小值点 x = 0 x = 0 x=0。最终,经过足够多次的迭代, x x x 会非常接近 0,此时 y = x 2 y = x^2 y=x2 达到最小值。
三、多元函数的梯度下降
3.1 函数及其梯度
考虑一个二维二次函数 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2。该函数描述了一个三维空间中的抛物面,顶点位于原点 (0, 0)。其梯度向量为:
∇ f = ( 2 x , 2 y ) \nabla f = (2x, 2y) ∇f=(2x,2y)
3.2 梯度下降的具体过程
假设想找到使 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2 最小化的 x x x 和 y y y 的值,将使用梯度下降算法来进行优化。
-
初始化:选择初始猜测 x 0 = 1 x_0 = 1 x0=1, y 0 = 1 y_0 = 1 y0=1,学习率 α = 0.1 \alpha = 0.1 α=0.1。
-
迭代过程:按照以下步骤进行迭代:
- 计算梯度:在当前点 ( x n , y n ) (x_n, y_n) (xn,yn) 计算梯度 ∇ f ( x n , y n ) = ( 2 x n , 2 y n ) \nabla f(x_n, y_n) = (2x_n, 2y_n) ∇f(xn,yn)=(2xn,2yn)。
- 更新参数:根据梯度的反方向更新 x x x 和 y y y:
x n + 1 = x n − α ⋅ ∂ f ∂ x ( x n , y n ) x_{n+1} = x_n - \alpha \cdot \frac{\partial f}{\partial x}(x_n, y_n) xn+1=xn−α⋅∂x∂f(xn,yn)
y n + 1 = y n − α ⋅ ∂ f ∂ y ( x n , y n ) y_{n+1} = y_n - \alpha \cdot \frac{\partial f}{\partial y}(x_n, y_n) yn+1=yn−α⋅∂y∂f(xn,yn) - 重复:重复上述步骤直到收敛或达到预定的迭代次数。
具体
🌰🌰
-
第一次迭代:
- 当前位置 ( x 0 , y 0 ) = ( 1 , 1 ) (x_0, y_0) = (1, 1) (x0,y0)=(1,1)
- 计算梯度: ∇ f ( x 0 , y 0 ) = ( 2 ∗ 1 , 2 ∗ 1 ) = ( 2 , 2 ) \nabla f(x_0, y_0) = (2*1, 2*1) = (2, 2) ∇f(x0,y0)=(2∗1,2∗1)=(2,2)
- 更新 x x x 和 y y y:
x 1 = x 0 − 0.1 ∗ 2 = 1 − 0.2 = 0.8 x_1 = x_0 - 0.1 * 2 = 1 - 0.2 = 0.8 x1=x0−0.1∗2=1−0.2=0.8
y 1 = y 0 − 0.1 ∗ 2 = 1 − 0.2 = 0.8 y_1 = y_0 - 0.1 * 2 = 1 - 0.2 = 0.8 y1=y0−0.1∗2=1−0.2=0.8
-
第二次迭代:
- 当前位置 ( x 1 , y 1 ) = ( 0.8 , 0.8 ) (x_1, y_1) = (0.8, 0.8) (x1,y1)=(0.8,0.8)
- 计算梯度: ∇ f ( x 1 , y 1 ) = ( 2 ∗ 0.8 , 2 ∗ 0.8 ) = ( 1.6 , 1.6 ) \nabla f(x_1, y_1) = (2*0.8, 2*0.8) = (1.6, 1.6) ∇f(x1,y1)=(2∗0.8,2∗0.8)=(1.6,1.6)
- 更新 x x x 和 y y y:
x 2 = x 1 − 0.1 ∗ 1.6 = 0.8 − 0.16 = 0.64 x_2 = x_1 - 0.1 * 1.6 = 0.8 - 0.16 = 0.64 x2=x1−0.1∗1.6=0.8−0.16=0.64
y 2 = y 1 − 0.1 ∗ 1.6 = 0.8 − 0.16 = 0.64 y_2 = y_1 - 0.1 * 1.6 = 0.8 - 0.16 = 0.64 y2=y1−0.1∗1.6=0.8−0.16=0.64
-
第三次迭代:
- 当前位置 ( x 2 , y 2 ) = ( 0.64 , 0.64 ) (x_2, y_2) = (0.64, 0.64) (x2,y2)=(0.64,0.64)
- 计算梯度: ∇ f ( x 2 , y 2 ) = ( 2 ∗ 0.64 , 2 ∗ 0.64 ) = ( 1.28 , 1.28 ) \nabla f(x_2, y_2) = (2*0.64, 2*0.64) = (1.28, 1.28) ∇f(x2,y2)=(2∗0.64,2∗0.64)=(1.28,1.28)
- 更新 x x x 和 y y y:
x 3 = x 2 − 0.1 ∗ 1.28 = 0.64 − 0.128 = 0.512 x_3 = x_2 - 0.1 * 1.28 = 0.64 - 0.128 = 0.512 x3=x2−0.1∗1.28=0.64−0.128=0.512
y 3 = y 2 − 0.1 ∗ 1.28 = 0.64 − 0.128 = 0.512 y_3 = y_2 - 0.1 * 1.28 = 0.64 - 0.128 = 0.512 y3=y2−0.1∗1.28=0.64−0.128=0.512
随着迭代次数的增加, x x x 和 y y y 将逐渐接近最小值点 ( 0 , 0 ) (0, 0) (0,0)。最终,经过足够多次的迭代, ( x , y ) (x, y) (x,y) 会非常接近 (0, 0),此时 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2 达到最小值。
3.3 神经网络中的梯度下降
为了更直观地理解神经网络中梯度下降的过程,我们将通过一个具体的二分类问题来展示如何使用梯度下降和反向传播算法优化网络参数。假设有一个简单的两层神经网络,用于区分两类样本。下面将详细说明每一步的计算过程,并给出具体的数值示例。
模型结构
- 输入层:2 个特征 x 1 x_1 x1 和 x 2 x_2 x2。
- 隐藏层:3 个神经元,激活函数为 ReLU(Rectified Linear Unit)。
- 输出层:1 个神经元,激活函数为 Sigmoid,用于二分类。
- 损失函数:交叉熵损失函数。
初始化参数
随机初始化权重和偏置:
- 输入层到隐藏层的权重矩阵 W ( 1 ) W^{(1)} W(1):
W ( 1 ) = ( 0.5 − 0.2 0.3 0.4 − 0.1 0.6 ) W^{(1)} = \begin{pmatrix} 0.5 & -0.2 \\ 0.3 & 0.4 \\ -0.1 & 0.6 \end{pmatrix} W(1)= 0.50.3−0.1−0.20.40.6 - 隐藏层到输出层的权重矩阵 W ( 2 ) W^{(2)} W(2):
W ( 2 ) = ( 0.2 − 0.3 0.4 ) W^{(2)} = \begin{pmatrix} 0.2 \\ -0.3 \\ 0.4 \end{pmatrix} W(2)= 0.2−0.30.4 - 隐藏层的偏置向量 b ( 1 ) b^{(1)} b(1):
b ( 1 ) = ( 0.1 − 0.2 0.3 ) b^{(1)} = \begin{pmatrix} 0.1 \\ -0.2 \\ 0.3 \end{pmatrix} b(1)= 0.1−0.20.3 - 输出层的偏置 b ( 2 ) b^{(2)} b(2):
b ( 2 ) = 0.1 b^{(2)} = 0.1 b(2)=0.1
具体
🌰🌰
考虑一个简单的训练样本:
- 输入特征 X = ( 1 2 ) X = \begin{pmatrix} 1 \\ 2 \end{pmatrix} X=(12)
- 对应标签 y = 1 y = 1 y=1
第一次迭代
1. 前向传播
-
计算隐藏层的线性组合:
z ( 1 ) = W ( 1 ) ⋅ X + b ( 1 ) = ( 0.5 − 0.2 0.3 0.4 − 0.1 0.6 ) ⋅ ( 1 2 ) + ( 0.1 − 0.2 0.3 ) = ( 0.5 ⋅ 1 + ( − 0.2 ) ⋅ 2 + 0.1 0.3 ⋅ 1 + 0.4 ⋅ 2 − 0.2 − 0.1 ⋅ 1 + 0.6 ⋅ 2 + 0.3 ) = ( 0.4 0.7 1.4 ) z^{(1)} = W^{(1)} \cdot X + b^{(1)} = \begin{pmatrix} 0.5 & -0.2 \\ 0.3 & 0.4 \\ -0.1 & 0.6 \end{pmatrix} \cdot \begin{pmatrix} 1 \\ 2 \end{pmatrix} + \begin{pmatrix} 0.1 \\ -0.2 \\ 0.3 \end{pmatrix} = \begin{pmatrix} 0.5 \cdot 1 + (-0.2) \cdot 2 + 0.1 \\ 0.3 \cdot 1 + 0.4 \cdot 2 - 0.2 \\ -0.1 \cdot 1 + 0.6 \cdot 2 + 0.3 \end{pmatrix} = \begin{pmatrix} 0.4 \\ 0.7 \\ 1.4 \end{pmatrix} z(1)=W(1)⋅X+b(1)= 0.50.3−0.1−0.20.40.6 ⋅(12)+ 0.1−0.20.3 = 0.5⋅1+(−0.2)⋅2+0.10.3⋅1+0.4⋅2−0.2−0.1⋅1+0.6⋅2+0.3 = 0.40.71.4 -
应用 ReLU 激活函数:
a ( 1 ) = ReLU ( z ( 1 ) ) = ( max ( 0 , 0.4 ) max ( 0 , 0.7 ) max ( 0 , 1.4 ) ) = ( 0.4 0.7 1.4 ) a^{(1)} = \text{ReLU}(z^{(1)}) = \begin{pmatrix} \max(0, 0.4) \\ \max(0, 0.7) \\ \max(0, 1.4) \end{pmatrix} = \begin{pmatrix} 0.4 \\ 0.7 \\ 1.4 \end{pmatrix} a(1)=ReLU(z(1))= max(0,0.4)max(0,0.7)max(0,1.4) = 0.40.71.4 -
计算输出层的线性组合:
z ( 2 ) = W ( 2 ) ⋅ a ( 1 ) + b ( 2 ) = ( 0.2 − 0.3 0.4 ) ⋅ ( 0.4 0.7 1.4 ) + 0.1 = 0.2 ⋅ 0.4 + ( − 0.3 ) ⋅ 0.7 + 0.4 ⋅ 1.4 + 0.1 = 0.8 − 0.21 + 0.56 + 0.1 = 1.25 z^{(2)} = W^{(2)} \cdot a^{(1)} + b^{(2)} = \begin{pmatrix} 0.2 \\ -0.3 \\ 0.4 \end{pmatrix} \cdot \begin{pmatrix} 0.4 \\ 0.7 \\ 1.4 \end{pmatrix} + 0.1 = 0.2 \cdot 0.4 + (-0.3) \cdot 0.7 + 0.4 \cdot 1.4 + 0.1 = 0.8 - 0.21 + 0.56 + 0.1 = 1.25 z(2)=W(2)⋅a(1)+b(2)= 0.2−0.30.4 ⋅ 0.40.71.4 +0.1=0.2⋅0.4+(−0.3)⋅0.7+0.4⋅1.4+0.1=0.8−0.21+0.56+0.1=1.25 -
应用 Sigmoid 激活函数:
a ( 2 ) = σ ( z ( 2 ) ) = 1 1 + e − 1.25 ≈ 0.777 a^{(2)} = \sigma(z^{(2)}) = \frac{1}{1 + e^{-1.25}} \approx 0.777 a(2)=σ(z(2))=1+e−1.251≈0.777
2. 计算损失
使用交叉熵损失函数:
L = − y log ( a ( 2 ) ) − ( 1 − y ) log ( 1 − a ( 2 ) ) = − 1 ⋅ log ( 0.777 ) − 0 ⋅ log ( 1 − 0.777 ) ≈ 0.251 L = -y \log(a^{(2)}) - (1 - y) \log(1 - a^{(2)}) = -1 \cdot \log(0.777) - 0 \cdot \log(1 - 0.777) \approx 0.251 L=−ylog(a(2))−(1−y)log(1−a(2))=−1⋅log(0.777)−0⋅log(1−0.777)≈0.251
3. 反向传播
-
计算输出层的误差:
δ ( 2 ) = a ( 2 ) − y = 0.777 − 1 = − 0.223 \delta^{(2)} = a^{(2)} - y = 0.777 - 1 = -0.223 δ(2)=a(2)−y=0.777−1=−0.223 -
计算输出层的梯度:
∇ W ( 2 ) L = δ ( 2 ) ⋅ a ( 1 ) T = − 0.223 ⋅ ( 0.4 0.7 1.4 ) = ( − 0.0892 − 0.1561 − 0.3122 ) \nabla_{W^{(2)}} L = \delta^{(2)} \cdot a^{(1)T} = -0.223 \cdot \begin{pmatrix} 0.4 \\ 0.7 \\ 1.4 \end{pmatrix} = \begin{pmatrix} -0.0892 \\ -0.1561 \\ -0.3122 \end{pmatrix} ∇W(2)L=δ(2)⋅a(1)T=−0.223⋅ 0.40.71.4 = −0.0892−0.1561−0.3122
∇ b ( 2 ) L = δ ( 2 ) = − 0.223 \nabla_{b^{(2)}} L = \delta^{(2)} = -0.223 ∇b(2)L=δ(2)=−0.223 -
计算隐藏层的误差:
δ ( 1 ) = ( δ ( 2 ) ⋅ W ( 2 ) T ) ⊙ f ′ ( z ( 1 ) ) \delta^{(1)} = (\delta^{(2)} \cdot W^{(2)T}) \odot f'(z^{(1)}) δ(1)=(δ(2)⋅W(2)T)⊙f′(z(1))
其中 f ′ f' f′ 是 ReLU 的导数(对于正数是 1,对于负数是 0),所以:
δ ( 1 ) = ( − 0.223 ⋅ ( 0.2 − 0.3 0.4 ) ) ⊙ ( 1 1 1 ) = ( − 0.0446 0.0669 − 0.0892 ) \delta^{(1)} = (-0.223 \cdot \begin{pmatrix} 0.2 \\ -0.3 \\ 0.4 \end{pmatrix}) \odot \begin{pmatrix} 1 \\ 1 \\ 1 \end{pmatrix} = \begin{pmatrix} -0.0446 \\ 0.0669 \\ -0.0892 \end{pmatrix} δ(1)=(−0.223⋅ 0.2−0.30.4 )⊙ 111 = −0.04460.0669−0.0892 -
计算隐藏层的梯度:
∇ W ( 1 ) L = δ ( 1 ) ⋅ X T = ( − 0.0446 0.0669 − 0.0892 ) ⋅ ( 1 2 ) = ( − 0.0446 − 0.0892 0.0669 0.1338 − 0.0892 − 0.1784 ) \nabla_{W^{(1)}} L = \delta^{(1)} \cdot X^T = \begin{pmatrix} -0.0446 \\ 0.0669 \\ -0.0892 \end{pmatrix} \cdot \begin{pmatrix} 1 \\ 2 \end{pmatrix} = \begin{pmatrix} -0.0446 & -0.0892 \\ 0.0669 & 0.1338 \\ -0.0892 & -0.1784 \end{pmatrix} ∇W(1)L=δ(1)⋅XT= −0.04460.0669−0.0892 ⋅(12)= −0.04460.0669−0.0892−0.08920.1338−0.1784
∇ b ( 1 ) L = δ ( 1 ) = ( − 0.0446 0.0669 − 0.0892 ) \nabla_{b^{(1)}} L = \delta^{(1)} = \begin{pmatrix} -0.0446 \\ 0.0669 \\ -0.0892 \end{pmatrix} ∇b(1)L=δ(1)= −0.04460.0669−0.0892
4. 更新参数
选择学习率 α = 0.1 \alpha = 0.1 α=0.1:
-
更新输出层的权重和偏置:
W new ( 2 ) = W ( 2 ) − α ⋅ ∇ W ( 2 ) L = ( 0.2 − 0.3 0.4 ) − 0.1 ⋅ ( − 0.0892 − 0.1561 − 0.3122 ) = ( 0.20892 − 0.28439 0.43122 ) W^{(2)}_{\text{new}} = W^{(2)} - \alpha \cdot \nabla_{W^{(2)}} L = \begin{pmatrix} 0.2 \\ -0.3 \\ 0.4 \end{pmatrix} - 0.1 \cdot \begin{pmatrix} -0.0892 \\ -0.1561 \\ -0.3122 \end{pmatrix} = \begin{pmatrix} 0.20892 \\ -0.28439 \\ 0.43122 \end{pmatrix} Wnew(2)=W(2)−α⋅∇W(2)L= 0.2−0.30.4 −0.1⋅ −0.0892−0.1561−0.3122 = 0.20892−0.284390.43122
b new ( 2 ) = b ( 2 ) − α ⋅ ∇ b ( 2 ) L = 0.1 − 0.1 ⋅ ( − 0.223 ) = 0.1223 b^{(2)}_{\text{new}} = b^{(2)} - \alpha \cdot \nabla_{b^{(2)}} L = 0.1 - 0.1 \cdot (-0.223) = 0.1223 bnew(2)=b(2)−α⋅∇b(2)L=0.1−0.1⋅(−0.223)=0.1223 -
更新隐藏层的权重和偏置:
W new ( 1 ) = W ( 1 ) − α ⋅ ∇ W ( 1 ) L = ( 0.5 − 0.2 0.3 0.4 − 0.1 0.6 ) − 0.1 ⋅ ( − 0.0446 − 0.0892 0.0669 0.1338 − 0.0892 − 0.1784 ) = ( 0.50446 − 0.19108 0.29331 0.38662 − 0.09108 0.61784 ) W^{(1)}_{\text{new}} = W^{(1)} - \alpha \cdot \nabla_{W^{(1)}} L = \begin{pmatrix} 0.5 & -0.2 \\ 0.3 & 0.4 \\ -0.1 & 0.6 \end{pmatrix} - 0.1 \cdot \begin{pmatrix} -0.0446 & -0.0892 \\ 0.0669 & 0.1338 \\ -0.0892 & -0.1784 \end{pmatrix} = \begin{pmatrix} 0.50446 & -0.19108 \\ 0.29331 & 0.38662 \\ -0.09108 & 0.61784 \end{pmatrix} Wnew(1)=W(1)−α⋅∇W(1)L= 0.50.3−0.1−0.20.40.6 −0.1⋅ −0.04460.0669−0.0892−0.08920.1338−0.1784 = 0.504460.29331−0.09108−0.191080.386620.61784
b new ( 1 ) = b ( 1 ) − α ⋅ ∇ b ( 1 ) L = ( 0.1 − 0.2 0.3 ) − 0.1 ⋅ ( − 0.0446 0.0669 − 0.0892 ) = ( 0.10446 − 0.20669 0.30892 ) b^{(1)}_{\text{new}} = b^{(1)} - \alpha \cdot \nabla_{b^{(1)}} L = \begin{pmatrix} 0.1 \\ -0.2 \\ 0.3 \end{pmatrix} - 0.1 \cdot \begin{pmatrix} -0.0446 \\ 0.0669 \\ -0.0892 \end{pmatrix} = \begin{pmatrix} 0.10446 \\ -0.20669 \\ 0.30892 \end{pmatrix} bnew(1)=b(1)−α⋅∇b(1)L= 0.1−0.20.3 −0.1⋅ −0.04460.0669−0.0892 = 0.10446−0.206690.30892
后续迭代
重复上述步骤,逐步减少损失函数,提高预测准确性。随着迭代次数的增加,网络的权重和偏置将逐渐收敛到最优解,从而使损失函数最小化,预测性能最大化。
通过这个具体的数值例子,可以更直观地理解神经网络中梯度下降和反向传播的工作原理。每一次迭代中,会根据当前的损失计算梯度,并沿着梯度的反方向调整参数,最终使模型更好地拟合训练数据。
四、结论
梯度不仅是理解多维空间中函数行为的强大工具,而且在优化问题中扮演着至关重要的角色。通过了解梯度的方向和反方向,我们可以有效地使用梯度下降算法来找到函数的最低点。无论是处理简单的一元二次函数还是更复杂的多元函数,梯度都为我们提供了一条通向最优解的道路。通过具体的迭代过程和参数更新方法,展示了如何在实际问题中应用梯度下降算法,帮助大家更好地掌握这一优化技术。
相关文章:
深入浅出梯度下降算法:快速抵达函数最小值的方法
引言 梯度是机器学习和优化领域中不可或缺的概念,它为我们提供了理解和调整多维空间中函数行为的工具。本文将详细介绍梯度的定义、性质,并通过具体的一元和多元函数案例展示如何使用梯度下降算法找到最佳参数。 一、梯度的基础知识 1.1 定义与计算 梯…...
OPC DA激活报错
报错提示: 解决办法: 查看Missing license keys,根据提示破解...
PyTorch到C++再到 CUDA 的调用链(C++ ATen 层) :以torch._amp_update_scale_调用为例
今天在看pytorch源码,遇到的问题,记录一下 。 source:/lib/python3.10/site-packages/torch/amp/grad_scaler.py torch._amp_update_scale_(_scale,_growth_tracker,found_inf_combined,self._growth_factor,self._backoff_factor,self._growth_interva…...
yolov5核查数据标注漏报和误报
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、误报二、漏报三、源码总结 前言 本文主要用于记录数据标注和模型预测之间的漏报和误报思想及其源码 提示:以下是本篇文章正文内容,…...
C# 设计模式概况
什么是设计模式 大家熟知的GOF23种设计模式,源自《Design Patterns: Elements of Reusable Object-Oriented Software》一书,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著,四人组Gang of Four简称GOF。总结了在面向…...
STM32 NOR FLASH(SPI FLASH)驱动移植(2)
2)FLASH 读取函数 /* * brief 读取 SPI FLASH * note 在指定地址开始读取指定长度的数据 * param pbuf : 数据存储区 * param addr : 开始读取的地址(最大 32bit) * param datalen : 要读取的字节数(最大 65535) * retval 无 */ void norflash_read(uint8_t *pbuf…...
Redis高可用集群部署
根据集群分析和持久化优化方式,这里用docker部署redis分片集群模式并设置为aof-rdb共用方式存储 准备 2核4G及以上服务器;安装好docker环境;配置docker镜像仓库(https://www.ecnfo.com:1443),因为下面镜像是从这个镜像仓库下载的{"builder": {"gc"…...
【玩转23种Java设计模式】行为型模式篇:命令模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...
代码随想录算法【Day10】
今日只做一题,剩下的题后面补 232.用栈实现队列 class MyQueue { public:stack<int> stIn;stack<int> stOut;/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {stIn.push(x);}…...
WKWebView打开pdf文件乱码?各种方案整理。
近期有用户反馈使用我们FinClip SDK运行的小程序,在iOS18.0.1的系统上打开部分pdf文件的时候出现了乱码的现象, 低版本的系统打开没有出现乱码的现象,用电脑打开这个pdf文件也是正常的。经过排查,可能是iOS18的系统对WKWebView进行了调整处理…...
Android中创建ViewModel的几种方法
文章目录 1. 使用 `ViewModelProvider`1.1 在 `Activity` 中创建 `ViewModel`1.2 在 `Fragment` 中创建 `ViewModel`2. 使用 `ViewModelFactory`2.1 创建 `ViewModel` 和 `ViewModelFactory`2.2 在 `Activity` 或 `Fragment` 中使用 `ViewModelFactory`3. 使用 `by viewModels(…...
【C语言】_指针运算
目录 1. 指针-整数 2. 指针-指针 2.1 指针-指针含义 2.2 指针-指针运算应用:实现my_strlen函数 3. 指针的关系运算(大小比较) 1. 指针-整数 联系关于指针变量类型关于指针类型和指针-整数相关知识: 原文链接如下࿱…...
多层设计模式:可否设计各层之间公用的数据定义模块?
在多层程序设计模式中,可以设计一个各层之间公用的数据类型定义模块。这种模块通常被称为“公共模块”或“共享模块”,它包含所有层都需要使用的数据类型定义。这有助于确保数据在不同层之间传递时的一致性和准确性。 以下是一些设计这种公用数据类型定…...
深度学习模型格式转换:pytorch2onnx(包含自定义操作符)
将PyTorch模型转换为ONNX(Open Neural Network Exchange)格式是实现模型跨平台部署和优化推理性能的一种常见方法。PyTorch 提供了多种方式来完成这一转换,以下是几种主要的方法: 一、静态模型转换 使用 torch.onnx.export() t…...
CDPHudi实战-集成spark
[一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do scp /opt/software/hudi-1.0.0/packaging/hudi-spark-bundle/target/hudi-spark3.4-bundle_2.12-1.0.0.jar cdp73-$i:/opt/cloudera/parcels/CDH/lib/spark3/jars/; done hudi-spark3.4-bu…...
Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s
前言:纯个人记录使用。 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。 官方文档…...
汇编语言与接口技术--跑马灯
一、 实验要求 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图: 单片机芯片选择AT89C51,晶振频率设为12MHz,操作参考单片机开发板使用说明。跑马灯点亮的时间间隔约为1秒。分别用定时器的模式1和模式2实现。(用P83…...
springcloud篇3-docker需熟练掌握的知识点
docker的原理请参考博文《Docker与Kubernetes》。 一、安装docker的指令 1.1 安装yum工具 yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken补充:配置镜像源 注意: yum安装是在线联网下载安装,而很多的资源…...
Unity网络通信相关
Socket 通信一张图搞定 谁提供服务谁绑定端口,建立Listener,写Host...
leetcode 173.二叉搜索树迭代器栈绝妙思路
以上算法题中一个比较好的实现思路就是利用栈来进行实现,以下方法三就是利用栈来进行实现的,思路很好,很简练。进行next的时候,先是一直拿到左边的子树,直到null为止,这一步比较好思考一点,下一…...
模电面试——设计题及综合分析题0x01(含答案)
1、已知某温控系统的部分电路如下图(EDP070252),晶体管VT导通时,继电器J吸合,压缩机M运转制冷,VT截止时,J释放,M停止运转。 (1)电源刚接通时,晶体…...
Linux性能优化-系列文章-汇总
前言 Linux性能优化,涉及了CPU,内存,磁盘,网络等很多方面,一方面涉及的知识面广,同时又要在原理方面掌握一定的深度。所以整理总结了Linux性能优化的一系列文章。当处理Linux性能问题的时候,可…...
仓库叉车高科技安全辅助设备——AI防碰撞系统N2024G-2
在当今这个高效运作、安全第一的物流时代,仓库作为供应链的中心地带,其安全与效率直接关系到企业的命脉。 随着科技的飞速发展,传统叉车作业模式正逐步向智能化、安全化转型,而在这场技术革新中,AI防碰撞系统N2024G-2…...
threejs 安装
参考了threejs官方网站文档安装,上来就是各种报错,最终参考之前大佬发的攻略解决了。过程供大家参考。 官方文档地址如下: three.js docshttps://threejs.org/docs/index.html#manual/en/introduction/Installation 具体参考这篇攻略&#…...
《 C++ 点滴漫谈: 十七 》编译器优化与 C++ volatile:看似简单却不容小觑
摘要 本文深入探讨了 C 中的 volatile 关键字,全面解析其基本概念、典型用途以及在现代编程中的实际意义。通过剖析 volatile 的核心功能,我们了解了它如何避免编译器优化对硬件交互和多线程环境中变量访问的干扰。同时,文章分析了 volatile…...
【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习
文章目录 Section 4:The Vim Help System(Vim 帮助系统)S04L14 Getting Help1 打开帮助系统2 退出帮助系统3 查看具体命令的帮助文档4 查看帮助文档中的主题5 帮助文档间的上翻、下翻6 关于 linewise7 查看光标所在术语名词的帮助文档8 关于退…...
电脑中缺失的nvrtc64_90.dll文件如何修复?
一、文件丢失问题 案例:nvrtc64_90.dll文件缺失 问题分析: nvrtc64_90.dll是NVIDIA CUDA Runtime Compilation库的一部分,通常与NVIDIA的CUDA Toolkit或相关驱动程序一起安装。如果该文件丢失,可能会导致基于CUDA的应用程序&…...
leveldb的DBSequence从哪里来,到哪里去?
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) leveldb数据库的DBSequence从哪里来,到哪里去? 大概的情形是,leveldb的记录初始DBSequence为0,随着记录的增加,记录sequence不断随着增加,并持久化…...
nginx高可用集群搭建
本文介绍nginx高可用集群的搭建。利用keepalived实时检查nginx进程是否存活、keepalived的虚拟ip技术,达到故障转移的目的。终端用户通过访问虚拟ip,感知不到实际发生的故障。架构图如下: 0、环境 Ubuntu:22.04.2 ltsnginx: 1.…...
基于TCP的Qt网络通信
基于TCP的Qt网络通信 项目源码:https://github.com/say-Hai/TcpSocketLearn/tree/QTcpSocket 在标准C没有提供专门用于套接字通信的类,所以只能使用操作系统提供的基于C的API函数,但是Qt就不一样了,它是C的一个框架并且里边提供了…...
MySql---进阶篇(六)---SQL优化
6.1:insert的优化: (1)普通的插入数据 如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化。 insert into tb_test values(1,tom); insert into tb_test values(2,cat); insert into tb_test values(3,jerry); 1). 优…...
什么是回归测试?
什么是回归测试? 回归测试被定义为一种软件测试,以确认最近的程序或代码更改没有对现有功能产生不利影响。回归测试只是对已经执行的测试用例的全部或部分选择,重新执行这些用例以确保现有功能正常工作。 进行此测试是为了确保新的代码更改不会对现有…...
详解MySQL SQL删除(超详,7K,含实例与分析)
文章目录 前言1. 删除表中的所有记录基本语法使用场景注意事项运用实例分析说明2. 删除特定记录基本语法使用场景注意事项运用实例分析说明3. 删除单条记录基本语法使用场景注意事项运用实例分析说明4. 删除违反引用完整性的记录基本语法使用场景注意事项运用实例分析说明5. 删…...
lec7-路由与路由器
lec7-路由与路由器 1. 路由器硬件 路由器的硬件部分: 断电失去: RAM断电不失去:NVRAM, Flash, ROMinterface也算是一部分 路由器是特殊组件的计算机 console 口进行具体的调试 辅助口(Auxiliary&…...
知识库召回列表模式揭秘:实现智能信息检索新突破
目录 一、什么是知识库的召回列表模式 召回列表模式的工作流程 典型应用场景 召回列表模式的优势 二、知识库召回列表模式的技术实现细节 1. 数据准备 2. 召回策略 3. 排序策略 4. 结果展示与交互 三、技术架构示例 1. 系统架构 2. 代码示例 四、总结 随着人工智能…...
WCH的CH57X的J-LINK的芯片FLASH烧录文件
WCH的CH57X的J-LINK的芯片FLASH烧录文件,需要在 D:\app\Keil_v5\SEGGER\JLink_V616a目录中JLINKDEVICES.XML文件中修改并增加以下信息。同时,需要加入CH57X.FLM文件 <Device> <ChipInfo Vendor"WCH" Name"CH57X" WorkRAMAddr"…...
Rust 基础入门指南
Rust 基础入门指南 1. Rust 语言概述 Rust 的历史与设计理念 Rust 是由 Mozilla 研究院的 Graydon Hoare 于2010年开始创建的系统编程语言。其设计目标是创建一种安全、并发、实用的编程语言,特别关注内存安全和并发性。 Rust 的核心设计理念包括: …...
Qt|QWidget窗口支持旋转
功能实现:使用QWidget创建的窗口支持窗口旋转功能。 展示的示例中支持由水平方向旋转至垂直方向。至于其它角度旋转的问题,看完这篇文章后应该会很简单能实现的! 开发环境:win VS2019 Qt 5.15.2 在实现之前也有想用使用 QProp…...
docker compose部署kafka集群
先部署zookeeper集群,启动 参考:docker compose部署zookeeper集群-CSDN博客 再部署kafka集群 networks: net: external: true services: kafka1: restart: always image: wurstmeister/kafka:2.13_2.8.1 container_name: kafka1 …...
Spring源码分析之事件机制——观察者模式(三)
目录 自定义事件 事件监听器 事件发布者(服务层) 使用示例controller层 Spring源码分析之事件机制——观察者模式(一)-CSDN博客 Spring源码分析之事件机制——观察者模式(二)-CSDN博客 这两篇文章是这…...
如何使用axios实现文件上传
文件上传 axios 支持文件上传,通常使用 FormData 对象来封装文件和其他表单数据。 import axios from axios;const formData new FormData(); formData.append(file, fileInput.files[0]); formData.append(description, 文件描述);axios.post(/api/upload, form…...
wx016基于springboot+vue+uniapp的超市购物系统小程序
开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…...
LLM - 使用 LLaMA-Factory 部署大模型 HTTP 多模态服务 (4)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144881432 大模型的 HTTP 服务,通过网络接口,提供 AI 模型功能的服务,允许通过发送 HTTP 请求,交互…...
JeeSite 快速开发平台:全能企业级快速开发解决方案|GitCode 光引计划征文展示
投稿人GitCode ID:thinkgem 光引计划投稿项目介绍 JeeSite 快速开发平台,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,后端基于经典组合 Spring Boot、Shiro、MyBatis,前端采用 Beetl、Bootstrap、Admi…...
HackMyVM-Airbind靶机的测试报告
目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 使用ipv6绕过iptables 四、结论 一、测试环境 1、系统环境 渗透机:kali2021.1(192.168.101.127) 靶 机:debian(192.168.101.11…...
探索Wiki:开源知识管理平台及其私有化部署
在如今的信息时代,企业和团队的知识管理变得愈发重要。如何有效地存储、整理、共享和协作,是提高团队效率和创新能力的关键因素之一。今天,我要为大家介绍一款非常有用的github上开源知识管理工具——Wiki,并分享它的私有化部署方…...
网关的主要作用
在网络安全领域,网关扮演着举足轻重的角色,它不仅是网络间的桥梁,更是安全防线的守护者。以下是网关在网络安全中的几个关键作用: 1. 防火墙功能:网关常常集成了防火墙技术,能够对进出网络的数据包进行严格…...
黑马JavaWeb开发跟学(十五).Maven高级
黑马JavaWeb开发跟学.十五.Maven高级 Maven高级1. 分模块设计与开发1.1 介绍1.2 实践1.2.1 分析1.2.2 实现 1.3 总结 2. 继承与聚合2.1 继承2.1.1 继承关系2.1.1.1 思路分析2.1.1.2 实现 2.1.2 版本锁定2.1.2.1 场景2.1.2.2 介绍2.1.2.3 实现2.1.2.4 属性配置 2.2 聚合2.2.1 介…...
TLS(传输层安全,Transport Layer Security)是用于在网络上提供通信安全的一种加密协议。
TLS(传输层安全,Transport Layer Security)是用于在网络上提供通信安全的一种加密协议。它是SSL(安全套接层,Secure Sockets Layer)的继任者,旨在确保两个应用程序之间数据传输的隐私性、完整性…...
Statistic for ML
statistical concept 統計學概念 免費完整內容 PMF and CDF PMF定義的值是P(Xx),而CDF定義的值是P(X < x),x為所有的實數線上的點。 probability mass function (PMF) 概率質量函數 p X ( x ) P ( X x ) pX(x)P(Xx) pX(x)P(Xx) 是離散隨機變數…...