从反向传播(BP)到BPTT:详细数学推导【原理理解】

从反向传播到BPTT:详细推导与问题解析

在本文中,我们将从反向传播算法开始,详细推导出反向传播通过时间(Backpropagation Through Time, BPTT)算法。重点讨论BPTT中的梯度消失和梯度爆炸问题,并解释如何解决这些问题。假设读者已经具备反向传播的基本知识,我们将简要回顾反向传播的核心概念,然后深入解析BPTT算法。

反向传播算法的简要回顾

反向传播算法(Backpropagation)是用于训练神经网络的一种有效方法。其核心思想是通过链式法则(Chain Rule)计算损失函数相对于各个权重的梯度,然后使用梯度下降法更新权重。以下是反向传播的主要步骤:

  1. 前向传播: 计算输入数据通过神经网络各层的输出。
  2. 计算损失: 通过损失函数计算预测输出与真实输出之间的误差。
  3. 反向传播: 通过链式法则计算损失相对于每个权重的梯度。

反向传播的详细过程涉及链式法则在多层网络中的应用,我们将这些步骤拓展到处理时间序列数据的BPTT算法中。

详情见:BP神经网络反向传播原理【数学原理、举例说明】

反向传播通过时间(BPTT)算法

BPTT是一种针对循环神经网络(Recurrent Neural Networks, RNNs)的训练算法,它将标准反向传播算法扩展到 时间序列数据 上。RNN的特点是其隐藏层不仅依赖于 当前的输入 ,还依赖于 前一时间步的隐藏状态 ,这使得RNN能够处理序列数据。然而,这也引入了计算梯度的复杂性,因为损失不仅与当前时间步的输出相关,还与之前时间步的隐藏状态相关。

前向传播

在BPTT中,前向传播是从时间步1到时间步T逐步计算每个时间步的隐藏状态和输出。

假设我们有一个输入序列 { x 1 , x 2 , … , x T } \{x_1, x_2, \ldots, x_T\} {x1,x2,,xT} ,每个 x t x_t xt 是在时间步t的输入。RNN的隐藏状态 h t h_t ht 和输出 y t y_t yt 依次计算如下:

  1. 初始化: 首先,隐藏状态 h 0 h_0 h0 通常初始化为零或小的随机值。
    h 0 = 0 (或小的随机值) h_0 = 0 \text{(或小的随机值)} h0=0(或小的随机值)

  2. 时间步1的计算:

    • 计算隐藏状态 h 1 h_1 h1
      h 1 = f ( W h x x 1 + W h h h 0 + b h ) h_1 = f(W_{hx} x_1 + W_{hh} h_0 + b_h) h1=f(Whxx1+Whhh0+bh)
      这里, W h x W_{hx} Whx 是输入到隐藏层的权重矩阵, W h h W_{hh} Whh 是隐藏层到隐藏层的权重矩阵, b h b_h bh 是偏置, f f f 是激活函数(如tanh或ReLU)。这一步可以理解为将 当前输入 x 1 x_1 x1 与前一时间步的隐藏状态 h 0 h_0 h0 结合,通过一个激活函数得到当前时间步的隐藏状态 h 1 h_1 h1

      这与传统BP(Backpropagation)不同,传统BP不考虑时间步之间的依赖,而RNN通过引入隐藏层状态的递归关系来捕捉 时间序列中的依赖性

    • 计算输出 y 1 y_1 y1
      y 1 = g ( W h y h 1 + b y ) y_1 = g(W_{hy} h_1 + b_y) y1=g(Whyh1+by)
      这里, W h y W_{hy} Why 是隐藏层到输出层的权重矩阵, b y b_y by 是输出层的偏置, g g g 是输出层的激活函数(通常为softmax或线性函数)。这一步可以理解为将隐藏状态 h 1 h_1 h1 转化为输出 y 1 y_1 y1

  3. 时间步t的计算(t=2, …, T): 对于后续的每个时间步,我们重复上述步骤:

    • 计算隐藏状态 h t h_t ht
      h t = f ( W h x x t + W h h h t − 1 + b h ) h_t = f(W_{hx} x_t + W_{hh} h_{t-1} + b_h) ht=f(Whxxt+Whhht1+bh)
      这里,隐藏状态 h t h_t ht 是当前输入 x t x_t xt 与前一时间步隐藏状态 h t − 1 h_{t-1} ht1 的结合,通过激活函数 f f f 得到。

    • 计算输出 y t y_t yt
      y t = g ( W h y h t + b y ) y_t = g(W_{hy} h_t + b_y) yt=g(Whyht+by)
      输出 y t y_t yt 是当前隐藏状态 h t h_t ht 通过激活函数 g g g 得到。

通过这一步步计算,我们将输入序列 { x 1 , x 2 , … , x t } \{x_1, x_2, \ldots, x_t\} {x1,x2,,xt} 转化为隐藏状态序列 { h 1 , h 2 , … , h t } \{h_1, h_2, \ldots, h_t\} {h1,h2,,ht} 和输出序列 { y 1 , y 2 , … , y t } \{y_1, y_2, \ldots, y_t\} {y1,y2,,yt}

为什么要将输入序列转换为隐藏状态序列和输出序列?

将输入序列转换为隐藏状态序列和输出序列的原因在于RNN的核心思想通过引入隐藏状态,模型能够捕捉序列数据中的时间依赖关系 。隐藏状态序列 { h 1 , h 2 , … , h t } \{h_1, h_2, \ldots, h_t\} {h1,h2,,ht} 是RNN对输入序列的内部表示,记录了前一时间步的信息,并将其传递给当前时间步。

数学上,这种递归关系可以理解为状态转移函数:
h t = f ( W h x x t + W h h h t − 1 + b h ) h_t = f(W_{hx} x_t + W_{hh} h_{t-1} + b_h) ht=f(Whxxt+Whhht1+bh)
这个公式表示当前的隐藏状态 h t h_t ht 是当前输入 x t x_t xt 和前一时间步隐藏状态 h t − 1 h_{t-1} ht1 的函数。通过这种递归关系,RNN能够记住之前时间步的信息,并在后续时间步中使用,从而捕捉长时间的依赖关系。

输出序列 { y 1 , y 2 , … , y t } \{y_1, y_2, \ldots, y_t\} {y1,y2,,yt} 是模型的预测结果,通过将隐藏状态转化为输出,我们可以计算损失,并通过反向传播更新模型参数。

计算损失

计算损失是为了衡量模型输出与真实输出之间的误差。对于整个序列,我们通常采用均方误差(MSE)或交叉熵损失。假设真实输出序列为 { y ^ 1 , y ^ 2 , … , y ^ t } \{\hat{y}_1, \hat{y}_2, \ldots, \hat{y}_t\} {y^1,y^2,,y^t} ,损失函数 L L L 可以表示为:

  1. 均方误差(MSE):
    L = ∑ t = 1 T 1 2 ( y t − y ^ t ) 2 L = \sum_{t=1}^T \frac{1}{2} (y_t - \hat{y}_t)^2 L=t=1T21(yty^t)2
    这里,我们计算每个时间步的输出 y t y_t yt 与真实输出 y ^ t \hat{y}_t y^t 之间的平方误差,并将所有时间步的误差求和。

  2. 交叉熵损失:
    L = − ∑ t = 1 T [ y ^ t log ⁡ ( y t ) + ( 1 − y ^ t ) log ⁡ ( 1 − y t ) ] L = -\sum_{t=1}^T [\hat{y}_t \log(y_t) + (1 - \hat{y}_t) \log(1 - y_t)] L=t=1T[y^tlog(yt)+(1y^t)log(1yt)]
    这里,我们计算每个时间步的输出 y t y_t yt 与真实输出 y ^ t \hat{y}_t y^t 之间的交叉熵损失,并将所有时间步的损失求和。

反向传播

反向传播的目的是通过链式法则计算损失相对于每个权重的梯度,并更新权重。具体步骤如下:

  1. 计算输出层的梯度:

    δ t y = ∂ ℓ ( y t , y ^ t ) ∂ y t ⋅ g ′ ( y t ) \delta^y_t = \frac{\partial \ell(y_t, \hat{y}_t)}{\partial y_t} \cdot g'(y_t) δty=yt(yt,y^t)g(yt)
    这里, δ t y \delta^y_t δty 是第 t 时间步的输出层梯度。这个公式中的每个部分代表:

    • ∂ ℓ ( y t , y ^ t ) ∂ y t \frac{\partial \ell(y_t, \hat{y}_t)}{\partial y_t} yt(yt,y^t) 是损失函数 ℓ \ell 对输出 y t y_t yt 的导数,它表示输出 y t y_t yt 的变化对损失函数 ℓ \ell 的影响。
    • g ′ ( y t ) g'(y_t) g(yt) 是输出层激活函数 g g g 对其输入 y t y_t yt 的导数。

根据链式法则,我们计算 ∂ ℓ ∂ y t \frac{\partial \ell}{\partial y_t} yt 时,需要考虑:
∂ ℓ ∂ y t = ∂ ℓ ∂ g ( y t ) ⋅ ∂ g ( y t ) ∂ y t \frac{\partial \ell}{\partial y_t} = \frac{\partial \ell}{\partial g(y_t)} \cdot \frac{\partial g(y_t)}{\partial y_t} yt=g(yt)ytg(yt)
这里, ∂ ℓ ∂ g ( y t ) \frac{\partial \ell}{\partial g(y_t)} g(yt) 是损失函数对激活函数输出的导数, ∂ g ( y t ) ∂ y t \frac{\partial g(y_t)}{\partial y_t} ytg(yt) 是激活函数 g g g 对输入 y t y_t yt 的导数。

  1. 计算隐藏层的梯度:
    隐藏层的梯度计算涉及当前时间步和未来时间步的影响:
    δ t h = δ t y W h y T ⋅ f ′ ( h t ) + δ t + 1 h W h h T ⋅ f ′ ( h t ) \delta^h_t = \delta^y_t W_{hy}^T \cdot f'(h_t) + \delta^h_{t+1} W_{hh}^T \cdot f'(h_t) δth=δtyWhyTf(ht)+δt+1hWhhTf(ht)

    • δ t y W h y T ⋅ f ′ ( h t ) \delta^y_t W_{hy}^T \cdot f'(h_t) δtyWhyTf(ht)当前时间步输出层梯度 传播回来的部分。具体来说, δ t y \delta^y_t δty 是输出层梯度,通过输出层到隐藏层的权重 W h y W_{hy} Why 传递回隐藏层,再乘以隐藏层激活函数 f f f 的导数 f ′ ( h t ) f'(h_t) f(ht)
    • δ t + 1 h W h h T ⋅ f ′ ( h t ) \delta^h_{t+1} W_{hh}^T \cdot f'(h_t) δt+1hWhhTf(ht)未来时间步隐藏层梯度 传播回来的部分。这里, δ t + 1 h \delta^h_{t+1} δt+1h 是下一时间步的隐藏层梯度,通过隐藏层到隐藏层的权重 W h h W_{hh} Whh 传递回当前隐藏层,再乘以当前隐藏层激活函数的导数 f ′ ( h t ) f'(h_t) f(ht)
  2. 更新权重:
    权重更新是通过梯度下降法进行的。梯度下降法的基本思想是沿着 梯度的反方向 更新权重,使得损失函数逐渐减小。

    • 输入到隐藏层的权重更新
      Δ W h x = ∑ t = 1 T δ t h ⋅ x t T \Delta W_{hx} = \sum_{t=1}^T \delta^h_t \cdot x_t^T ΔWhx=t=1TδthxtT
      这里, δ t h \delta^h_t δth 是时间步 t t t 的隐藏层梯度, ⋅ x t T \cdot x_t^T xtT 表示输入 x t x_t xt 的转置。我们将所有时间步的梯度相加,得到输入到隐藏层权重的更新量。

    • 隐藏层到隐藏层的权重更新
      Δ W h h = ∑ t = 2 T δ t h ⋅ h t − 1 T \Delta W_{hh} = \sum_{t=2}^T \delta^h_t \cdot h_{t-1}^T ΔWhh=t=2Tδthht1T
      这里, δ t h \delta^h_t δth 是时间步 t t t 的隐藏层梯度, ⋅ h t − 1 T \cdot h_{t-1}^T ht1T 表示前一时间步隐藏状态 h t − 1 h_{t-1} ht1 的转置。同样地,我们将所有时间步的梯度相加,得到隐藏层到隐藏层权重的更新量。

    • 隐藏层到输出层的权重更新
      Δ W h y = ∑ t = 1 T δ t y ⋅ h t T \Delta W_{hy} = \sum_{t=1}^T \delta^y_t \cdot h_t^T ΔWhy=t=1TδtyhtT
      这里, δ t y \delta^y_t δty 是时间步 t t t 的输出层梯度, ⋅ h t T \cdot h_t^T htT 表示当前时间步隐藏状态 h t h_t ht 的转置。我们将所有时间步的梯度相加,得到隐藏层到输出层权重的更新量。

这些权重更新公式通过链式法则计算各个权重的梯度,并使用梯度下降法更新权重,使得损失函数最小化。

梯度消失和梯度爆炸问题

在BPTT中,梯度消失和梯度爆炸是两个主要问题。这两个问题都与梯度在时间步长上的传播有关。随着时间步数增加,梯度的值可能会逐渐减小到几乎为零(梯度消失)或变得非常大(梯度爆炸),这会影响模型的训练效果。

梯度消失

随着时间步数的增加,梯度逐渐减小,最终可能变得非常接近于零。这导致模型无法有效更新权重,无法捕捉到长期依赖关系。

  • 数学上,如果激活函数的导数 f ′ ( h t ) f'(h_t) f(ht) 小于 1,多次相乘后会趋近于零。
  • 比如,激活函数为 tanh ⁡ \tanh tanh ,它的导数值在 [-1, 1] 之间,且通常小于 1。
梯度爆炸

随着时间步数的增加,梯度逐渐变大,最终可能变得非常大。这导致权重更新过大,模型无法收敛。

  • 数学上,如果激活函数的导数 f ′ ( h t ) f'(h_t) f(ht) 大于 1,多次相乘后会迅速增长。
  • 比如,激活函数为 ReLU(修正线性单元),其导数在正区间为 1,如果某些参数或权重较大,梯度可能会迅速累积变大。

梯度传播过程中的数学推导

假设一个简单的RNN模型,隐藏层激活函数为 f f f ,我们考虑隐藏层的状态 h t h_t ht 及其梯度的传播过程。

基本概念和公式
  1. 隐藏层状态更新:
    h t = f ( W h h h t − 1 + W h x x t + b h ) h_t = f(W_{hh} h_{t-1} + W_{hx} x_t + b_h) ht=f(Whhht1+Whxxt+bh)

  2. 输出层状态:
    y t = g ( W h y h t + b y ) y_t = g(W_{hy} h_t + b_y) yt=g(Whyht+by)

  3. 损失函数:
    L = ∑ t = 1 T ℓ ( y t , y ^ t ) \mathcal{L} = \sum_{t=1}^T \ell(y_t, \hat{y}_t) L=t=1T(yt,y^t)

  4. 输出层梯度:
    δ t y = ∂ ℓ ( y t , y ^ t ) ∂ y t ⋅ g ′ ( y t ) \delta^y_t = \frac{\partial \ell(y_t, \hat{y}_t)}{\partial y_t} \cdot g'(y_t) δty=yt(yt,y^t)g(yt)

梯度传播到隐藏层

我们通过链式法则计算隐藏层梯度。首先从输出层梯度开始传播,考虑激活函数 f f f 的导数 f ′ ( h t ) f'(h_t) f(ht)

隐藏层梯度的递归公式为:

δ t h = δ t y W h y T ⋅ f ′ ( h t ) + δ t + 1 h W h h T ⋅ f ′ ( h t ) \delta^h_t = \delta^y_t W_{hy}^T \cdot f'(h_t) + \delta^h_{t+1} W_{hh}^T \cdot f'(h_t) δth=δtyWhyTf(ht)+δt+1hWhhTf(ht)

假设激活函数 f f f 的导数在所有时间步长上都是一个常数 k k k,即 f ′ ( h t ) = k f'(h_t) = k f(ht)=k。为了简化,我们假设权重矩阵 W h h W_{hh} Whh W h y W_{hy} Why 也为常数。

梯度递归公式的展开

我们从最后一个时间步 T T T 开始,逐步向前展开递归公式:

δ T h = δ T y W h y T ⋅ k \delta^h_T = \delta^y_T W_{hy}^T \cdot k δTh=δTyWhyTk

对于 T − 1 T-1 T1 时间步:

δ T − 1 h = δ T − 1 y W h y T ⋅ k + δ T h W h h T ⋅ k \delta^h_{T-1} = \delta^y_{T-1} W_{hy}^T \cdot k + \delta^h_T W_{hh}^T \cdot k δT1h=δT1yWhyTk+δThWhhTk

δ T h \delta^h_T δTh带入:
= δ T − 1 y W h y T ⋅ k + ( δ T y W h y T ⋅ k ) W h h T ⋅ k = \delta^y_{T-1} W_{hy}^T \cdot k + (\delta^y_T W_{hy}^T \cdot k) W_{hh}^T \cdot k =δT1yWhyTk+(δTyWhyTk)WhhTk
= k δ T − 1 y W h y T + k 2 δ T y W h y T W h h T = k \delta^y_{T-1} W_{hy}^T + k^2 \delta^y_T W_{hy}^T W_{hh}^T =kδT1yWhyT+k2δTyWhyTWhhT

我们继续展开 T − 2 T-2 T2 时间步:

δ T − 2 h = δ T − 2 y W h y T ⋅ k + δ T − 1 h W h h T ⋅ k \delta^h_{T-2} = \delta^y_{T-2} W_{hy}^T \cdot k + \delta^h_{T-1} W_{hh}^T \cdot k δT2h=δT2yWhyTk+δT1hWhhTk
= δ T − 2 y W h y T ⋅ k + ( δ T − 1 y W h y T ⋅ k + δ T h W h h T ⋅ k ) W h h T ⋅ k = \delta^y_{T-2} W_{hy}^T \cdot k + \left( \delta^y_{T-1} W_{hy}^T \cdot k + \delta^h_T W_{hh}^T \cdot k \right) W_{hh}^T \cdot k =δT2yWhyTk+(δT1yWhyTk+δThWhhTk)WhhTk
= δ T − 2 y W h y T ⋅ k + δ T − 1 y W h y T W h h T ⋅ k 2 + δ T y W h y T W h h T W h h T ⋅ k 3 = \delta^y_{T-2} W_{hy}^T \cdot k + \delta^y_{T-1} W_{hy}^T W_{hh}^T \cdot k^2 + \delta^y_T W_{hy}^T W_{hh}^T W_{hh}^T \cdot k^3 =δT2yWhyTk+δT1yWhyTWhhTk2+δTyWhyTWhhTWhhTk3

推广到一般情况,对于时间步 ( t ):

δ t h = δ t y W h y T ⋅ k + δ t + 1 h W h h T ⋅ k \delta^h_t = \delta^y_t W_{hy}^T \cdot k + \delta^h_{t+1} W_{hh}^T \cdot k δth=δtyWhyTk+δt+1hWhhTk

递归展开后,我们可以看到梯度会逐步乘以 ( k ),并传播到前面的时间步。这意味着:

δ t h = δ t y ⋅ ( W h y T ⋅ k t ) \delta^h_t = \delta^y_t \cdot (W_{hy}^T \cdot k^t) δth=δty(WhyTkt)

推导公式

假设 W h y W_{hy} Why W h h W_{hh} Whh 为单位矩阵 I I I,我们简化得到:

δ t h = δ ⋅ k t \delta^h_t = \delta \cdot k^t δth=δkt

如果激活函数的导数 k < 1 k < 1 k<1 ,那么 k t k^t kt 会随着 t t t 增加而快速趋近于零,导致梯度消失。

具体示例

为了更直观地理解梯度消失和梯度爆炸,我们用一个简单的RNN模型和一个假设的初始梯度进行解释。

假设:

  • 输入序列长度为 ( T )。
  • 隐藏层激活函数为 ( tanh ⁡ \tanh tanh )。
  • 初始梯度为 ( δ = 1 \delta = 1 δ=1 )。
  • 每一步的激活函数导数 ( f ′ ( h t ) = k f'(h_t) = k f(ht)=k )(假设为常数)。
梯度消失示例

假设激活函数导数 k = 0.5 k = 0.5 k=0.5 ,即每一步的导数都小于 1。

随着时间步数 T T T 的增加,梯度会逐渐减小:

δ T h = δ ⋅ k T \delta^h_T = \delta \cdot k^T δTh=δkT

例如,当 T = 10 T = 10 T=10 时:

δ 10 h = 1 ⋅ 0. 5 10 = 1 ⋅ 0.00098 = 0.00098 \delta^h_{10} = 1 \cdot 0.5^{10} = 1 \cdot 0.00098 = 0.00098 δ10h=10.510=10.00098=0.00098

可以看到,梯度非常小,接近于零。

更进一步,如果 T = 20 T = 20 T=20

δ 20 h = 1 ⋅ 0. 5 20 = 1 ⋅ 0.00000095 = 0.00000095 \delta^h_{20} = 1 \cdot 0.5^{20} = 1 \cdot 0.00000095 = 0.00000095 δ20h=10.520=10.00000095=0.00000095

梯度几乎为零,说明模型无法有效更新权重,导致无法捕捉长期依赖关系。

梯度爆炸示例

假设激活函数导数 k = 1.5 k = 1.5 k=1.5 ,即每一步的导数都大于 1。

随着时间步数 T T T 的增加,梯度会逐渐增大:

δ T h = δ ⋅ k T \delta^h_T = \delta \cdot k^T δTh=δkT

例如,当 T = 10 T = 10 T=10 时:

δ 10 h = 1 ⋅ 1. 5 10 = 1 ⋅ 57.67 = 57.67 \delta^h_{10} = 1 \cdot 1.5^{10} = 1 \cdot 57.67 = 57.67 δ10h=11.510=157.67=57.67

可以看到,梯度非常大,导致训练不稳定。

更进一步,如果 T = 20 T = 20 T=20

δ 20 h = 1 ⋅ 1. 5 20 = 1 ⋅ 33252.32 = 33252.32 \delta^h_{20} = 1 \cdot 1.5^{20} = 1 \cdot 33252.32 = 33252.32 δ20h=11.520=133252.32=33252.32

梯度变得非常大,说明模型无法收敛,权重更新会过大,导致训练失败。

在这里插入图片描述

  • 梯度消失:图中红线表示的梯度随着时间步数 𝑇 增加而快速减小,趋近于零。这说明当时间步数增加时,梯度值变得非常小,无法有效更新权重,导致模型无法捕捉长期依赖关系。
  • 梯度爆炸:图中蓝线表示的梯度随着时间步数 𝑇 增加而快速增大。这说明当时间步数增加时,梯度值变得非常大,导致权重更新过大,训练过程变得不稳定,模型难以收敛。

解决梯度消失和梯度爆炸的方法

为了缓解梯度消失和梯度爆炸问题,可以采用以下几种常见的方法:

  1. 梯度裁剪(Gradient Clipping)

    • 将梯度的绝对值限制在某个阈值范围内,防止梯度爆炸。
    • 例如,当梯度超过某个阈值时,将其裁剪到这个阈值。
  2. 正则化方法

    • 使用L2正则化(权重衰减)防止过度活跃的神经元。
    • 增加权重更新时的惩罚项,控制权重值不至于过大。
  3. 批归一化(Batch Normalization)

    • 对每个时间步的隐藏状态进行归一化,稳定训练过程。
    • 通过归一化,控制每个时间步的输出范围,防止梯度过大或过小。
  4. 调整激活函数

    • 选择适当的激活函数(如ReLU、Leaky ReLU等),防止梯度消失和爆炸。
    • 例如,Leaky ReLU 在负区间也有非零导数,避免了完全的梯度消失问题。

为什么很小的梯度无法更新权重并导致无法捕捉长期依赖关系?

当梯度非常小时,反向传播的权重更新公式:

Δ W = − η ⋅ ∂ L ∂ W \Delta W = -\eta \cdot \frac{\partial \mathcal{L}}{\partial W} ΔW=ηWL

梯度项 ∂ L ∂ W \frac{\partial \mathcal{L}}{\partial W} WL 会非常小。这里, η \eta η 是学习率。当梯度接近零时,权重更新 Δ W \Delta W ΔW 也会接近零。这意味着神经网络的权重几乎不会发生变化,导致模型无法从训练数据中学习到有用的信息,从而无法有效捕捉长期依赖关系。

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

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

相关文章

采用LoRA方法微调llama3大语言模型

文章目录 前言一、Llama3模型简介1.下载llama3源码到linux服务器2.安装依赖3.测试预训练模型Meta-Llama-3-8B4.测试指令微调模型Meta-Llama3-8B-Instruct5.小结 二、LoRA微调Llama31.引入库2.编写配置文件3.LoRA训练的产物 三、测试新模型效果1.编写配置文件2.运行配置文件&…

QT教程-一,初识QT

目录 一,QT是什么&#xff1f;能够使用它做什么&#xff1f; 二&#xff0c;Qt 能够使用的语言 三&#xff0c;Qt主要用于什么领域&#xff1f; 四&#xff0c;Qt开发的软件 一,QT是什么&#xff1f;能够使用它做什么&#xff1f; Qt是一个跨平台的 C 开发库&#xff0c;主…

全球最高点赞记录,世界点赞第一名是谁?世界点赞第一人名字的由来

世界点赞第一人名字的由来&#xff1a; 起源与概念提出&#xff1a; 二十一世纪东方伟大的思想家哲学家教育家颜廷利教授&#xff0c;一位在中国21世纪早期便以其非凡才华和创新精神著称的学者&#xff0c;早在互联网尚未普及的20世纪90年代&#xff0c;就已经提出了“点赞”的…

python爬虫登录到海康相机管理页面

简述 1.最近接到个任务是在管理页面更改相机的某个参数&#xff0c;下载官方的sdk貌似没有提供这个接口&#xff0c;所以只能自己写爬虫登录发请求了。 1.主要步骤 1.1 发送get请求获取到salt&#xff0c;sessionID&#xff0c;challenge等信息 http://admin:123456192.168.…

交叉熵损失函数计算过程(tensorflow)

交叉熵损失函数通常用于多类分类损失函数计算。计算公式如下&#xff1a; P为真实值&#xff0c;Q为预测值。 使用tensorflow计算 import tensorflow as tf import keras# 创建一个示例数据集 # 假设有3个样本&#xff0c;每个样本有4个特征&#xff0c;共2个类别 # 目标标签…

2024最新私有化部署AI大模型,让每个人都有属于自己的AI助理

让每个人都拥有一个属于自己的本地大模型 下载Ollama 下载地址 ​ https://ollama.com/download ​ Ollama支持MacOS、Linux、Windows 解压 下载完成后&#xff0c;会得到一个Ollama-darwin.zip文件&#xff0c;解压后&#xff0c;以Mac为例是一个可运行文件&#xff1a;O…

AI应用案例:服务器智能分析管理系统

服务器硬件配置、性能状态、所运行的应用系统等信息分散于多个不同的信息管理系统。人为查询判断现有的服务器资源是否满足用户需求&#xff0c;且需结合资产管理系统与Maximo基础资源、性能监控、运维管理等各个系统互不关联&#xff0c;数据分散不能为运维管理提供完整一致的…

在Spring 当中存在的八大模式

在Spring 当中存在的八大模式 文章目录 在Spring 当中存在的八大模式每博一文案1. 简单工厂模式2. 工厂方法模式3. 单例模式4. 代理模式5. 装饰器模式6. 观察者模式7. 策略模式8. 模板方法模式最后&#xff1a; 每博一文案 我认为 “知世故而不世故” 才是真正意义上的成熟。回…

【PPT密码】PPT文件的两种不可编辑情况

不知道大家有没有遇到过&#xff0c;PPT文件无法编辑的情况&#xff0c;今天小编分享两种ppt文件不可编辑的原因以及解决方法。 情况一 如果打开ppt文件之后&#xff0c;发现幻灯片某些地方或者每张幻灯片同一个地方&#xff0c;无法编辑&#xff0c;这可能是因为PPT中设置了…

ISCC 2024 部分wp

文章目录 一、Misc1、Number_is_the_key2、FunZip3、擂台—— 重“隐”&#xff1b;4、RSA_KU5、时间刺客6、成语学习7、 精装四合一8、钢铁侠在解密9、有人让我给你带个话10、Magic_Keyboard11、工业互联网模拟仿真数据分析 二、Web1、还没想好名字的塔防游戏2、代码审计3、原…

Python数据分析实验四:数据分析综合应用开发

目录 一、实验目的与要求二、主要实验过程1、加载数据集2、数据预处理3、划分数据集4、创建模型估计器5、模型拟合6、模型性能评估 三、主要程序清单和运行结果四、实验体会 一、实验目的与要求 1、目的&#xff1a; 综合运用所学知识&#xff0c;选取有实际背景的应用问题进行…

【Python】【Scrapy 爬虫】理解HTML和XPath

为了从网页中抽取信息&#xff0c;必须对其结构有更多了解。我们快速浏览HTML、HTML的树状表示&#xff0c;以及在网页上选取信息的一种方式XPath。 HTML、DOM树表示以及XPath 互联网是如何工作的&#xff1f; 当两台电脑需要通信的时候&#xff0c;你必须要连接他们&#xff…

Android Studio实现MQTT协议的连接

1添加依赖 在项目中找到下图文件 打开文件 如下 plugins {alias(libs.plugins.android.application) }android {namespace "com.example.mqtt_04"compileSdk 34defaultConfig {applicationId "com.example.mqtt_04"minSdk 27targetSdk 34versionCo…

小红书无限加群脚本无需ROOT【使用简单无教程】

小红书无限加群脚本无需ROOT&#xff0c;包含了对应的小红书版本【使用简单无教程】 链接&#xff1a;https://pan.baidu.com/s/1HkLhahmHDFMKvqCC3Q3haA?pwd6hzf 提取码&#xff1a;6hzf

【Vue】computed 和 methods 的区别

概述 在使用时&#xff0c;computed 当做属性使用&#xff0c;而 methods 则当做方法调用computed 可以具有 getter 和 setter&#xff0c;因此可以赋值&#xff0c;而 methods 不行computed 无法接收多个参数&#xff0c;而 methods 可以computed 具有缓存&#xff0c;而 met…

Python函数、类和方法

大家好&#xff0c;当涉及到编写可维护、可扩展且易于测试的代码时&#xff0c;Python提供了一些强大的工具和概念&#xff0c;其中包括函数、类和方法。这些是Python编程中的核心要素&#xff0c;可以帮助我们构建高效的测试框架和可靠的测试用例。 本文将探讨Python中的函数、…

大语言模型的工程技巧(三)——分布式计算

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文将讨论如何利用多台机器进行神经网络的分布式训练。利用多台机器来加速大语言模型的训练&#xff0c;是其获得成功的重要原…

BUUCTF靶场[Web] [极客大挑战 2019]Havefun1、[HCTF 2018]WarmUp1、[ACTF2020 新生赛]Include

[web][极客大挑战 2019]Havefun1 考点&#xff1a;前端、GET传参 点开网址&#xff0c;发现是这个界面 点击界面没有回显&#xff0c;老规矩查看源代码&#xff0c;看到以下代码 代码主要意思为&#xff1a; 用get传参&#xff0c;将所传的参数给cat&#xff0c;如果catdog…

Linux基础(五):常用基本命令

从本节开始&#xff0c;我们正式进入Linux的学习&#xff0c;通过前面的了解&#xff0c;我们知道我们要以命令的形式使用操作系统&#xff08;使用操作系统提供的各类命令&#xff0c;以获得字符反馈的形式去使用操作系统。&#xff09;&#xff0c;因此&#xff0c;我们是很有…

【全开源】点餐小程序系统源码(ThinkPHP+FastAdmin+UniApp)

基于ThinkPHPFastAdminUniApp开发的点餐微信小程序&#xff0c;类似肯德基&#xff0c;麦当劳&#xff0c;喜茶等小程序多店铺模式&#xff0c;支持子商户模式&#xff0c;提供全部前后台无加密源代码和数据库&#xff0c;支持私有化部署。 革新餐饮行业的智慧点餐解决方案 一…