【数学】主成分分析(PCA)的详细深度推导过程

本文基于Deep Learning (2017, MIT),推导过程补全了所涉及的知识及书中推导过程中跳跃和省略的部分。
blog

1 概述

现代数据集,如网络索引、高分辨率图像、气象学、实验测量等,通常包含高维特征,高纬度的数据可能不清晰、冗余,甚至具有误导性。数据可视化和解释变量之间的关系很困难,而使用这种高维数据训练的神经网络模型往往容易出现过拟合(维度诅咒)。
主成分分析(PCA)是一种简单而强大的无监督机器学习技术,用于数据降维。它旨在从大型变量集中提取一个较小的数据集,同时尽可能保留原始信息和特征(有损压缩)。PCA有助于识别数据集中最显著和有意义的特征,使数据易于可视化。应用场景包括:统计学、去噪和为机器学习算法预处理数据。

  • 主成分是什么?
    主成分是构建为原始变量的线性组合的新变量。这些新变量是不相关的,并且包含原始数据中大部分的信息。

2 背景数学知识

这些知识对下一节的推导很重要。

  • 正交向量和矩阵:
    • 如果两个向量垂直,则它们是正交的。即两个向量的点积为零。
    • 正交矩阵是一个方阵,其行和列是相互正交的单位向量;每两行和两列的点积为零,每一行和每一列的大小为1。
    • 如果 A T = A − 1 A^T=A^{-1} AT=A1 A A T = A T A = I AA^T=A^TA=I AAT=ATA=I,则 A A A是正交矩阵。
    • 在机器人学中,旋转矩阵通常是一个 3 × 3 3\times3 3×3的正交矩阵,在空间变换中它会旋转向量的方向但保持原始向量的大小。
  • 矩阵、向量乘法规则:
    • ( A B ) T = B T A T (AB)^T=B^TA^T (AB)T=BTAT,两个矩阵的乘积的转置。
    • a ⃗ T b ⃗ = b ⃗ T a ⃗ \vec{a}^T\vec{b}=\vec{b}^T\vec{a} a Tb =b Ta ,两个结果都是标量,标量的转置是相同的。
    • ( A + B ) C = A C + B C (A + B)C = AC + BC (A+B)C=AC+BC,乘法是可分配的。
    • A B ≠ B A AB \neq{} BA AB=BA,乘法一般不满足交换律。
    • A ( B C ) = ( A B ) C A(BC)=(AB)C A(BC)=(AB)C,乘法满足结合律。
  • 对称矩阵:
    • A = A T A=A^T A=AT A A A是对称矩阵。
    • X T X X^TX XTX是对称矩阵,因为 ( X T X ) T = X T X (X^TX)^T=X^TX (XTX)T=XTX
  • 向量导数规则( B B B是常量矩阵):
    • d ( x T B ) / d x = B d(x^TB)/dx=B d(xTB)/dx=B
    • d ( x T x ) / d x = 2 x d(x^Tx)/dx=2x d(xTx)/dx=2x
    • d ( x T B x ) / d x = 2 B x d(x^TBx)/dx=2Bx d(xTBx)/dx=2Bx
  • 矩阵迹规则:
    • T r ( A ) = T r ( A T ) Tr(A)=Tr(A^T) Tr(A)=Tr(AT)
    • T r ( A B ) = T r ( B A ) Tr(AB)=Tr(BA) Tr(AB)=Tr(BA)
    • T r ( A ) = ∑ i λ i Tr(A)=\sum_i{\lambda_i} Tr(A)=iλi,其中 λ \lambda λ A A A的特征值。
    • 迹在循环移位下不变: T r ( A B C D ) = T r ( B C D A ) = T r ( C D A B ) = T r ( D A B C ) Tr(ABCD)=Tr(BCDA)=Tr(CDAB)=Tr(DABC) Tr(ABCD)=Tr(BCDA)=Tr(CDAB)=Tr(DABC)
  • 向量和矩阵范数:
    • 向量的 L 2 L^2 L2范数,也称为欧几里得范数: ∣ ∣ x ∣ ∣ 2 = ∑ i ∣ x i ∣ 2 ||x||_2=\sqrt{\sum_i|x_i|^2} ∣∣x2=ixi2
    • 通常使用平方的 L 2 L^2 L2范数来衡量向量的大小,可以计算为 x T x x^Tx xTx
    • Frobenius范数用于衡量矩阵的大小: ∣ ∣ A ∣ ∣ F = ∑ i , j A i , j 2 ||A||_F=\sqrt{\sum_{i,j}A^2_{i,j}} ∣∣AF=i,jAi,j2
    • Frobenius范数是所有矩阵元素的绝对平方和的平方根。
    • Frobenius范数是矩阵版本的欧几里得范数。
  • 特征值分解和特征值:
    • 方阵 A A A的特征向量是一个非零向量 v v v,使得 A A A的乘法仅改变 v v v的比例: A v = λ v Av=\lambda v Av=λv λ \lambda λ是特征值, v v v是特征向量。
    • 假设矩阵 A A A n n n个线性无关的特征向量 v ( i ) v^{(i)} v(i),我们可以将所有特征向量连接起来形成一个矩阵 V = [ v ( 1 ) , … , v ( n ) ] V=[v^{(1)},\ldots,v^{(n)}] V=[v(1),,v(n)],并通过连接所有特征值 λ = [ λ 1 , … , λ n ] T \lambda=[\lambda_1,\ldots,\lambda_n]^T λ=[λ1,,λn]T形成一个向量,那么 A A A特征分解 A = V d i a g ( λ ) V − 1 A=Vdiag(\lambda)V^{-1} A=Vdiag(λ)V1
    • 每个实对称矩阵都可以分解为 A = Q Λ Q T A=Q\Lambda Q^T A=QΛQT,其中 Q Q Q是由 A A A的特征向量组成的正交矩阵, Λ \Lambda Λ(读作’lambda’)是一个对角矩阵。
  • 拉格朗日乘数法:
    • 拉格朗日乘数法是一种在方程约束下寻找函数局部最大值和最小值的策略。
    • 一般形式: L ( x , λ ) = f ( x ) + λ ⋅ g ( x ) \mathcal{L}(x,\lambda)=f(x)+\lambda\cdot g(x) L(x,λ)=f(x)+λg(x) λ \lambda λ称为拉格朗日乘子。

3 详细PCA推导

需求描述

我们有 m m m个点的输入数据,表示为 x ( 1 ) , . . . , x ( m ) {x^{(1)},...,x^{(m)}} x(1),...,x(m) R n \mathbb{R}^{n} Rn的实数集中。因此,每个点 x ( i ) x^{(i)} x(i)是一个列向量,具有 n n n维特征。

需要对输入数据进行有损压缩,将这些点编码以表示它们的较低维度版本。换句话说,我们想要找到编码向量 c ( i ) ∈ R l c^{(i)}\in \mathbb{R}^{l} c(i)Rl ( l < n ) (l<n) (l<n)来表示每个输入点 x ( i ) x^{(i)} x(i)。我们的目标是找到产生输入的编码向量的编码函数 f ( x ) = c f(x)=c f(x)=c,以及相应的重构(解码)函数 x ≈ g ( f ( x ) ) x\approx g(f(x)) xg(f(x)),根据编码向量 c c c计算原始输入。

解码的 g ( f ( x ) ) g(f(x)) g(f(x))是一组新的点(变量),因此它与原始 x x x是近似的。存储 c ( i ) c^{(i)} c(i)和解码函数比存储 x ( i ) x^{(i)} x(i)更节省空间,因为 c ( i ) c^{(i)} c(i)的维度较低。

解码矩阵

我们选择使用矩阵 D D D作为解码矩阵,将编码向量 c ( i ) c^{(i)} c(i)映射回 R n \mathbb{R}^{n} Rn,因此 g ( c ) = D c g(c)=Dc g(c)=Dc,其中 D ∈ R n × l D\in \mathbb{R}^{n\times l} DRn×l。为了简化编码问题,PCA将 D D D的列约束为彼此正交。

衡量重构的表现

在继续之前,我们需要弄清楚如何生成最优的编码点 c ∗ c^{*} c,我们可以测量输入点 x x x与其重构 g ( c ∗ ) g(c^*) g(c)之间的距离,使用 L 2 L^2 L2范数(或欧几里得范数): c ∗ = arg ⁡ min ⁡ c ∣ ∣ x − g ( c ) ∣ ∣ 2 c^{*}=\arg\min_c||x-g(c)||_2 c=argminc∣∣xg(c)2。由于 L 2 L^2 L2范数是非负的,并且平方操作是单调递增的,所以我们可以转而使用平方的 L 2 L^2 L2范数:
c ∗ = arg ⁡ min ⁡ c ∣ ∣ x − g ( c ) ∣ ∣ 2 2 c^{*}={\arg\min}_c||x-g(c)||_2^2 c=argminc∣∣xg(c)22 向量的 L 2 L^2 L2范数是其分量的平方和,它等于向量与自身的点积,例如 ∣ ∣ x ∣ ∣ 2 = ∑ ∣ x i ∣ 2 = x T x ||x||_2=\sqrt{\sum|x_i|^2}=\sqrt{x^Tx} ∣∣x2=xi2 =xTx ,因此平方的 L 2 L^2 L2范数可以写成以下形式:
∣ ∣ x − g ( c ) ∣ ∣ 2 2 = ( x − g ( c ) ) T ( x − g ( c ) ) ||x-g(c)||_2^2 = (x-g(c))^T(x-g(c)) ∣∣xg(c)22=(xg(c))T(xg(c)) 由分配率:
= ( x T − g ( c ) T ) ( x − g ( c ) ) = x T x − x T g ( c ) − g ( c ) T x + g ( c ) T g ( c ) =(x^T-g(c)^T)(x-g(c))=x^Tx-x^Tg(c)-g(c)^Tx+g(c)^Tg(c) =(xTg(c)T)(xg(c))=xTxxTg(c)g(c)Tx+g(c)Tg(c) 由于 x T g ( c ) x^Tg(c) xTg(c) g ( c ) T x g(c)^Tx g(c)Tx是标量,标量等于其转置, ( g ( c ) T x ) T = x T g ( c ) (g(c)^Tx)^T=x^Tg(c) (g(c)Tx)T=xTg(c),所以:
= x T x − 2 x T g ( c ) + g ( c ) T g ( c ) =x^Tx-2x^Tg(c)+g(c)^Tg(c) =xTx2xTg(c)+g(c)Tg(c) 为了找到使上述函数最小化的 c c c,第一项可以省略,因为它不依赖于 c c c,所以:
c ∗ = arg ⁡ min ⁡ c − 2 x T g ( c ) + g ( c ) T g ( c ) c^*={\arg\min}_c-2x^Tg(c)+g(c)^Tg(c) c=argminc2xTg(c)+g(c)Tg(c) 然后用 g ( c ) g(c) g(c)的定义 D c Dc Dc进行替换:
= arg ⁡ min ⁡ c − 2 x T D c + c T D T D c ={\arg\min}_c-2x^TDc+c^TD^TDc =argminc2xTDc+cTDTDc 由于 D D D的正交性和单位范数约束:
c ∗ = arg ⁡ min ⁡ c − 2 x T D c + c T I l c c^*={\arg\min}_c-2x^TDc+c^TI_lc c=argminc2xTDc+cTIlc = arg ⁡ min ⁡ c − 2 x T D c + c T c = {\arg\min}_c-2x^TDc+c^Tc =argminc2xTDc+cTc

目标函数

现在目标函数是 − 2 x T D c + c T c -2x^TDc+c^Tc 2xTDc+cTc,我们需要找到 c ∗ c^* c来最小化目标函数。使用向量微积分,并令其导数等于0:
∇ c ( − 2 x T D c + c T c ) = 0 \nabla_c(-2x^TDc+c^Tc)=0 c(2xTDc+cTc)=0 根据向量导数规则:
− 2 D T x + 2 c = 0 ⇒ c = D T x -2D^Tx+2c=0 \Rightarrow c=D^Tx 2DTx+2c=0c=DTx

找到编码矩阵 D D D

所以编码器函数是 f ( x ) = D T x f(x)=D^Tx f(x)=DTx。因此我们可以定义 PCA 重构操作为 r ( x ) = g ( f ( x ) ) = D ( D T x ) = D D T x r(x)=g(f(x))=D(D^Tx)=DD^Tx r(x)=g(f(x))=D(DTx)=DDTx

因此编码矩阵 D D D 也被重构过程使用。我们需要找到最优的 D D D 来最小化重构误差,即输入和重构之间所有维度特征的距离。这里使用 Frobenius 范数(矩阵范数)定义目标函数:
D ∗ = arg ⁡ min ⁡ D ∑ i , j ( x j ( i ) − r ( x i ) j ) 2 , D T D = I l D^*={\arg\min}_D\sqrt{\sum_{i,j}(x_j^{(i)}-r(x^{i})_j)^2},\quad D^TD=I_l D=argminDi,j(xj(i)r(xi)j)2 ,DTD=Il 从考虑 l = 1 l=1 l=1 的情况开始(这也是第一个主成分), D D D 是一个单一向量 d d d,并使用平方 L 2 L^2 L2 范数形式:
d ∗ = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − r ( x i ) ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 d^*={\arg\min}_d{\sum_{i}||(x^{(i)}-r(x^{i}))}||_2^2, ||d||_2=1 d=argmindi∣∣(x(i)r(xi))22,∣∣d2=1 = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − d d T x ( i ) ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 = {\arg\min}_d{\sum_{i}||(x^{(i)}-dd^Tx^{(i)})||_2^2}, ||d||_2=1 =argmindi∣∣(x(i)ddTx(i))22,∣∣d2=1 d T x ( i ) d^Tx^{(i)} dTx(i) 是一个标量:
= arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − d T x ( i ) d ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 = {\arg\min}_d{\sum_{i}||(x^{(i)}-d^Tx^{(i)}d)}||_2^2, ||d||_2=1 =argmindi∣∣(x(i)dTx(i)d)22,∣∣d2=1 标量等于其自身的转置:
d ∗ = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − x ( i ) T d d ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 d^*= {\arg\min}_d{\sum_{i}||(x^{(i)}-x^{(i)T}dd)}||_2^2, ||d||_2=1 d=argmindi∣∣(x(i)x(i)Tdd)22,∣∣d2=1

使用矩阵形式表示

X ∈ R m × n X\in \mathbb{R}^{m\times n} XRm×n 表示所有描述点的向量堆叠,即 { x ( 1 ) T , x ( 2 ) T , … , x ( i ) T , … , x ( m ) T } \{x^{(1)^T}, x^{(2)^T}, \ldots, x^{(i)^T}, \ldots, x^{(m)^T}\} {x(1)T,x(2)T,,x(i)T,,x(m)T},使得 X i , : = x ( i ) T X_{i,:}=x^{(i)^T} Xi,:=x(i)T

X = [ x ( 1 ) T x ( 2 ) T … x ( m ) T ] ⇒ X d = [ x ( 1 ) T d x ( 2 ) T d … x ( m ) T d ] X = \begin{bmatrix} x^{(1)^T}\\ x^{(2)^T}\\ \ldots\\ x^{(m)^T} \end{bmatrix} \Rightarrow Xd = \begin{bmatrix} x^{(1)^T}d\\ x^{(2)^T}d\\ \ldots\\ x^{(m)^T}d \end{bmatrix} X= x(1)Tx(2)Tx(m)T Xd= x(1)Tdx(2)Tdx(m)Td ⇒ X d d T = [ x ( 1 ) T d d T x ( 2 ) T d d T … x ( m ) T d d T ] \Rightarrow Xdd^T = \begin{bmatrix} x^{(1)^T}dd^T\\ x^{(2)^T}dd^T\\ \ldots\\ x^{(m)^T}dd^T\\ \end{bmatrix} XddT= x(1)TddTx(2)TddTx(m)TddT ⇒ X − X d d T = [ x ( 1 ) T − x ( 1 ) T d d T x ( 2 ) T − x ( 2 ) T d d T … x ( m ) T − x ( m ) T d d T ] \Rightarrow X-Xdd^T = \begin{bmatrix} x^{(1)^T}-x^{(1)^T}dd^T\\ x^{(2)^T}-x^{(2)^T}dd^T\\ \ldots\\ x^{(m)^T}-x^{(m)^T}dd^T\\ \end{bmatrix} XXddT= x(1)Tx(1)TddTx(2)Tx(2)TddTx(m)Tx(m)TddT 矩阵中的一行的转置:
( x ( i ) T − x ( i ) T d d T ) T = x ( i ) − d d T x ( i ) (x^{(i)^T}-x^{(i)^T}dd^T)^T=x^{(i)}-dd^Tx^{(i)} (x(i)Tx(i)TddT)T=x(i)ddTx(i) 由于 d T x ( i ) d^Tx^{(i)} dTx(i) 是标量:
= x ( i ) − d T x ( i ) d = x ( i ) − x ( i ) T d d =x^{(i)}-d^Tx^{(i)}d=x^{(i)}-x^{(i)^T}dd =x(i)dTx(i)d=x(i)x(i)Tdd 所以我们知道 X X X 的第 i i i 行的 L 2 L^2 L2 范数与原始形式相同,因此我们可以使用矩阵重写问题,并省略求和符号:
d ∗ = arg ⁡ min ⁡ d ∣ ∣ X − X d d T ∣ ∣ F 2 , d T d = 1 d^*={\arg\min}_{d}||X-Xdd^T||_F^2, \quad d^Td=1 d=argmind∣∣XXddTF2,dTd=1 利用矩阵迹规则简化 Frobenius 范数部分如下:
arg ⁡ min ⁡ d ∣ ∣ X − X d d T ∣ ∣ F 2 {\arg\min}_{d}||X-Xdd^T||_F^2 argmind∣∣XXddTF2 = arg ⁡ min ⁡ d T r ( ( X − X d d T ) T ( X − X d d T ) ) ={\arg\min}_{d}Tr((X-Xdd^T)^T(X-Xdd^T)) =argmindTr((XXddT)T(XXddT)) = arg ⁡ min ⁡ d − T r ( X T X d d T ) − T r ( d d T X T X ) + T r ( d d T X T X d d T ) ={\arg\min}_{d}-Tr(X^TXdd^T)-Tr(dd^TX^TX)+Tr(dd^TX^TXdd^T) =argmindTr(XTXddT)Tr(ddTXTX)+Tr(ddTXTXddT) = arg ⁡ min ⁡ d − 2 T r ( X T X d d T ) + T r ( X T X d d T d d T ) ={\arg\min}_{d}-2Tr(X^TXdd^T)+Tr(X^TXdd^Tdd^T) =argmind2Tr(XTXddT)+Tr(XTXddTddT) 由于 d T d = 1 d^Td=1 dTd=1
= arg ⁡ min ⁡ d − 2 T r ( X T X d d T ) + T r ( X T X d d T ) ={\arg\min}_{d}-2Tr(X^TXdd^T)+Tr(X^TXdd^T) =argmind2Tr(XTXddT)+Tr(XTXddT) = arg ⁡ min ⁡ d − T r ( X T X d d T ) ={\arg\min}_{d}-Tr(X^TXdd^T) =argmindTr(XTXddT) = arg ⁡ max ⁡ d T r ( X T X d d T ) ={\arg\max}_{d}Tr(X^TXdd^T) =argmaxdTr(XTXddT) 由于迹是循环置换不变的,将方程重写为:
d ∗ = arg ⁡ max ⁡ d T r ( d T X T X d ) , d T d = 1 d^*={\arg\max}_{d}Tr(d^TX^TXd), \quad d^Td=1 d=argmaxdTr(dTXTXd),dTd=1 由于 d T X T X d d^TX^TXd dTXTXd 是实数,因此迹符号可以省略:
d ∗ = arg ⁡ max ⁡ d d T X T X d , d T d = 1 d^*={\arg\max}_{d}d^TX^TXd,\quad d^Td=1 d=argmaxddTXTXd,dTd=1

寻找最优的 d d d

现在的问题是找到最优的 d d d 来最大化 d T X T X d d^TX^TXd dTXTXd,并且有约束条件 d T d = 1 d^Td=1 dTd=1

使用拉格朗日乘子法来将问题描述为关于 d d d 的形式:
L ( d , λ ) = d T X T X d + λ ( d T d − 1 ) \mathcal{L}(d,\lambda)=d^TX^TXd+\lambda(d^Td-1) L(d,λ)=dTXTXd+λ(dTd1) d d d 求导数(向量导数规则):
∇ d L ( d , λ ) = 2 X T X d + 2 λ d \nabla_d\mathcal{L}(d,\lambda)=2X^TXd+2\lambda d dL(d,λ)=2XTXd+2λd 令导数等于0, d d d 将是最优的:
2 X T X d + 2 λ d = 0 2X^TXd+2\lambda d=0 2XTXd+2λd=0 X T X d = − λ d X^TXd=-\lambda d XTXd=λd X T X d = λ ′ d , ( λ ′ = − λ ) X^TXd=\lambda' d,\quad(\lambda'=-\lambda) XTXd=λd,(λ=λ) 这个方程是典型的矩阵特征值分解形式, d d d 是矩阵 X T X X^TX XTX 的特征向量, λ ′ \lambda' λ 是对应的特征值。

利用上述结果,让我们重新审视原方程:
d ∗ = arg ⁡ max ⁡ d d T X T X d , d T d = 1 d^*={\arg\max}_{d}d^TX^TXd, \quad d^Td=1 d=argmaxddTXTXd,dTd=1 = arg ⁡ max ⁡ d d T λ ′ d ={\arg\max}_{d}d^T\lambda' d =argmaxddTλd = arg ⁡ max ⁡ d λ ′ d T d ={\arg\max}_{d}\lambda'd^T d =argmaxdλdTd = arg ⁡ max ⁡ d λ ′ ={\arg\max}_{d}\lambda' =argmaxdλ 现在问题已经变的非常清楚了, X T X X^TX XTX 的最大特征值会最大化原方程的结果,因此最优的 d d d 是矩阵 X T X X^TX XTX 对应最大特征值的特征向量。

这个推导是针对 l = 1 l=1 l=1 的情况,只包含第一个主成分。当 l > 1 l>1 l>1 时, D = [ d 1 , d 2 , … ] D=[d_1, d_2, \ldots] D=[d1,d2,],第一个主成分 d 1 d_1 d1 是矩阵 X T X X^TX XTX 对应最大特征值的特征向量,第二个主成分 d 2 d_2 d2 是对应第二大特征值的特征向量,以此类推。


4 总结

我们有一个数据集,包含 m m m 个点,记为 x ( 1 ) , . . . , x ( m ) {x^{(1)},...,x^{(m)}} x(1),...,x(m)
X ∈ R m × n X\in \mathbb{R}^{m\times n} XRm×n 为将所有这些点堆叠而成的矩阵: [ x ( 1 ) T , x ( 2 ) T , … , x ( i ) T , … , x ( m ) T ] [x^{(1)^T}, x^{(2)^T}, \ldots, x^{(i)^T}, \ldots, x^{(m)^T}] [x(1)T,x(2)T,,x(i)T,,x(m)T]

主成分分析(PCA)编码函数表示为 f ( x ) = D T x f(x)=D^Tx f(x)=DTx,重构函数表示为 x ≈ g ( c ) = D c x\approx g(c)=Dc xg(c)=Dc,其中 D = [ d 1 , d 2 , … ] D=[d_1, d_2, \ldots] D=[d1,d2,] 的列是 X T X X^TX XTX 的特征向量,特征向量对应的特征值大小为降序排列。 D T x D^Tx DTx即是降维度之后的数据。


呼~
后续恢复元气后会分析一些PCA的应用案例。

在这里插入图片描述

“Remember, Red, hope is a good thing, maybe the best of things, and no good thing ever dies.
I will be hoping that this letter finds you, and finds you well.”

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

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

相关文章

【学习】软件测试人员使用Loadrunner进行性能测试的优势

在软件测试领域&#xff0c;性能测试是一项至关重要的环节&#xff0c;它关乎到软件系统的稳定性和用户体验。而在这其中&#xff0c;Loadrunner作为一款久经考验的性能测试工具&#xff0c;凭借其独特的优势&#xff0c;成为了众多企业和开发者眼中的“得力助手”。 首先&…

在 Google Cloud 上轻松部署开放大语言模型

今天&#xff0c;“在 Google Cloud 上部署”功能正式上线&#xff01; 这是 Hugging Face Hub 上的一个新功能&#xff0c;让开发者可以轻松地将数千个基础模型使用 Vertex AI 或 Google Kubernetes Engine (GKE) 部署到 Google Cloud。 Model Garden (模型库) 是 Google Clou…

C语言高质量编程之assert()和const

目录 编程中常见的错误 assert() const 编程中常见的错误 在编程中我们通常会遇到三种错误形式&#xff0c;分别是&#xff1a;编译型错误&#xff0c;链接型错误&#xff0c;运行时错误。 编译型错误&#xff1a; 在编译阶段发生的错误&#xff0c;绝大多数情况是由语法错误…

Golang | Leetcode Golang题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; func fourSum(nums []int, target int) (quadruplets [][]int) {sort.Ints(nums)n : len(nums)for i : 0; i < n-3 && nums[i]nums[i1]nums[i2]nums[i3] < target; i {if i > 0 && nums[i] nums[i-1] || nums[i]…

[GDC24]TheFInals的破坏系统

GDC24上TheFinals的开发工作室–EmbarkStudios带来; TheFinals把实时破坏在主流游戏上提升到了新的高度,可以说是新的标杆,达成了: 可以出现大规模的任意破坏破坏之后充分影响gameplay,可以把建筑任意炸毁之后,坍塌的建筑继续保留&物理正确(有正确的网络同步),可以废墟中继…

微服务之Consul 注册中心介绍以及搭建

一、微服务概述 1.1单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名思义&#xff0c;整个项目中所有功能模块都在一个工程中开发&#xff1b;项目部署时需要对所有模块一起编译、打包&#xff1b;项目的架构设计、开发模式都非常简单。 当项…

ES6: promise对象与回调地狱

ES6&#xff1a; promise对象与回调地狱 一、回调地狱二、Promise概述三、Promise的组成四、用函数封装Promise读取文件操作 一、回调地狱 在js中大量使用回调函数进行异步操作&#xff0c;而异步操作什么时候返回结果是不可控的&#xff0c;所以希望一段程序按我们制定的顺序执…

电脑无法开机?原因分析与解决方案

电脑无法开机是一种常见的问题&#xff0c;可能会给用户带来诸多困扰。无法启动可能是由于硬件故障、软件问题或者其他未知原因引起的。在本文中&#xff0c;我们将介绍三种常见的方法来解决电脑无法开机的问题&#xff0c;以帮助用户尽快恢复正常使用。 方法1&#xff1a;检查…

电影《你想活出怎样的人生》观后感

上周去看了宫崎骏电影《你想活出怎样的人生》&#xff0c;就像作为导演问观众的一个问题一样&#xff0c;宫崎骏老爷子&#xff0c;在电影中&#xff0c;给出了他的一些开放式答案。自己可是说是宫崎骏的粉丝&#xff0c;宫崎骏老爷子的大部分电影&#xff0c;自己基本都看过了…

Nevercenter CameraBag Pro--专业级摄影后期处理利器

Nevercenter CameraBag Pro是一款功能强大的照片滤镜软件&#xff0c;专为摄影爱好者和专业摄影师设计。它拥有超过200种预设滤镜和效果&#xff0c;包括黑白、复古、胶片等多种风格&#xff0c;能够轻松改变照片的外观&#xff0c;并赋予作品独特的艺术感。此外&#xff0c;Ca…

数据库(3)

目录 11.那你知道什么是覆盖索引和回表吗&#xff1f; 12.什么是MVCC&#xff1f;说说MySQL实现MVCC的原理&#xff1f; 13.MySQL的锁的类型有哪些呢&#xff1f; 14.你们数据量级多大&#xff1f;分库分表是怎么做的&#xff1f; 15.分表后非分库字段sharding_key的查询怎…

【Spring Boot】深入解密Spring Boot日志:最佳实践与策略解析

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Spring Boot】深入解密Spring Boot日志&#xff1a;最佳实践与策略解析 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 Spring Boot 日志一. 日志的概念?…

Linux 网络排查命令

端口相关服务检查 netstat -ntpl|grep [$Port]说明&#xff1a;[$Port]为相应的端口号。 0.0.0.0代表本机上可用的任意地址。比如&#xff0c;0.0.0.0:80表示本机上所有地址的80端口。 tcp 0.0.0.0:80表示在所有的可用接口上监听TCP的80端口 如果返回结果为空&#xff0c;说明…

MySQL 社区版 安装总结

很早就安装过MySQL&#xff0c;没有遇到过什么问题&#xff0c;直接next就行了&#xff0c;这次在新电脑上安装却遇到了一些问题&#xff0c;记录一下。 安装的是MySQL社区版&#xff0c;下载地址是www.mysql.com&#xff0c;进入后选择DOWNLOAD页面&#xff0c;选择MySQL Com…

minikube环境搭建

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列、spring教程等&#xff0c;大家有兴趣的可以看一看 &#x1f4d9;Jav…

贝乐虎儿歌v6.8.0解锁高级版亲子学习儿歌

软件介绍 贝乐虎儿歌免费版app&#xff0c;出自乐擎网络的创意工坊&#xff0c;专为孩子们雕琢了一系列富含创意的动画儿歌内容。这款app通过贝乐虎兄弟的可爱形象&#xff0c;让孩子们在愉快的观看中接触到各种儿歌和故事。不仅如此&#xff0c;app还巧妙地将古诗、英语等学习…

什么是享元模式,有哪些具体应用

一、定义 享元模式是一种通过尽可能多地共享数据来最小化内存使用和对象数量&#xff0c;从而提高性能的设计模式。在享元模式中&#xff0c;如果需要相同数据的多个对象&#xff0c;则共享这些对象而不是创建新的对象&#xff0c;从而提高系统的效率。 其实有很多应用场景&am…

软件设计师——软件工程基础知识

软件工程基础知识 软件过程软件过程模型软件测试方法进度管理软件复杂性度量环路复杂度耦合聚合和组合 软件过程 软件过程模型 软件测试方法 黑盒测试和白盒测试 白盒测试中&#xff0c;语句覆盖对程序执行逻辑的覆盖很低&#xff0c;因此一般认为它是很弱的逻辑覆盖。 进度管…

全新视频剪辑软件会声会影2024

会声会影 (CyberLink PowerDirector) 是一款既强大又易于使用的视频编辑软件&#xff0c;具有众多功能和工具&#xff0c;专为用户设计制作高质量的视频剪辑和制作。无论您是一个新手或是一个有经验的电影制作者&#xff0c;会声会影都适合您的需要。 生活即电影 下载地址&…

了解大语言模型的参数高效微调(Parameter-Effcient Fine-Tuning)

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 大语言模型在众多应用领域实现了突破性的进步&#xff0c;显著提升了各种任务的完成度。然而&#xff0c;其庞大的规模也带来了高昂的计算成本。这些模型往往包含数十亿甚至上千亿参数&#xff0c;需要…