图神经网络(GNN)入门笔记(1)——图信号处理与图傅里叶变换

一、信号处理:时域与频域

时域(Time Domain)是我们生活中常见的信号表示方式,以横轴为时间,纵轴为信号该时刻的强度(幅度),就可以得到一张时域图。打个比方,通过每时每刻的震动强度可以得到音频的时域图,或者画一张每小时的车流量,或者每日的降水量的图,也是时域图。
频域(Frequency Domain)则是一种数学上描述信号的方式。在频域中,唯一存在的波形是正弦波(Sine Wave,此处指代余弦和正弦这样的简谐波总称),通过不断叠加不同周期的正弦波,我们认为我们可以拟合所有的时域信号。画成图的话,频域是横轴为频率,纵轴为幅度的一个图形。
经典的时域与频域示意图,出处见水印
那么我们为什么需要频域呢?一方面,将复杂信号拆分为不同频率的正弦波,可以更简洁地对其进行表示。另一方面,通过频率分离,我们可以做到一些滤波操作。例如,一段音频里既有男生在说话,也有女生在说话,我们想把男女生的声音分开,而女生的声音频率要比男生的高,于是就可以根据频率来划分。保留男生的低频声音的滤波叫做低通滤波,而保留女生的高频声音的滤波叫做高通滤波

二、傅里叶变换

2.1 傅里叶变换的本质

傅里叶变换的总公式如下:
F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − i ω t d t F(\omega) =\int_{-\infty}^{+\infty} f(t)e^{-i\omega t}dt F(ω)=+f(t)etdt
其中 ω \omega ω表示频率,而 t t t表示时间,这个操作就是把信号从时域转到频域上。
这个可怕的式子到底是什么意思呢?在这里非常推荐3Blue1Brown的图解。
让我们回到高中学过,或者高中的你正在学的复数概念。复数是二维的数,在横轴的实数轴上,又添加了一条纵轴的虚数轴。而单位虚数 i = − 1 i=\sqrt{-1} i=1
著名欧拉公式就是 e i x = cos ⁡ x + i sin ⁡ x e^{ix}=\cos x + i \sin x eix=cosx+isinx,这个公式有一个重要的几何意义,那就是 e i x e^{ix} eix代表着在复平面上,从(1,0)出发,沿着圆心为原点,半径为1的单位圆逆时针走 x x x个单位的圆周,所落到的点代表的复数。
由此可知:

  • h ( t ) = e i t h(t)=e^{it} h(t)=eit 代表一个每秒走1个单位的圆周的,在圆周上逆时针运动的点的轨迹函数。
  • h ( t ) = e − i t h(t)=e^{-it} h(t)=eit是顺时针运动的轨迹函数。
  • h ( t ) = e − i ω t h(t)=e^{-i\omega t} h(t)=et是每 1 ω \frac{1}{\omega} ω1秒走1单位圆周(或者说每秒走 ω \omega ω单位圆周),在圆周上逆时针运动的点的轨迹函数。
  • h ( t ) = f ( t ) e − i ω t h(t)=f(t)e^{-i\omega t} h(t)=f(t)et,则相当于我们将时域图上,横轴为时间,纵轴为幅度的 f ( t ) f(t) f(t),画到了圆上。时间从轴变成了角度,幅度从轴变成了幅长(到原点的距离)。圆上的一圈,我们能画原时域图 1 ω \frac{1}{\omega} ω1秒的内容。
    图解
    对于一个正弦波,大部分情况下只要你无限地画下去,它在圆周上都会分布得比较均匀,除了……当 1 ω \frac{1}{\omega} ω1秒恰好是原正弦波的一个周期时。此时,时域图上波峰的位置会在圆的一侧,而波谷的位置会在另一侧,就像这样:
    图解2
    那么这时,我们将这个图形上所有的点都加起来,也就是,找它们二维上的几何平均点(质心),就可以近似得到原函数在 ω \omega ω这个频率下的正弦波有多大的强度。而这种正弦波在原函数中持续时间越长(画了越多圈上图的图案),得到的 F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − i ω t d t F(\omega) =\int_{-\infty}^{+\infty} f(t)e^{-i\omega t}dt F(ω)=+f(t)etdt也会越大。由此,我们就得到了原时域信号在不同频率下的强度。
    同样,也存在频域到时域上的傅里叶逆变换:
    f ( t ) = 1 2 π ∫ − ∞ ∞ F ( ω ) e i ω t d ω f(t) = \frac{1}{2\pi} \int_{-\infty}^{\infty} F(\omega) e^{i\omega t} d\omega f(t)=2π1F(ω)etdω

2.2 从线性代数角度看离散傅里叶变换

能够被存储下来的信号,往往没有真正的连续形式,故实际中用得更多的,是离散傅里叶变换。既然离散了,我们显然也没办法把所有频率都做一遍了,此时可以近似地用 2 k π n ( k ∈ { 0 , . . . , n − 1 } \frac{2k\pi}{n}(k \in \{0,...,n-1\} n2(k{0,...,n1}这一套频率来近似地拟合,下面我们记记 W n = e 2 π n i W_n=e^{\frac{2\pi}{n}i} Wn=en2πi
假设我们在时域上有一组采样点 f ( t 0 ) , . . . , f ( t n − 1 ) f(t_0),...,f(t_{n-1}) f(t0),...,f(tn1),离散傅里叶变换的公式为:
F ( W n k ) = ∑ j = 0 n − 1 f ( t j ) W n − k j F(W_n^k)=\sum_{j=0}^{n-1} f(t_j) W_n^{-kj} F(Wnk)=j=0n1f(tj)Wnkj
相应地,逆傅里叶变换的公式为:
f ( t j ) = 1 n ∑ k = 0 n − 1 F ( W n k ) W n k j f(t_j) = \frac{1}{n}\sum_{k=0}^{n-1} F(W_n^k)W_n^{kj} f(tj)=n1k=0n1F(Wnk)Wnkj
如果把傅里叶变换写成矩阵形式,就是这样:
( F ( 0 ) ⋮ F ( n − 1 ) ) = ( W n − 0 ⋯ W n − ( n − 1 ) ⋮ ⋱ ⋮ W n − ( n − 1 ) ⋯ W n − ( n − 1 ) 2 ) ( f ( t 0 ) ⋮ f ( t n − 1 ) ) \begin{pmatrix} F(0) \\ \vdots \\ F(n-1) \end{pmatrix}= \begin{pmatrix} W_n^{-0} & \cdots & W_n^{-(n-1)} \\ \vdots & \ddots & \vdots \\ W_n^{-(n-1)} & \cdots & W_n^{-(n-1)^2} \end{pmatrix} \begin{pmatrix} f(t_0) \\ \vdots \\ f(t_{n-1}) \end{pmatrix} F(0)F(n1) = Wn0Wn(n1)Wn(n1)Wn(n1)2 f(t0)f(tn1)

中间那个巨大的矩阵,我们记作 U U U,于是上式可以简写为 F = U f F=Uf F=Uf
同样,我们可以把逆傅里叶变换写成 f = 1 n V F f=\frac{1}{n}VF f=n1VF,其中 V i j = W n i j V_{ij}=W_n^{ij} Vij=Wnij
考虑 ( V U ) i j = ∑ k = 0 n − 1 W n i k W n − k j = ∑ k = 0 n − 1 W n k ( i − j ) (VU)_{ij}=\sum_{k=0}^{n-1} W_n^{ik}W_n^{-kj}=\sum_{k=0}^{n-1}W_n^{k(i-j)} (VU)ij=k=0n1WnikWnkj=k=0n1Wnk(ij)
i = j i=j i=j时,显然和为 ( V U ) i i = n (VU)_{ii}=n (VU)ii=n。而 i ≠ j i \not= j i=j时,根据等比数列求和可得 ( V U ) i j = W n n ( i − j ) − 1 W n ( i − j ) − 1 (VU)_{ij}=\frac{W^{n(i-j)}_n-1}{W^{(i-j)}_n-1} (VU)ij=Wn(ij)1Wnn(ij)1,由 W n n = 1 W^n_n=1 Wnn=1可知此时 ( V U ) i j = 0 (VU)_{ij}=0 (VU)ij=0

三、拉普拉斯算子

拉普拉斯算子(Laplace Operator)写作一个正着的三角,表示梯度的散度,简单来说,对于 n n n维函数(注意这里是 n n n维而不是 n n n个采样点) f ( x 1 , . . . , x n ) f(x_1,...,x_n) f(x1,...,xn)有:
Δ f = ∇ ⋅ ∇ f = ( ∂ ∂ x 1 … ∂ ∂ x n ) ( ∂ ∂ x 1 ⋮ ∂ ∂ x n ) f = ∑ i = 1 n ∂ 2 f ∂ x i 2 \Delta f = \nabla \cdot \nabla f = \begin{pmatrix} \frac{\partial}{\partial x_1} & \dots & \frac{\partial}{\partial x_n}\end{pmatrix}\begin{pmatrix} \frac{\partial}{\partial x_1} \\ \vdots \\ \frac{\partial}{\partial x_n}\end{pmatrix}f=\sum_{i=1}^n \frac{\partial^2 f}{\partial x_i^2} Δf=f=(x1xn) x1xn f=i=1nxi22f
那么拉普拉斯算子和频率有什么关系呢?写成连续形式或许不够直观,我们可以考虑一个二维离散的场景,即,对一张灰度图使用拉普拉斯算子。函数 f ( x , y ) f(x,y) f(x,y)表示的是灰度图上 ( x , y ) (x,y) (x,y)点的灰度。在此情景下,我们近似地将导数 ∂ f ∂ x = lim ⁡ h → 0 ( f ( x + h ) − f ( x ) ) \frac{\partial f}{\partial x}=\lim_{h \to 0} (f(x+h)-f(x)) xf=limh0(f(x+h)f(x))写作 f ( x + 1 ) − f ( x ) f(x+1)-f(x) f(x+1)f(x) f ( x ) − f ( x − 1 ) f(x)-f(x-1) f(x)f(x1),则:
∂ 2 f ( x 0 , y 0 ) ∂ x 0 2 + ∂ 2 f ( x 0 , y 0 ) ∂ y 0 2 \frac{\partial^2 f(x_0,y_0)}{\partial x_0^2}+\frac{\partial^2 f(x_0,y_0)}{\partial y_0^2} x022f(x0,y0)+y022f(x0,y0)
= ∂ f ( x 0 + 1 , y 0 ) ∂ x 0 − ∂ f ( x 0 , y 0 ) ∂ x 0 + ∂ f ( x 0 , y 0 + 1 ) ∂ y 0 − ∂ f ( x 0 , y 0 ) ∂ y 0 =\frac{\partial f(x_0+1,y_0)}{\partial x_0} - \frac{\partial f(x_0,y_0)}{\partial x_0} + \frac{\partial f(x_0,y_0+1)}{\partial y_0} - \frac{\partial f(x_0,y_0)}{\partial y_0} =x0f(x0+1,y0)x0f(x0,y0)+y0f(x0,y0+1)y0f(x0,y0)
= f ( x 0 + 1 , y 0 ) + f ( x 0 , y 0 + 1 ) + f ( x 0 − 1 , y 0 ) + f ( x 0 , y 0 − 1 ) − 4 f ( x 0 , y 0 ) =f(x_0+1,y_0)+f(x_0,y_0+1)+f(x_0-1,y_0)+f(x_0,y_0-1)-4f(x_0,y_0) =f(x0+1,y0)+f(x0,y0+1)+f(x01,y0)+f(x0,y01)4f(x0,y0)
而这反映了这个像素点处灰度值的变化大小,某种意义上相当于此处的频率。这也是CV中的拉普拉斯卷积核的来历:
( 0 1 0 1 − 4 1 0 1 0 ) \begin{pmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{pmatrix} 010141010
既然拉普拉斯算子是干这个用的,可以想见它和傅里叶变换会有些关系。为了寻求这个关系,我们可以回顾一下线性代数中特征值和特征向量的概念:

特征值和特征向量
概念:对于一个矩阵 A A A,若存在向量 u i u_i ui和常数值 λ i \lambda_i λi,使得 A u i = λ i u i Au_i=\lambda_i u_i Aui=λiui,则称 λ i \lambda_i λi A A A的特征值, u i u_i ui A A A的特征向量。
求法:则 ( A − λ i I ) u i = 0 (A-\lambda_i I)u_i=0 (AλiI)ui=0,通过解 ∣ A − λ I ∣ = 0 |A-\lambda I|=0 AλI=0可以得到 n n n组解,再相应带入回原式可以得到相应的 λ i \lambda_i λi。矩阵的特征值集合是唯一的,而每个特征值对应的特征向量构成一个特征子空间。
矩阵的对角化:若 A A A n n n个线性无关的特征向量 U = ( u 1 , . . . , u n ) U=(u_1,...,u_n) U=(u1,...,un),则 A = U d i a g ( λ 1 , . . . , λ n ) U − 1 A=Udiag(\lambda_1,...,\lambda_n) U^{-1} A=Udiag(λ1,...,λn)U1
利用对角化计算矩阵向量乘:将向量 x x x映射到空间 U U U中,得到 x = x 1 u 1 + . . . + x n u n x=x_1u_1+...+x_nu_n x=x1u1+...+xnun,则 A x = x 1 λ 1 u 1 + . . . + x n λ n u n Ax=x_1\lambda_1u_1+...+x_n \lambda_n u_n Ax=x1λ1u1+...+xnλnun

那么,假如有这样一个函数 f f f和常数值 λ \lambda λ,使得 Δ f = λ f \Delta f = \lambda f Δf=λf,岂不是这就是 Δ \Delta Δ的特征值和特征函数了吗?那么再想想,什么样的函数,经过两次求导,还能等于一个常数乘以它本身呢?答案是…… sin ⁡ x \sin x sinx cos ⁡ x \cos x cosx e x e^x ex,对吧?事实上, d 2 e i x d x 2 e i a x = − a 2 e i a x \frac{d^2 e^{ix}}{dx^2} e^{iax}=-a^2e^{iax} dx2d2eixeiax=a2eiax,也即 e i a x e^{iax} eiax系列函数是拉普拉斯算子的特征函数。
我们可不可以像利用特征向量计算矩阵向量乘一样,利用这特征函数来计算拉普拉斯算子呢?那么第一步,我们就需要把一个任意函数 f ( x ) f(x) f(x),映射到 e i a x e^{iax} eiax的函数族空间中。实际上,套一下傅里叶函数的公式可知:
f ( x ) = 1 2 π ∫ − ∞ + ∞ ( ∫ − ∞ + ∞ f ( t ) e − i ω t d t ) e i ω x d ω f(x)=\frac{1}{2\pi}\int_{-\infty}^{+\infty} (\int_{-\infty}^{+\infty} f(t)e^{-i\omega t} dt) e^{i\omega x} d \omega f(x)=2π1+(+f(t)etdt)exdω
c ( ω ) = 1 2 π ∫ − ∞ + ∞ f ( t ) e − i ω t d t c(\omega)=\frac{1}{2\pi}\int_{-\infty}^{+\infty} f(t)e^{-i\omega t} dt c(ω)=2π1+f(t)etdt,如果它收敛到一个常数值,则这个常数值是和 f f f整体有关,而和自变量 x x x的具体取值无关的。 f ( x ) f(x) f(x)也就就此被映射到了特征函数族中。这时候,想做拉普拉斯算子,就是:

Δ f ( x ) = ∫ − ∞ + ∞ ω 2 c ( ω ) e i ω x d ω \Delta f(x)=\int_{-\infty}^{+\infty} \omega^2c(\omega)e^{i\omega x} d\omega Δf(x)=+ω2c(ω)exdω

四、图的拉普拉斯矩阵

A A A为图的邻接矩阵(即当i和j存在边时 A i j = 1 A_{ij}=1 Aij=1,否则 A i j = 0 A_{ij}=0 Aij=0,在此我们只考虑无向图,即 A A A为对称矩阵),而 D D D为图的度数矩阵(对角阵, D i i D_{ii} Dii表示点 i i i有多少条邻边),定义图拉普拉斯矩阵为:
L = D − A L=D-A L=DA
形象化地理解,我们考虑这样一个实际问题。有一个公园建在山上,公园内有 n n n个景点,一些景点之间有路相连。我们想要分析这个公园某个景点有多陡峭。应用拉普拉斯矩阵的话,是这样的:
Δ h ( u ) = ∑ v ∈ N e i g h b o r ( u ) ( h ( u ) − h ( v ) ) \Delta h(u) = \sum_{v \in Neighbor(u)} (h(u)-h(v)) Δh(u)=vNeighbor(u)(h(u)h(v))
Δ h = ( Δ h ( 1 ) ⋮ Δ h ( n ) ) = ( D − A ) h = L A \Delta h= \begin{pmatrix} \Delta h(1) \\ \vdots \\ \Delta h(n)\end{pmatrix}=(D-A)h=LA Δh= Δh(1)Δh(n) =(DA)h=LA
当然,就这么直接用似乎还有些问题,直接用上面这个 L L L的话,似乎一个节点邻居越多,最后得到的变化值就越大,因此实际中我们一般会对其进行归一化,比如这样:
L ^ = D − 1 L = I − D − 1 A \hat L =D^{-1}L=I-D^{-1}A L^=D1L=ID1A
不过这种非对称归一化会有点小问题,我们假设点1有很多邻居,而点2只有点1一个邻居。在归一化时, Δ h ( 1 ) \Delta h(1) Δh(1)只除了点1的度数,而 Δ h ( 2 ) \Delta h(2) Δh(2)只除了点2的度数。在一些问题(例如图上标签预测问题)中,我们认为此时2受到1的影响过高了。解决方案则是,在归一化过程中,点2受到点1的影响,不仅要除以和点2度数相关的量,也要除以和点1度数相关的量。具体来说,就是这样做对称归一化
L ^ = D − 1 2 L D − 1 2 = I − D − 1 2 A D − 1 2 \hat L = D^{-\frac{1}{2}} L D^{-\frac{1}{2}} = I-D^{-\frac{1}{2}} A D^{-\frac{1}{2}} L^=D21LD21=ID21AD21

五、图傅里叶变换

一维信号的傅里叶变换,本质是用不同频率的正弦波来拟合原信号。那我们应该如何构造一组图上的基本信号,来拟合原图的函数呢。
考虑把信号记为 f = ( f ( 1 ) , . . . , f ( n ) ) T f=(f(1),...,f(n))^T f=(f(1),...,f(n))T,然后考虑用下式,通过引入平方消除正负性的影响,来反映整张图的波动性(variation):
f t L f = ∑ i , j , i < j A i j ( f ( i ) − f ( j ) ) 2 f^tLf = \sum_{i,j,i<j}A_{ij}(f(i)-f(j))^2 ftLf=i,j,i<jAij(f(i)f(j))2
首先我们可以发现,对于 u 1 = ( 1 n , . . . , 1 n ) T u_1=(\frac{1}{\sqrt{n}},...,\frac{1}{\sqrt{n}})^T u1=(n 1,...,n 1)T(这里对向量的模做了归一化), L u 1 = 0 Lu_1=0 Lu1=0,即 u 1 u_1 u1 L L L的一个特征向量, 0 0 0为其特征值,而且它能够使得原图的波动最小。接下来,我们不断重复以下过程:
u k = min ⁡ ∣ ∣ f ∣ ∣ = 1 , f ∣ u 1 , . . u k − 1 f t L f u_k = \min_{||f||=1, f \vert u_1,..u_{k-1}}f^t L f uk=∣∣f∣∣=1,fu1,..uk1minftLf
我们就会得到一组 L L L的特征向量正交基,它们也是一组使得原图波动最小的基本图信号,而且对应特征值 λ k = u k t L u k \lambda_k=u_k^tLu_k λk=uktLuk
x ~ \widetilde x x 为图信号 x x x在频域下的表示,则 x = u 1 x ~ 1 + . . . + u n x ~ n = U x ~ x=u_1\widetilde x_1 +...+u_n \widetilde x_n =U \widetilde x x=u1x 1+...+unx n=Ux 。相应的,我们可以定义将 x x x表示在频域上的图傅里叶变换为 x ~ = U T x \widetilde x = U^T x x =UTx,而特征值 ( λ 1 , . . . λ n ) (\lambda_1,...\lambda_n) (λ1,...λn),就是 n n n组频率。
下图就是一个不同频率上拉普拉斯特征向量的可视化表现:
拉普拉斯矩阵特征向量的可视化

六、图滤波与图卷积

我们之前提过,在声音信号中,通过改变原信号不同频率的强弱,可以做到诸如分离男女声音之类的功能,这个过程就叫滤波。此外还有一个经常提到的概念叫卷积,假设 f f f为原函数, g g g为卷积核, f f f g g g之间做卷积写成公式是这样的:
( f ∗ g ) ( t ) = ∫ − ∞ ∞ f ( t ′ ) g ( t − t ′ ) d t ′ (f * g)(t)=\int_{-\infty}^{\infty} f(t')g(t-t') dt' (fg)(t)=f(t)g(tt)dt
而我们有:

卷积定理:若 f ^ \hat f f^ f f f在频域上的表示,则 ( g ∗ g f ) ^ ( t ) = ( f ^ ⋅ g ^ ) ( ω ) = ∫ − ∞ + ∞ f ^ ( ω ) g ^ ( ω ) d ω \hat{(g *_g f)}(t)=(\hat f \cdot \hat g) (\omega)=\int_{-\infty}^{+\infty} \hat f(\omega)\hat g(\omega) d\omega (ggf)^(t)=(f^g^)(ω)=+f^(ω)g^(ω)dω

虽然在这里我不打算展开证明,但可以简单介绍一下,利用这个定理,我们可以通过(1)将 f f f g g g O ( n log ⁡ n ) O(n \log n) O(nlogn)从时域转化为频域 (2)对二者在频域进行 O ( n ) O(n) O(n)点积 (3)频域 O ( n log ⁡ n ) O(n \log n) O(nlogn)转化回时域 的三个步骤,将本来需要 O ( n 2 ) O(n^2) O(n2)计算的卷积在 O ( n log ⁡ n ) O(n \log n) O(nlogn)中快速完成。
让我们放眼第二步,你发现了什么?——没错,在频域上进行点积,不就是对 f f f在不同频率的强度进行调整吗?所以卷积和滤波本质上是相同的操作。
好,因为我们已经定义过图傅里叶变换了,所以可以以同样流程考虑图的情况,设 f f f为图结点的特征组成的向量, g g g是卷积核,则:
( g ∗ g f ) = U ( U T g ⋅ U T f ) (g *_g f)=U(U^T g \cdot U^T f) (ggf)=U(UTgUTf)
W = d i a g ( U T g ) W=diag(U^Tg) W=diag(UTg),则 ( g ∗ g f ) = U W U T f (g *_g f)=UWU^T f (ggf)=UWUTf
也即,如果我们希望对图信号进行处理,只需要找到(使用各种学习方法)合适的一组 W W W n n n个参数即可。这就是谱域(Spectral Domain)上的图卷积的基本思想。
当然,到目前为止,我们得到的这个信号处理方式想要实际应用还存在一些问题:

  1. W W W是和图形状强相关的,参数量和图的点数也有关,难以适用于不同的图。
  2. 需要计算图傅里叶算子(拉普拉斯矩阵的特征向量),这个过程是 O ( n 3 ) O(n^3) O(n3)的, n n n为图的点数,复杂度较高且和图规模相关。
  3. 只能用于无向图(需要拉普拉斯矩阵对称以保证可以找到正交基特征向量)。
  4. 难以对局部空间信息进行处理(毕竟所有频率都是全局的)。
    我们将在下一节继续讨论这些问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【八百客CRM-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【AIGC】如何在ChatGPT中制作个性化GPTs应用详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;前言&#x1f4af;什么是GPTsGPTs的工作原理GPTs的优势GPTs的应用前景总结 &#x1f4af;创建GPTS应用的基本流程进入GPTs创建界面方式一&#xff1a;按照引导完成生成创建GPTs方式二…

读书笔记--Java与线程

并发不一定要依赖多线程&#xff08;如PHP中很常见的多线程并发&#xff09;&#xff0c;但是Java里面谈论并发&#xff0c;大多数都与线程脱不了关系。 线程的实现 我们都知道&#xff0c;线程是比进程更轻量级的调度执行单位&#xff0c;线程的引入&#xff0c;可以把一个进程…

PICO+Unity 用手柄点击UI界面

如果UI要跟随头显&#xff0c;可将Canvas放置到XR Origin->Camera Offset->Main Camera下 1.Canvas添加TrackedDeviceGraphicRaycaster组件 2.EventSystem移动默认的Standard Input Module&#xff0c;添加XRUIInputModule组件 3.&#xff08;可选&#xff09;设置射线可…

三十六、Python基础语法(JSON操作)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种基于文本&#xff0c;轻量级的数据交换格式。它易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;在自动化测试中经常用来存放测试数据。 JSON的特点&#xff1a; 基于文本&#xff0c;不包含图…

产品设计理念:10个案例分享

在互联网时代&#xff0c;企业通过在线产品为用户提供服务。要在众多竞争产品中脱颖而出并吸引更多用户&#xff0c;企业不仅要提供优质的服务&#xff0c;还要在产品设计上给用户带来卓越的体验。互联网产品设计包括页面布局、服务内容、流程逻辑、色彩搭配、图标、按钮等多个…

智能社区服务小程序+ssm

智能社区服务小程序 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了智能社区服务小程序的开发全过程。通过分析智能社区服务小程序管理的不足&#xff0c;创建了一个计算机管理智能社区服务小程序的方案。文…

Flutter3.22.2中SliverAppBar设置背景色滑动显示颜色错误

在使用Flutter项目开发中&#xff0c;可能会有页面需要滑动收起标题栏的效果&#xff0c;一般都会使用SliverAppBar来实现&#xff0c;当项目的Flutter的SDK版本升级到3.4后&#xff0c;发现使用了SliverAppBar的页面&#xff0c;在滑动过程中&#xff0c;标题栏和状态栏的颜色…

Odoo | 免费开源ERP:汽车及零配件行业信息化解决方案

文 / 开源智造 Odoo亚太金牌服务 概述 围绕汽车行业产业链上下游企业的整体业务主线&#xff0c;提供面向汽车主机厂整车个性化制造解决方案&#xff0c;产业链上下游一体化协同解决方案&#xff0c;数字化精益制造解决方案、全价值链质量管理解决方案&#xff0c;数字化运营解…

目前对于后期的打算

在完成了 Python 基本语法的学习后&#xff0c;我犹如推开了编程世界的一扇大门&#xff0c;初窥门径却也深知前方还有广袤无垠的知识天地等待我去探索。Python 作为一门广泛应用于软件开发、数据分析和人工智能等领域的高级编程语言&#xff0c;在当今数字化时代具有举足轻重的…

React中右击出现自定弹窗

前言 在react中点击右键,完成阻止浏览器的默认行为,完成自定义的悬浮框(Menu菜单). 版本 "react": "^18.2.0", "umijs/route-utils": "^4.0.1", "antd": "^5.18.1", "ant-design/pro-components": &q…

Elasticsearch如果集群出现节点故障,我应该如何快速定位问题?

当 Elasticsearch (ES) 集群发生故障时&#xff0c;快速定位问题源头非常重要。Elasticsearch 是一个分布式系统&#xff0c;故障可能由多种原因引起&#xff0c;涉及到硬件、配置、网络、集群本身的健康状况等多个层面。以下是一些定位问题的步骤和工具&#xff1a; 检查集群…

【Docker】Docker基础及docker-compose

一、Docker下载 更新yum包 yum update 安装需要的软件包&#xff08; yum-util 提供yum-config-manager功能&#xff0c;后两个是devicemapper驱动依赖&#xff09; yum install -y yum-utils device-mapper-persistent-data lvm2 设置stable镜像仓库&#xff08;使用阿里…

Linux:理解动静态库

一、前言 如果我们写了一些方法想给别人用&#xff1f;&#xff1f;有什么办法呢&#xff1f;&#xff1f; ——>(1)我直接把头文件和源文件给他&#xff08;.c.h&#xff09; ——>这样会让别人轻易看到你的实现 &#xff08;2&#xff09;把源文件打包成库&#xff…

快速了解SpringBoot 统一功能处理

拦截器 什么是拦截器&#xff1a; 拦截器是Spring框架提供的重要功能之一&#xff0c;主要进行拦截用户请求&#xff0c;在指定方法前后&#xff0c;根据业务需求&#xff0c;执行预先设定的代码。 也就是说,允许开发⼈员提前预定义⼀些逻辑,在⽤⼾的请求响应前后执⾏.也可以…

随着最新的补丁更新,Windows 再次变得容易受到攻击

SafeBreach专家Alon Leviev发布了一款名为 Windows Downdate的工具&#xff0c;可用于对Windows 10、Windows 11 和 Windows Server 版本进行降级攻击。 这种攻击允许利用已经修补的漏洞&#xff0c;因为操作系统再次容易受到旧错误的影响。 Windows Downdate 是一个开源Pyth…

Linux笔记-对Linux环境变量的进一步认识(2024-08-09)

此篇公开到互联网上的时间是&#xff1a;2024-11-11 主要是PATH和LD_LIBRARY_PATH。 基本概念 在 Linux 中&#xff0c;PATH 和 LD_LIBRARY_PATH 是两个不同的环境变量&#xff0c;它们的作用和使用场景有所不同。 PATH 作用&#xff1a;用来指定可执行文件的搜索路径。当你…

Linux操作系统之DHCP服务部署与配置

一、实验目的 1、理解DHCP的定义和工作原理&#xff1b; 2、掌握DHCP服务器的配置方法。 二、实验环境 1台PC、VMware虚拟机、3个CentOS7操作系统 三、实验步骤及内容 1、使用yum安装dhcp&#xff1b; 图1 安装DHCP服务 图2 查看DHCP是否安装 2、修改VM中虚拟网络编辑器…

优化时钟网络之时钟抖动

Note&#xff1a;文章内容以Xilinx 7系列FPGA进行讲解 1、什么是时钟抖动 时钟抖动就是时钟周期之间出现的偏差。比如一个时钟周期为10ns的时钟&#xff0c;理想情况下&#xff0c;其上升沿会出现在0ns&#xff0c;10ns&#xff0c;20ns时刻&#xff0c;假设某个上升沿出现的时…

第三十六章 Vue之路由重定向/404页面设置/路径模式设置

目录 一、路由重定向 1.1. 使用方式 1.2. 完整代码 1.2.1. main.js 1.2.2. App.vue 1.2.3. index.js 1.2.4. Search.vue 1.2.5. Home.vue 1.3. 运行效果 二、设定404错误页面 2.1. 使用方式 2.2. 完整代码 2.2.1. index.js 2.2.2. NotFound.vue 2.2.3. 运行效…