Kronecker分解(K-FAC):让自然梯度在深度学习中飞起来

Kronecker分解(K-FAC):让自然梯度在深度学习中飞起来

在深度学习的优化中,自然梯度下降(Natural Gradient Descent)是一个强大的工具,它利用Fisher信息矩阵(FIM)调整梯度方向,让参数更新更高效。然而,Fisher信息矩阵的计算复杂度是个大难题——对于参数量巨大的神经网络,直接计算和求逆几乎是不可能的。这时,Kronecker分解(Kronecker-Factored Approximate Curvature,简称K-FAC)登场了。它通过巧妙的近似,让自然梯度在深度学习中变得实用。今天,我们就来聊聊K-FAC的原理、优势,以及参数正交性如何给它加分。


Fisher信息矩阵的挑战

Fisher信息矩阵 ( I ( θ ) I(\theta) I(θ) ) 衡量了模型输出对参数 ( θ \theta θ ) 的敏感度,在自然梯度下降中的更新公式是:

θ t + 1 = θ t − η I ( θ ) − 1 ∂ L ∂ θ \theta_{t+1} = \theta_t - \eta I(\theta)^{-1} \frac{\partial L}{\partial \theta} θt+1=θtηI(θ)1θL

这里,( I ( θ ) − 1 I(\theta)^{-1} I(θ)1 ) 是Fisher信息矩阵的逆,起到“校正”梯度的作用。但问题来了:

  • 存储复杂度:如果模型有 ( n n n ) 个参数,( I ( θ ) I(\theta) I(θ) ) 是一个 ( n × n n \times n n×n ) 的矩阵,需要 ( O ( n 2 ) O(n^2) O(n2) ) 的存储空间。
  • 计算复杂度:求逆需要 ( O ( n 3 ) O(n^3) O(n3)) 的时间复杂度。

对于一个有百万参数的神经网络,( n 2 n^2 n2 ) 和 ( n 3 n^3 n3 ) 是天文数字,直接计算完全不现实。K-FAC的出现,就是要解决这个“卡脖子”的问题。


什么是Kronecker分解(K-FAC)?

K-FAC是一种近似方法,全称是“Kronecker-Factored Approximate Curvature”。它的核心思想是利用神经网络的层级结构,将Fisher信息矩阵分解成小块矩阵,然后用Kronecker乘积(一种特殊的矩阵乘法)来近似表示。这样,既降低了计算成本,又保留了自然梯度的大部分优势。

通俗比喻

想象你在整理一个巨大的仓库(Fisher信息矩阵),里面堆满了杂乱的货物(参数间的关系)。直接搬运整个仓库太费力,而K-FAC就像把仓库分成几个小隔间(每一层网络一个),每个隔间用两个简单清单(小矩阵)描述货物分布。这样,你不用搬整个仓库,只需处理小隔间,就能大致知道货物的布局。


K-FAC的原理

1. 分层近似

神经网络通常是分层的,每一层有自己的权重(例如 ( W l W_l Wl ))。K-FAC假设Fisher信息矩阵 ( I ( θ ) I(\theta) I(θ) ) 对不同层之间的参数交叉项近似为零,只关注每层内部的参数关系。这样,( I ( θ ) I(\theta) I(θ) ) 变成一个块对角矩阵(block-diagonal matrix),每个块对应一层:

I ( θ ) ≈ diag ( I 1 , I 2 , … , I L ) I(\theta) \approx \text{diag}(I_1, I_2, \dots, I_L) I(θ)diag(I1,I2,,IL)

其中 ( I l I_l Il ) 是第 ( l l l ) 层的Fisher信息矩阵。

2. Kronecker分解

对于每一层 ( l l l ),权重 ( W l W_l Wl ) 是一个矩阵(比如 ( m × n m \times n m×n ))。对应的Fisher信息矩阵 ( I l I_l Il ) 本来是一个 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 的大矩阵,直接计算很麻烦。K-FAC观察到,神经网络的梯度可以分解为输入和输出的贡献,于是近似为:

I l ≈ A l ⊗ G l I_l \approx A_l \otimes G_l IlAlGl

  • ( A l A_l Al ):输入激活的协方差矩阵(大小 ( m × m m \times m m×m )),表示前一层输出的统计特性。
  • ( G l G_l Gl ):梯度相对于输出的协方差矩阵(大小 ( n × n n \times n n×n )),表示当前层输出的统计特性。
  • ( ⊗ \otimes ):Kronecker乘积,将两个小矩阵“组合”成一个大矩阵。后文有解释。

3. 高效求逆

Kronecker乘积有个妙处:如果 ( I l = A l ⊗ G l I_l = A_l \otimes G_l Il=AlGl ),其逆可以通过小矩阵的逆计算:

I l − 1 = A l − 1 ⊗ G l − 1 I_l^{-1} = A_l^{-1} \otimes G_l^{-1} Il1=Al1Gl1

  • ( A l A_l Al ) 是 ( m × m m \times m m×m ),求逆是 ( O ( m 3 ) O(m^3) O(m3) )。
  • ( G l G_l Gl ) 是 ( n × n n \times n n×n ),求逆是 ( O ( n 3 ) O(n^3) O(n3) )。

相比直接求 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 矩阵的 ( O ( ( m n ) 3 ) O((mn)^3) O((mn)3) ),K-FAC把复杂度降到了 ( O ( m 3 + n 3 ) O(m^3 + n^3) O(m3+n3) ),通常 ( m m m ) 和 ( n n n ) 远小于 ( m ⋅ n m \cdot n mn ),节省巨大。


K-FAC的数学细节

假设第 ( l l l ) 层的输出为 ( a l = W l h l − 1 a_l = W_l h_{l-1} al=Wlhl1 )(( h l − 1 h_{l-1} hl1 ) 是前一层激活),损失为 ( L L L )。Fisher信息矩阵的精确定义是:

I l = E [ vec ( ∂ L ∂ a l h l − 1 T ) vec ( ∂ L ∂ a l h l − 1 T ) T ] I_l = E\left[ \text{vec}\left( \frac{\partial L}{\partial a_l} h_{l-1}^T \right) \text{vec}\left( \frac{\partial L}{\partial a_l} h_{l-1}^T \right)^T \right] Il=E[vec(alLhl1T)vec(alLhl1T)T]

K-FAC近似为:

I l ≈ E [ h l − 1 h l − 1 T ] ⊗ E [ ∂ L ∂ a l ∂ L ∂ a l T ] = A l ⊗ G l I_l \approx E\left[ h_{l-1} h_{l-1}^T \right] \otimes E\left[ \frac{\partial L}{\partial a_l} \frac{\partial L}{\partial a_l}^T \right] = A_l \otimes G_l IlE[hl1hl1T]E[alLalLT]=AlGl

  • ( A l = E [ h l − 1 h l − 1 T ] A_l = E[h_{l-1} h_{l-1}^T] Al=E[hl1hl1T] ):输入协方差。
  • ( G l = E [ ∂ L ∂ a l ∂ L ∂ a l T ] G_l = E\left[ \frac{\partial L}{\partial a_l} \frac{\partial L}{\partial a_l}^T \right] Gl=E[alLalLT] ):输出梯度协方差。

自然梯度更新变成:

vec ( Δ W l ) = ( A l − 1 ⊗ G l − 1 ) vec ( ∂ L ∂ W l ) \text{vec}(\Delta W_l) = (A_l^{-1} \otimes G_l^{-1}) \text{vec}\left( \frac{\partial L}{\partial W_l} \right) vec(ΔWl)=(Al1Gl1)vec(WlL)

实际中,( A l A_l Al ) 和 ( G l G_l Gl ) 通过小批量数据的平均值估计,动态更新。


K-FAC的优势

1. 计算效率

从 ( O ( n 3 ) O(n^3) O(n3) ) 降到 ( O ( m 3 + n 3 ) O(m^3 + n^3) O(m3+n3) ),K-FAC让自然梯度在大型网络中可行。例如,一个隐藏层有 1000 个神经元,普通方法需要处理百万级矩阵,而K-FAC只需处理千级矩阵。

2. 保留曲率信息

虽然是近似,K-FAC依然捕捉了每层参数的局部曲率,帮助模型更快收敛,尤其在损失函数表面复杂时。

3. 并行性

每一层的 ( A l A_l Al ) 和 ( G l G_l Gl ) 可以独立计算,非常适合GPU并行加速。


参数正交性如何助力K-FAC?

参数正交性是指Fisher信息矩阵的非对角元素 ( I i j = 0 I_{ij} = 0 Iij=0 )(( i ≠ j i \neq j i=j )),意味着参数间信息独立。K-FAC天然假设层间正交(块对角结构),但层内参数的正交性也能进一步简化计算。

1. 更接近对角形式

如果模型设计时让权重尽量正交(比如通过正交初始化,( W l W l T = I W_l W_l^T = I WlWlT=I )),( A l A_l Al ) 和 ( G l G_l Gl ) 的非对角元素会减小,( I l I_l Il ) 更接近对角矩阵。求逆时计算量进一步降低,甚至可以用简单的逐元素除法近似。

2. 提高稳定性

正交参数减少梯度方向的耦合,自然梯度更新更稳定,避免震荡。例如,卷积网络中正交卷积核可以增强K-FAC的效果。

3. 实际应用

在RNN或Transformer中,正交初始化(如Hennig的正交矩阵)结合K-FAC,能显著提升训练速度和性能。


K-FAC的应用场景

  • 深度神经网络:K-FAC在DNN优化中加速收敛,常用于图像分类任务。
  • 强化学习:如ACKTR算法,结合K-FAC改进策略优化。
  • 生成模型:变分自编码器(VAE)中,K-FAC优化变分参数。

总结

Kronecker分解(K-FAC)通过分层和Kronecker乘积,将Fisher信息矩阵的计算复杂度从“天文数字”降到可接受范围,让自然梯度下降在深度学习中大放异彩。它不仅高效,还保留了曲率信息,适合现代大规模模型。参数正交性则是它的好帮手,通过减少参数间干扰,让K-FAC更简单、更稳定。下次训练网络时,不妨试试K-FAC,也许会带来惊喜!

补充:解释Kronecker乘积

详细解释Kronecker乘积(Kronecker Product)的含义,以及为什么K-FAC观察到神经网络的梯度可以分解为输入和输出的贡献,从而将其近似为 ( I l ≈ A l ⊗ G l I_l \approx A_l \otimes G_l IlAlGl )。


什么是Kronecker乘积?

Kronecker乘积是一种特殊的矩阵运算,用符号 ( ⊗ \otimes ) 表示。它可以将两个较小的矩阵“组合”成一个更大的矩阵。具体来说,假设有两个矩阵:

  • ( A A A ) 是 ( m × m m \times m m×m ) 的矩阵。
  • ( G G G ) 是 ( n × n n \times n n×n ) 的矩阵。

它们的Kronecker乘积 ( A ⊗ G A \otimes G AG ) 是一个 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 的矩阵,定义为:

A ⊗ G = [ a 11 G a 12 G ⋯ a 1 m G a 21 G a 22 G ⋯ a 2 m G ⋮ ⋮ ⋱ ⋮ a m 1 G a m 2 G ⋯ a m m G ] A \otimes G = \begin{bmatrix} a_{11} G & a_{12} G & \cdots & a_{1m} G \\ a_{21} G & a_{22} G & \cdots & a_{2m} G \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} G & a_{m2} G & \cdots & a_{mm} G \end{bmatrix} AG= a11Ga21Gam1Ga12Ga22Gam2Ga1mGa2mGammG

其中,( a i j a_{ij} aij ) 是 ( A A A ) 的第 ( i i i ) 行第 ( j j j ) 列元素,( G G G ) 是整个 ( n × n n \times n n×n ) 矩阵。也就是说,( A A A ) 的每个元素 ( a i j a_{ij} aij ) 都被放大为一个 ( n × n n \times n n×n ) 的块矩阵 ( a i j G a_{ij} G aijG )。

通俗解释

想象你在做一个拼图,( A A A ) 是一个 ( m × m m \times m m×m ) 的模板,告诉你每个位置的重要性(比如协方差);( G G G ) 是一个 ( n × n n \times n n×n ) 的小图案。Kronecker乘积就像把 ( G G G ) 这个图案按照 ( A A A ) 的模板放大排列,形成一个更大的拼图,最终大小是 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) )。

例子

假设 ( A = [ 1 2 3 4 ] A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} A=[1324] )(2×2),( G = [ 0 1 1 0 ] G = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} G=[0110] )(2×2),则:

A ⊗ G = [ 1 ⋅ [ 0 1 1 0 ] 2 ⋅ [ 0 1 1 0 ] 3 ⋅ [ 0 1 1 0 ] 4 ⋅ [ 0 1 1 0 ] ] A \otimes G = \begin{bmatrix} 1 \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} & 2 \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} \\ 3 \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} & 4 \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} \end{bmatrix} AG= 1[0110]3[0110]2[0110]4[0110]

= [ 0 1 0 2 1 0 2 0 0 3 0 4 3 0 4 0 ] = \begin{bmatrix} 0 & 1 & 0 & 2 \\ 1 & 0 & 2 & 0 \\ 0 & 3 & 0 & 4 \\ 3 & 0 & 4 & 0 \end{bmatrix} = 0103103002042040

结果是一个 4×4 矩阵(( 2 ⋅ 2 × 2 ⋅ 2 2 \cdot 2 \times 2 \cdot 2 22×22 ))。


K-FAC为何用Kronecker乘积近似?

现在我们来看K-FAC为什么观察到神经网络的梯度可以分解为输入和输出的贡献,并用 ( I l ≈ A l ⊗ G l I_l \approx A_l \otimes G_l IlAlGl ) 来近似Fisher信息矩阵。

背景:Fisher信息矩阵的定义

对于第 ( l l l ) 层的权重 ( W l W_l Wl )(一个 ( m × n m \times n m×n ) 矩阵),Fisher信息矩阵 ( I l I_l Il ) 是关于 ( W l W_l Wl ) 的二阶统计量。假设输出为 ( a l = W l h l − 1 a_l = W_l h_{l-1} al=Wlhl1 )(( h l − 1 h_{l-1} hl1 ) 是前一层激活),损失为 ( L L L ),精确的Fisher信息矩阵是:

I l = E [ vec ( ∂ L ∂ a l h l − 1 T ) vec ( ∂ L ∂ a l h l − 1 T ) T ] I_l = E\left[ \text{vec}\left( \frac{\partial L}{\partial a_l} h_{l-1}^T \right) \text{vec}\left( \frac{\partial L}{\partial a_l} h_{l-1}^T \right)^T \right] Il=E[vec(alLhl1T)vec(alLhl1T)T]

这里:

  • ( ∂ L ∂ a l \frac{\partial L}{\partial a_l} alL ) 是损失对输出的梯度(大小为 ( n × 1 n \times 1 n×1 ))。
  • ( h l − 1 h_{l-1} hl1 ) 是输入激活(大小为 ( m × 1 m \times 1 m×1 ))。
  • ( ∂ L ∂ a l h l − 1 T \frac{\partial L}{\partial a_l} h_{l-1}^T alLhl1T ) 是 ( W l W_l Wl ) 的梯度(( m × n m \times n m×n ) 矩阵)。
  • ( vec ( ⋅ ) \text{vec}(\cdot) vec() ) 将矩阵拉成向量,( I l I_l Il ) 是 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 的。

直接计算这个期望需要存储和操作一个巨大矩阵,复杂度为 ( O ( ( m n ) 2 ) O((mn)^2) O((mn)2) )。

K-FAC的观察:梯度分解

K-FAC注意到,神经网络的梯度 ( ∂ L ∂ W l = ∂ L ∂ a l h l − 1 T \frac{\partial L}{\partial W_l} = \frac{\partial L}{\partial a_l} h_{l-1}^T WlL=alLhl1T ) 天然具有“输入”和“输出”的分离结构:

  • 输入贡献:( h l − 1 h_{l-1} hl1 ) 是前一层的激活,决定了梯度的“空间结构”。
  • 输出贡献:( ∂ L ∂ a l \frac{\partial L}{\partial a_l} alL ) 是当前层的输出梯度,决定了梯度的“强度”。

这两个部分是外积(outer product)的形式,提示我们可以分别统计它们的特性,而不是直接算整个大矩阵的协方差。

分解为输入和输出的协方差

K-FAC假设梯度的期望可以近似分解为输入和输出的独立统计量:

I l ≈ E [ h l − 1 h l − 1 T ] ⊗ E [ ∂ L ∂ a l ∂ L ∂ a l T ] I_l \approx E\left[ h_{l-1} h_{l-1}^T \right] \otimes E\left[ \frac{\partial L}{\partial a_l} \frac{\partial L}{\partial a_l}^T \right] IlE[hl1hl1T]E[alLalLT]

  • ( A l = E [ h l − 1 h l − 1 T ] A_l = E[h_{l-1} h_{l-1}^T] Al=E[hl1hl1T] ):输入激活的协方差矩阵(( m × m m \times m m×m )),捕捉了 ( h l − 1 h_{l-1} hl1 ) 的统计特性。
  • ( G l = E [ ∂ L ∂ a l ∂ L ∂ a l T ] G_l = E\left[ \frac{\partial L}{\partial a_l} \frac{\partial L}{\partial a_l}^T \right] Gl=E[alLalLT] ):输出梯度的协方差矩阵(( n × n n \times n n×n )),捕捉了后续层反馈的统计特性。

为什么用Kronecker乘积 ( ⊗ \otimes )?因为梯度 ( ∂ L ∂ W l \frac{\partial L}{\partial W_l} WlL ) 是一个矩阵,其向量化形式 ( vec ( ∂ L ∂ W l ) \text{vec}(\frac{\partial L}{\partial W_l}) vec(WlL) ) 的协方差天然可以用输入和输出的外积结构表示。Kronecker乘积正好能将 ( A l A_l Al ) 和 ( G l G_l Gl ) “组合”成一个 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 的矩阵,与 ( I l I_l Il ) 的维度一致。

为什么这个近似合理?
  1. 结构假设

    • 神经网络的分层设计让输入 ( h l − 1 h_{l-1} hl1 ) 和输出梯度 ( ∂ L ∂ a l \frac{\partial L}{\partial a_l} alL ) 在统计上相对独立。
    • 这种分解假设 ( h l − 1 h_{l-1} hl1 ) 和 ( ∂ L ∂ a l \frac{\partial L}{\partial a_l} alL ) 的相关性主要通过外积体现,忽略了更高阶的交叉项。
  2. 维度匹配

    • ( A l ⊗ G l A_l \otimes G_l AlGl ) 生成一个 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 矩阵,与 ( I l I_l Il ) 的维度一致。
    • 它保留了输入和输出的主要统计信息,同时简化了计算。
  3. 经验验证

    • 实验表明,这种近似在实践中效果很好,尤其在全连接层和卷积层中,能捕捉梯度曲率的主要特征。

为什么分解为输入和输出的贡献?

回到K-FAC的观察:神经网络的梯度 ( ∂ L ∂ W l = ∂ L ∂ a l h l − 1 T \frac{\partial L}{\partial W_l} = \frac{\partial L}{\partial a_l} h_{l-1}^T WlL=alLhl1T ) 是一个外积形式,这种结构启发我们分开考虑:

  • 输入端(( h l − 1 h_{l-1} hl1 )):它来自前一层,反映了数据的空间分布(如激活的协方差)。
  • 输出端(( ∂ L ∂ a l \frac{\partial L}{\partial a_l} alL )):它来自后续层,反映了损失对当前输出的敏感度。

在神经网络中,梯度本质上是“输入”和“输出”交互的结果。K-FAC利用这一点,将Fisher信息矩阵分解为两部分的乘积,而不是直接处理整个权重矩阵的复杂关系。这种分解不仅符合直觉(网络是层层传递的),也大大降低了计算负担。


总结

Kronecker乘积 ( ⊗ \otimes ) 是K-FAC的核心工具,它将输入协方差 ( A l A_l Al ) 和输出梯度协方差 ( G l G_l Gl ) 组合成一个大矩阵,近似表示Fisher信息矩阵 ( I l I_l Il )。这种近似的依据是神经网络梯度的外积结构——输入和输出的贡献可以分开统计。K-FAC通过这种方式,把原本难以计算的 ( ( m ⋅ n ) × ( m ⋅ n ) (m \cdot n) \times (m \cdot n) (mn)×(mn) ) 矩阵问题,简化成了两个小矩阵的操作,既高效又实用。

后记

2025年2月24日22点48分于上海,在Grok3大模型辅助下完成。

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

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

相关文章

【HTML— 快速入门】HTML 基础

准备工作 vscode下载 百度网盘 Subline Text 下载 Sublime Text下载 百度网盘 vscode 下载 Sublime Text 是一款轻量好用的文本编辑器,我们在写前端代码时,使用 Sublime Text 打开比使用记事本打开,得到的代码体验更好,比 vscode…

鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar)

鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar) 1、效果展示2、下载 DevEco Studio3、创建项目4、新建页面模板5、更改应用信息6、新建以下页面7、Index.ets8、真机运行9、图片资源文件 1、效果展示 2、下载 DevEco Studio 访问官网根据自己的版本…

自动驾驶泊车算法详解(一)

自动驾驶泊车算法是自动驾驶技术中的重要组成部分,主要用于实现车辆在复杂场景下的自动泊车功能(如垂直泊车、侧方位泊车、斜列泊车等)。其核心目标是通过感知、规划和控制技术,使车辆在无人工干预的情况下安全、高效地完成泊车动…

鸿蒙next 点击穿透实现

点击穿透可以参考华为开发的保留文章,该章节只能在developer preview版本下查看 点击穿透 主要的方法是hitTestBehavior // xxx.ets Entry Component struct HitTestBehaviorExample {build() {// outer stackStack() {Button(outer button).onTouch((event) > {console.i…

27.[前端开发-JavaScript基础]Day04-函数基本使用-递归-变量作用域-函数式编程

一、JavaScript函数 1 认识JavaScript函数 程序中的foo、bar、baz 认识函数 函数使用的步骤 2 函数的声明和调用 声明和调用函数 函数的参数 有参数的函数练习 函数的返回值 函数的练习 arguments参数(JS高级再学习) 3 函数的递归调用 函数中调用函数…

蓝桥杯练习代码

一、最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入:strs = ["flower","flow","flight"] 输出:"fl"示例 2: 输入:strs = ["dog",&q…

添加成对约束后的标签传播算法研究:使用Python语言编写算法,在空手道数据集下验证算法的准确性,在一定程度上解决非对齐问题

背景: 辅导的过程中遇到了一个比较新颖的问题,下面是我对这个问题的分析和简要思路介绍。 思路分析: 这算机器学习下面的无监督学习,标签传播算法简称LPA,传统的标签传播算法会出现非对齐问题,一句话描述就…

鸿蒙开发第4篇__关于在鸿蒙应用中使用Java语言进行设计

本博文很重要 HarmonyOS从 API8 开始不再支持使用Java作为开发语言,未来的新功能将在ArkTS中实现. API 8对应的是HarmonyOS 3.0.0版本。请看下图: 因此, 读者如果看到类似《鸿蒙应用程序开发》(2021年版本 清华大学出版计)书 还使用Java语言…

sklearn机器学习 Python代码通用模板

以下是一个使用 scikit-learn(sklearn)进行机器学习的通用 Python 代码模板。这个模板涵盖了数据加载、预处理、模型训练、评估和预测的基本流程,适用于常见的机器学习任务。 python # 导入必要的库 import numpy as np import pandas as …

P9420 [蓝桥杯 2023 国 B] 双子数--最高效的质数筛【埃拉托斯特尼筛法】

P9420 [蓝桥杯 2023 国 B] 双子数 题目 分析代码 题目 分析 首先&#xff0c;我们如何找到双子数&#xff1f; 1&#xff09;找到所有质数满足范围内的质数&#xff08;即至少质数^2<23333333333333) 我们看见双子数x的范围2333<x<23333333333333&#xff0c;又因为…

deepseek 导出导入模型(docker)

前言 实现导出导入deepseek 模型。deepseek 安装docker下参考 docker 导出模型 实际生产环境建议使用docker-compose.yml进行布局&#xff0c;然后持久化ollama模型数据到本地参考 echo "start ollama" docker start ollama#压缩容器内文件夹&#xff0c;然后拷贝…

mysql有索引但是查询没有使用索引是什么问题

关键原因分析 索引选择性问题 如果 order_id 没有索引&#xff0c;即使 insert_time 有索引&#xff0c;优化器可能认为先通过 order_id 过滤数据更高效。但由于 order_id 无索引&#xff0c;只能全表扫描后过滤。即使 insert_time 有索引&#xff0c;如果满足 insert_time >…

【Qt】为程序增加闪退crash报告日志

背景 随着软件代码量的增加&#xff0c;软件崩溃闪退的肯能行越来越大&#xff0c;其中一些是难以复现的&#xff0c;比如访问了访问了非法地址、被操作系统杀死等。 为此&#xff0c;在软件出现闪退情况时&#xff0c;尽可能多的记录闪退发生时信息&#xff0c;对排查闪退原…

C#从入门到精通(35)—如何防止winform程序因为误操作被关闭

前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发的上位机软件运行起来以后,一般在右上角都有一个关闭按钮,正常情况下点击关闭按钮就能关闭软件,但是不排除我们不想关闭软件,但是因为不…

ffmpeg avdevice_register_all 注册设备的作用

在 FFmpeg 中&#xff0c;avdevice_register_all() 是一个用于注册所有输入和输出设备的函数。它是 FFmpeg 的 libavdevice 模块的一部分&#xff0c;专门用于处理音频和视频的输入/输出设备&#xff08;如摄像头、麦克风、屏幕捕获等&#xff09;。 以下是对 avdevice_regist…

[RH342]tcpdump

[RH342]tcpdump 1. 题目2. 解题 1. 题目 服务器serverc 和 servera 之间有进程定期发送一个明文密码,找出它2. 解题 找出通信端口 抓包分析 tcpdump -X -vv port 6644红框中就是密码,所以密码是root123

连接Sql Server时报错无法通过使用安全套接字层加密与 SQL Server 建立安全连接

文章目录 一. 前言二. 解决方案 方案1方案2 三. 总结 一. 前言 在《数据库原理》这门课的实验上&#xff0c;需要使用SQL Server&#xff0c;然后使用jdbc连接sql server突然报错为&#xff1a;SQLServerException: “Encrypt”属性设置为“true”且 “trustServerCertific…

从 Spring Boot 2 升级到 Spring Boot 3 的终极指南

一、升级前的核心准备 1. JDK 版本升级 Spring Boot 3 强制要求 Java 17 及以上版本。若当前项目使用 Java 8 或 11&#xff0c;需按以下步骤操作&#xff1a; 安装 JDK 17&#xff1a;从 Oracle 或 OpenJDK 官网下载&#xff0c;配置环境变量&#xff08;如 JAVA_HOME&…

Buildroot 添加自定义模块-内置文件到文件系统

目录 概述实现步骤1. 创建包目录和文件结构2. 配置 Config.in3. 定义 cp_bin_files.mk4. 添加源文件install.shmy.conf 5. 配置与编译 概述 Buildroot 是一个高度可定制和模块化的嵌入式 Linux 构建系统&#xff0c;适用于从简单到复杂的各种嵌入式项目. buildroot的源码中bui…

物联网通信应用案例之《智慧农业》

案例概述 在智慧农业方面&#xff0c;一般的应用场景为可以自动检测温度湿度等一系列环境情况并且可以自动做出相应的处理措施如简单的浇水和温度控制等&#xff0c;且数据情况可远程查看&#xff0c;以及用户可以实现远程控制。 基本实现原理 传感器通过串口将数据传递到Wi…