【论文阅读】Deep Graph Infomax

目录

  • 0、基本信息
  • 1、研究动机
  • 2、创新点
    • 2.1、核心思想:
    • 2.2、思想推导:
  • 3、准备
    • 3.1、符号
    • 3.2、互信息
    • 3.3、JS散度
    • 3.4、Deep InfoMax方法
    • 3.5、判别器:f-GAN估计散度
  • 4、具体实现
    • 4.1、局部-全局互信息最大化
    • 4.2、理论动机
  • 5、实验设置
    • 5.1、直推式学习(Cora,Citeseer and Pubmed)
  • 6、代码实现
    • 6.1、DGI
    • 6.2、GCNLayer
    • 6.3、readout function
    • 6.4、discriminator
  • 7、参考链接

0、基本信息

  • 会议:2019-ICLR
  • 作者:Petar Veliˇckovi´,William Fedus
  • 文章链接:Deep Graph Infomax
  • 代码链接:Deep Graph Infomax

1、研究动机

(1)无监督图学习的重要性
 尽管图神经网络取得了显著的进步,但是大多数方法采用监督学习的方法,然而,在真实世界中,图的标签是较少的,这些方法很难推广到大量的无标签的图数据中。因此,对于很多重要任务而言就显得不可或缺。

(2)现有方法的缺点
 目前,主流的用于图结构数据表征学习的无监督算法,random walk-based objectives,有时简化为重构邻域信息,基本思想为训练编码器使输入图中的接近的结点在表征空间中也接近。但也存在着如下的缺点:

  • random walk-based objectives以牺牲结构信息为代价过度强调邻近信息
  • 性能很大程度上取决于超参数的选择
  • 基于图卷积编码器模型的引入,不清楚random-walk objectives是否提供了有用信号。

 基于上述的缺点与不足,本文提出了用于无监督图学习的替代目标,其基于互信息而不是随机游走。将Deep InfoMax(DIM)引入图结构数据,提出Deep Graph Infomax(DGI)模型。

在概率论和信息论中,两个随机变量的互信息(Mutual Information,简称MI)是指变量间相互依赖性的量度,度量两个事件集合之间的相关性(mutual dependence)。

2、创新点

  • 将DIM引入图领域。

2.1、核心思想:

 训练一个编码器,它的目标函数,不是最小化输入与输出的MSE,而是最大化输入与输出的互信息。

重构误差小,不能说明学习出来的特征好,好特征应该是能够提取出样本的最独特,具体的信息。那如何衡量学习出来的信息是该样本独特的呢?这里就是用“互信息”来衡量。

2.2、思想推导:

->1、首先,我们已知要用互信息来衡量学习特征的好坏,也就是说,最大化互信息是我们的目标。
->2、最大化互信息可以转化为最大化JS散度
->3、JS散度计算困难,通过“局部变分技巧”快速估算,得到JS散度的估算值,即“负采样估计”。
->4、“负采样估计”——引入一个判别网络 σ ( T ( x , z ) ) \sigma(T(x,z)) σ(T(x,z)) x x x 及其对应的 z z z 视为一个正样本对, x x x 及随机抽取的 z ^ \hat{z} z^ 则视为负样本,然后最大化似然函数,等价于最小化交叉熵,得到最终的优化目标函数。
->5、接下来,定义细节内容。。。

3、准备

3.1、符号

  • 结点特征: X = { x ⃗ 1 , x ⃗ 2 , … , x ⃗ N } \mathbf{X}=\{\vec{x}_{1},\vec{x}_{2},\ldots,\vec{x}_{N}\} X={x 1,x 2,,x N}, N N N是图中结点的个数, X ⃗ i ∈ R F \vec{X}_i\in \mathbb{R}^F X iRF表示结点i的特征。
  • 邻接矩阵(无权图): A ∈ R N × N A\in \mathbb{R}^{N \times N} ARN×N,如果结点i与结点j相连 A i j = 1 A_{ij}=1 Aij=1,否则 A i j = 0 A_{ij}=0 Aij=0
  • 编码器: E : R N × F × R N × N → R N × F ′ \mathcal{E}:\mathbb{R}^{N \times F} \times \mathbb{R}^{N \times N} \to \mathbb{R}^{N \times F'} E:RN×F×RN×NRN×F E ( X , A ) = H = { h ⃗ 1 , h ⃗ 2 , … , h ⃗ N } \mathcal{E}(X,A)=H=\{\vec{h}_{1},\vec{h}_{2},\ldots,\vec{h}_{N}\} E(X,A)=H={h 1,h 2,,h N},表示结点 i i i的高阶表征 h ⃗ i ∈ R F ′ \vec{h}_{i}\in \mathbb{R}^{F'} h iRF,称为patch representions
  • Readout Function: R : R N × F → R F \mathcal{R}:\mathbb{R}^{N \times F} \to \mathbb{R}^F R:RN×FRF s ⃗ = R ( E ( X , A ) ) \vec{s}=\mathcal{R}(\mathcal{E}(X,A)) s =R(E(X,A))为图级别的表示
  • 判别器: D : R F × R F → R \mathcal{D}:\mathbb{R}^{F} \times \mathbb{R}^F \to \mathbb{R} D:RF×RFR D ( h ⃗ i , s ⃗ ) \mathcal{D}(\vec{h}_i,\vec{s}) D(h i,s )表示分配给该patch-summary对的概率分数
  • Corruption Function : C : R N × F × R N × N → R M × F × R M × M \mathcal{C}:\mathbb{R}^{N \times F} \times \mathbb{R}^{N \times N} \to\mathbb{R}^{M \times F} \times \mathbb{R}^{M \times M} C:RN×F×RN×NRM×F×RM×M,从原始图获得一个负例样本,即 ( X ~ , A ~ ) = C ( X , A ) (\tilde{X},\tilde{A})=\mathcal{C}(X,A) (X~,A~)=C(X,A).

3.2、互信息

 互信息(Mutual Information)是度量两个事件集合之间的相关性(mutual dependence),它是信息论里一种有用的信息度量,它可以看成是一个随机变量中包含的关于另一个随机变量的信息量,或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性。互信息最常用的单位是bit。
 互信息指的是两个随机变量之间的关联程度,即给定一个随机变量后,另一个随机变量不确定性的削弱程度,因而互信息取值最小为0,意味着给定一个随机变量对确定一另一个随机变量没有关系,最大取值为随机变量的熵,意味着给定一个随机变量,能完全消除另一个随机变量的不确定性。

3.3、JS散度

JS散度度量了两个概率分布的相似度,基于KL散度(相对熵)的变体,解决了KL散度非对称的问题。一般地,JS散度是对称的,其取值是0到1之间。
 设概率空间上有两个概率分布 P P P Q Q Q M = 1 2 ( P + Q ) M=\frac{1}{2}(P+Q) M=21(P+Q) P P P Q Q Q的平均,则 P P P Q Q Q的JS散度定义为:
J S ( P ∣ ∣ Q ) = 1 2 D K L ( P ∣ ∣ M ) + 1 2 D K L ( Q ∣ ∣ M ) JS(P||Q)=\frac{1}{2}D_{KL}(P||M)+\frac{1}{2}D_{KL}(Q||M) JS(P∣∣Q)=21DKL(P∣∣M)+21DKL(Q∣∣M)
其中, D K L D_{KL} DKL表示 K L KL KL 散度,定义如下:
D K L ( P ∣ ∣ Q ) = ∑ x ∈ X P ( x ) l o g ( P ( x ) Q ( x ) ) D_{KL}(P||Q)=\sum_{x\in X}P(x)log(\frac{P(x)}{Q(x)}) DKL(P∣∣Q)=xXP(x)log(Q(x)P(x))

3.4、Deep InfoMax方法

 许多表示学习算法使用像素级的训练目标,当只有一小部分信号在语义层面上起作用时是不利的。Bengio 等研究者假设应该更直接地根据信息内容和统计或架构约束来学习表示,据此提出了 Deep InfoMax(DIM)。该方法可用于学习期望特征的表示,并且在分类任务上优于许多流行的无监督学习方法。

 互信息是概率论和信息论中重要的内容,它表示的是一个随机变量中包含另一个随机变量的信息量,可以理解成两个随机变量之间的相关程度。最大化互信息,也就是说对于每个输入样本x,编码器能够尽可能地找出专属于样本x的特征y。因此,这样一来,只通过特征y,也能很好地分辨出原始样本来(因为学习到的特征含有样本的独特信息)。

于是,最大化互信息的计算过程,有了以下的转换:

I ( X ; Y ) = ∫ Y ∫ X p ( x , y ) log ⁡ p ( x , y ) p ( x ) p ( y ) d x d y = ∫ Y ∫ X p ( y ∣ x ) p ( x ) log ⁡ p ( y ∣ x ) p ( y ) d x d y \begin{aligned} I(X ; Y) &=\int_{Y} \int_{X} p(x, y) \log \frac{p(x, y)}{p(x) p(y)} d x d y \\ &=\int_{Y} \int_{X} p(y | x) p(x) \log \frac{p(y | x)}{p(y)} d x d y \end{aligned} I(X;Y)=YXp(x,y)logp(x)p(y)p(x,y)dxdy=YXp(yx)p(x)logp(y)p(yx)dxdy

等价于
I ( X ; Y ) = K L ( p ( x , y ) ∥ p ( x ) p ( y ) ) I(X ; Y)=K L(p(x, y) \| p(x) p(y)) I(X;Y)=KL(p(x,y)p(x)p(y))

 最大化互信息,就是要拉大联合分布与边缘分布乘积的距离。
KL散度无上界,利用JS散度与KL散度之间的转换关系:

$$\begin{array}{l}

I(X ; Y) \propto J S(p(x, y), p(x) p(y))
\end{array}$$

此时就可以将最大化互信息这个问题转换成最大化JS散度

这个过程详细可以看MINE-Mutual Information Neural Estimation

Deep InfoMax是在论文Learning deep representations by mutual information estimation and maximization中提出。

3.5、判别器:f-GAN估计散度

 在机器学习中,计算两个概率分布P,Q的散度是有一定难度的,因为很多时候是无法知道两个概率分布的解析形式,或者分布只有采样出来的样本(这时就是比较两批样本之间的相似性)。

 f-GAN是通过“局部变分技巧“来进行快速地估算。
D f ( P ∥ Q ) = max ⁡ T ( E x ∼ p ( x ) [ T ( x ) ] − E x ∼ q ( x ) [ g ( T ( x ) ) ] ) \mathbb{D}_{\mathbf{f}}(\mathbf{P} \| \mathbf{Q})=\max _{\mathbf{T}}\left(\mathbb{E}_{\mathbf{x} \sim \mathbf{p}(\mathbf{x})}[\mathbf{T}(\mathbf{x})]-\mathbb{E}_{\mathbf{x} \sim \mathbf{q}(\mathbf{x})}[\mathbf{g}(\mathbf{T}(\mathbf{x}))]\right) Df(PQ)=Tmax(Exp(x)[T(x)]Exq(x)[g(T(x))])
分别从两个分布 P \mathbf{P} P Q \mathbf{Q} Q进行采样,然后计算 T ( x ) T(x) T(x) g ( T ( x ) ) g(T(x)) g(T(x))的平均值,优化 T T T,使得它们的差最大,最终的结果即为散度的估算值。T(x)可以用足够复杂的神经网络去拟合。

因此,最大化互信息的目标函数为:
J S ( p ( x , y ) , p ( x ) p ( y ) ) = max ⁡ D ( E ( x , y ) ∼ p ( x , y ) [ log ⁡ σ ( D ( x , y ) ) ] + E x ~ ∼ p ( x ) , y ~ ∼ p ( y ) [ log ⁡ ( 1 − σ ( D ( x ~ , y ~ ) ) ) ] ) \mathbf{J S}(\mathbf{p}(\mathbf{x}, \mathbf{y}), \mathbf{p}(\mathbf{x}) \mathbf{p}(\mathbf{y}))=\max _{\mathbf{D}}\left(\mathbb{E}_{(\mathbf{x}, \mathbf{y}) \sim \mathbf{p}(\mathbf{x}, \mathbf{y})}[\log \sigma(\mathbf{D}(\mathbf{x}, \mathbf{y}))]+\mathbb{E}_{\tilde{\mathbf{x}} \sim \mathbf{p}(\mathbf{x}), \tilde{y} \sim \mathbf{p}(\mathbf{y})}[\log (1-\sigma(\mathbf{D}(\tilde{\mathbf{x}}, \tilde{\mathbf{y}})))]\right) JS(p(x,y),p(x)p(y))=Dmax(E(x,y)p(x,y)[logσ(D(x,y))]+Ex~p(x),y~p(y)[log(1σ(D(x~,y~)))])

 这个公式实际上就是“负采样估计”:引入一个判别网络 σ(D(x,y)),x 及其对应的 y 视为一个正样本对,x 及随机抽取的 y 则视为负样本,然后最大化似然函数(等价于最小化交叉熵)。

4、具体实现

4.1、局部-全局互信息最大化

(1)、利用 r e a d o u t f u n c t i o n readout\;\; function readoutfunction将patch representions即 E ( X , A ) \mathcal{E}(X,A) E(X,A),转化为图的全局信息 s y m m a r y v e c t o r s ⃗ symmary \;\;vector\;\; \vec{s} symmaryvectors ,即 s ⃗ = R ( E ( X , A ) ) \vec{s}=\mathcal{R}(\mathcal{E}(X,A)) s =R(E(X,A))
(2)、采用判别器, D : R F × R F → R \mathcal{D}:\mathbb{R}^{F} \times \mathbb{R}^F \to \mathbb{R} D:RF×RFR作为最大化局部互信息的近似 D ( h ⃗ i , s ⃗ ) \mathcal{D}(\vec{h}_i,\vec{s}) D(h i,s )表示分配给该patch-summary对的概率分数,若patch在summary内,则得分越高。
(3)、负样本。在多图情形下,可以直接从训练集的另一个图中选择一个图即可;在单图情况下,构造Corruption Function : C : R N × F × R N × N → R M × F × R M × M \mathcal{C}:\mathbb{R}^{N \times F} \times \mathbb{R}^{N \times N} \to\mathbb{R}^{M \times F} \times \mathbb{R}^{M \times M} C:RN×F×RN×NRM×F×RM×M,从原始图获得一个负例样本,即 ( X ~ , A ~ ) = C ( X , A ) (\tilde{X},\tilde{A})=\mathcal{C}(X,A) (X~,A~)=C(X,A)。负样本的选择过程决定了我们要捕获特定类型的结构信息。
(4)、判别器 D \mathcal{D} D,可以通过将 s ⃗ \vec{s} s 与另一个图 ( X ~ , A ~ ) (\tilde{X},\tilde{A}) (X~,A~)中的patch representations h ~ ⃗ j \vec{\tilde{h}}_j h~ j得到;
(5)、本文使用与DIM一致的、使用噪音对比类型的目标函数,以联合分布(正样本)与边缘分布之积的标准二值交叉熵作为损失函数:
L = 1 N + M ( ∑ i = 1 N E ( X , A ) [ log ⁡ D ( h ⃗ i , s ⃗ ) ] + ∑ j = 1 M E ( X ~ , A ~ ) [ log ⁡ ( 1 − D ( h ~ ⃗ j , s ⃗ ) ) ] ) \mathcal{L}=\frac{1}{N+M}\left(\sum_{i=1}^{N}\mathbb{E}_{(\mathbf{X},\mathbf{A})}\left[\log\mathcal{D}\left(\vec{h}_i,\vec{s}\right)\right]+\sum_{j=1}^{M}\mathbb{E}_{(\tilde{\mathbf{X}},\tilde{\mathbf{A}})}\left[\log\left(1-\mathcal{D}\left(\vec{\widetilde{h}}_j,\vec{s}\right)\right)\right]\right) L=N+M1(i=1NE(X,A)[logD(h i,s )]+j=1ME(X~,A~)[log(1D(h j,s ))])

基于联合分布和边缘分布之积的JS散度,可以有效地最大化 h ⃗ i \vec{h}_i h i s ⃗ \vec{s} s 的互信息。

4.2、理论动机

(1)引理1
给定K个图,每个图的结点表示的集合为 X ( k ) X^{(k)} X(k),每个图从分布 p ( X ) p(X) p(X)中被选中的概率是均匀的,那么,联合概率与边缘概率之间的最优分类器在类平衡的条件下,错误的上限是:

E r r ∗ = 1 2 ∑ k = 1 ∣ X ∣ p ( s ⃗ k ) 2 \mathrm{Err}^* = \frac{1}{2}\sum_{k=1}^{|X|}p(\vec{s}^{k})^2 Err=21k=1Xp(s k)2
(2)推论1
假设readout函数是单射的, ∣ s ⃗ ∣ > = ∣ X ∣ |\vec{s}|>=|X| s >=X,则对于 s ⃗ ∗ \vec{s}^* s 在联合分布和边际分布之积间最优分类器分类误差下的最优summary,存在 ∣ s ⃗ ∗ ∣ = ∣ X ∣ |\vec{s}^*|=|X| s =X
(3)定理1
∣ s ⃗ ∗ ∣ = a r g m i n s ⃗ M I ( X ; s ⃗ ) |\vec{s}^*|=argmin_{\vec{s}} MI(X;\vec{s}) s =argmins MI(X;s ),MI表示互信息.

定理1表明,最小化判别器的分类误差可以最大化输入与 输出之间的互信息。

(4)定理2
假设 ∣ X i ∣ = ∣ X ∣ = ∣ s ⃗ ∣ > = ∣ h ⃗ i ∣ |X_i|=|X|=|\vec{s}|>=|\vec{h}_i| Xi=X=s >=h i,则能最小化 p ( h ⃗ ) i , s ⃗ ) p(\vec{h})_i,\vec{s}) p(h )i,s ) p ( h ⃗ i ) p ( s ⃗ ) p(\vec{h}_i)p(\vec{s}) p(h i)p(s )的分类误差可以最大化 M I ( X ( k ) , h ⃗ i ) MI(X^{(k)},\vec{h}_i) MI(X(k),h i)

4.2、DGI的整体架构

  • 通过corruption function采样一个负样本: ( X ~ , A ~ ) ∼ C ( X , A ) (\tilde{X},\tilde{A})\sim\mathcal{C}(X,A) (X~,A~)C(X,A)
  • 通过编码器获得正例样本的patch representations: H = E ( X , A ) = { h ⃗ 1 , h ⃗ 2 , … , h ⃗ N } \mathrm{H}=\mathcal{E}(\mathrm{X},\mathrm{A})=\{\vec{h}_{1},\vec{h}_{2},\ldots,\vec{h}_{N}\} H=E(X,A)={h 1,h 2,,h N}
  • 通过编码器获得负例样本的patch representations: H ~ = E ( X ~ , A ~ ) = { h ~ ⃗ 1 , h ~ ⃗ 2 , … , h ~ ⃗ N } \mathrm{\tilde{H}}=\mathcal{E}(\mathrm{\tilde{X}},\mathrm{\tilde{A}})=\{\vec{\tilde{h}}_{1},\vec{\tilde{h}}_{2},\ldots,\vec{\tilde{h}}_{N}\} H~=E(X~,A~)={h~ 1,h~ 2,,h~ N}
  • 将patch represents输入到readout function 计算图的全局信息 s ⃗ = R ( H ) \vec{s}=\mathcal{R}(\mathrm{H}) s =R(H)
  • 通过梯度下降算法最大化损失函数,更新 E , R , D \mathcal{E},\mathcal{R},\mathcal{D} E,R,D的参数

在这里插入图片描述

5、实验设置

DGI以完全无监督的方式学习patch represents,然后直接使用这些表征来训练和测试简单的线性分类器,来评估这些表征得节点级分类的效果。
这里仅仅列出直推式学习的实验设置。

5.1、直推式学习(Cora,Citeseer and Pubmed)

(1)、编码器(encoder)
由一层的图卷积网络(GCN)组成,如下形式:
E ( X , A ) = σ ( D ^ − 1 2 A ^ D ^ − 1 2 X Θ ) \mathcal{E}(X,A)=\sigma(\hat{D}^{-\frac{1}{2}}\hat{A}\hat{D}^{-\frac{1}{2}}X\Theta) E(X,A)=σ(D^21A^D^21XΘ)
A ^ = A + I N \hat{A}=A+I_N A^=A+IN是带有自环的邻接矩阵, D ^ \hat{D} D^是对应的度矩阵, σ \sigma σ是参数化的ReLU(即PReLU), Θ \Theta Θ为可学习的线性变换参数。

(2)、corruption function
在直推式学习任务中,corruption function旨在使图中不同结点的结构相似性进行正确编码,故保留原始的邻接矩阵,并对原始特征矩阵按行随机排列,即 ( X ~ , A ~ ) = ( s h u f f l e ( X ) , A ) (\tilde{X},\tilde{A})=(shuffle(X),A) (X~,A~)=(shuffle(X),A).

(3)、readout function
R ( H ) = σ ( 1 N ∑ i = 1 N h ⃗ i ) \mathcal{R}(H)=\sigma(\frac{1}{N}\sum_{i=1}^N\vec{h}_i) R(H)=σ(N1i=1Nh i)
σ \sigma σ为sigmoid函数。

(4)、discriminator function

D ( h ⃗ i , s ⃗ ) = σ ( h ⃗ i T W s ⃗ ) \mathcal{D}(\vec{h}_i,\vec{s})=\sigma(\vec{h}_i^TW\vec{s}) D(h i,s )=σ(h iTWs )
W \mathbf{W} W是一个可学习的得分矩阵, σ \sigma σ为sigmoid激活函数,用来将得分转化为 ( h ⃗ i , s ⃗ ) (\vec{h}_i,\vec{s}) (h i,s )的概率。

6、代码实现

完整代码链接
链接:https://pan.baidu.com/s/1JyWhR1LP0Sdzhpl25SSjXw
提取码:6666

6.1、DGI

import torch
import torch.nn as nn
import torch.nn.functional as F
from layers.readout import readout
from layers.GCNLayer import GCNLayer
from layers.discriminator import discriminatorclass DGI(nn.Module):def __init__(self,infeat,hidfeat,activation='prelu', ) -> None:super(DGI,self).__init__()self.gcn  = GCNLayer(infeat,hidfeat,activation)self.readout = readout()self.disc = discriminator(hidfeat)def forward(self,g,x1,x2):h1 = self.gcn(x1,g)h2 = self.gcn(x2,g)s = self.readout(h1)res = self.disc(s,h1,h2)return resdef embed(self,x,g):h = self.gcn(x,g)s = self.readout(h)return h.detach(),s.detach()

6.2、GCNLayer

import torch.nn as nn
import torch
class GCNLayer(nn.Module):def __init__(self, infeat,outfeat,activation,bias=True) -> None:super(GCNLayer,self).__init__()self.layer = nn.Linear(infeat,outfeat,bias=False)self.activation = nn.PReLU() if bias:self.bias = nn.Parameter(torch.FloatTensor(outfeat))self.bias.data.fill_(0.0)else:self.register_parameter('bias', None)for m in self.modules():self.weights_init(m)def weights_init(self, m):if isinstance(m, nn.Linear):torch.nn.init.xavier_uniform_(m.weight.data)if m.bias is not None:m.bias.data.fill_(0.0)def forward(self,x,g):out = self.layer(x)out = torch.spmm(g,out)if self.bias is not None:out = out + self.biasreturn self.activation(out)

6.3、readout function

import torch
import torch.nn as nnclass readout(nn.Module):def __init__(self, ) -> None:super(readout,self).__init__()self.act = nn.Sigmoid()def forward(self,seq):return self.act(torch.mean(seq,dim=1))

6.4、discriminator

import torch
import torch.nn as nn
class discriminator(nn.Module):def __init__(self,hidfeat) -> None:super(discriminator,self).__init__()self.bidlinear = nn.Bilinear(hidfeat,hidfeat,1)#self.act = nn.Sigmoid()for m in self.modules():self.weights_init(m)def weights_init(self, m):if isinstance(m, nn.Bilinear):torch.nn.init.xavier_uniform_(m.weight.data)if m.bias is not None:m.bias.data.fill_(0.0)def forward(self,s,h1,h2):s = torch.unsqueeze(s, 1)s = s.expand_as(h1)dis_1 = self.bidlinear(h1,s)#dis_1 = self.act(dis_1)dis_2 = self.bidlinear(h2,s)#dis_2 = self.act(dis_2)logits = torch.cat([dis_1,dis_2],dim=0)#.transpose(1,0)return logits

7、参考链接

参考链接1
参考链接2
参考链接3
参考链接4

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

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

相关文章

C# 使用Fleck创建WebSocket服务器

目录 写在前面 代码实现 服务端代码 客户端代码 调用示例 写在前面 Fleck 是 C# 实现的 WebSocket 服务器,通过 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后浏览器和服务器之间就形成了一条快速通道;两者之间…

1.5 Unity中的数据存储 PlayerPrefs

Unity中的三种数据存储:数据存储也称为数据持久化 一、PlayerPrefs PlayerPrefs是Unity引擎自身提供的一个用于本地持久化保存与读取的类,以键值对的形式将数据保存在文件中,然后程序可以根据关键字提取数值。 PlayerPrefs类支持3种数据类…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《计及储能参与的电能-调频-备用市场日前联合交易决策模型》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及到电能、调频和备用市场的联合交易决策模型,并特别考虑了储能在其中的参与。 电能市场: 这是指电能的买卖市场&…

Java使用IText生产PDF时,中文标点符号出现在行首的问题处理

Java使用IText生成PDF时,中文标点符号出现在行首的问题处理 使用itext 5进行html转成pdf时,标点符号出现在某一行的开头 但这种情况下显然不符合中文书写的规则,主要问题出在itext中的DefaultSplitCharacter类,该方法主要用来判断…

04- OpenCV:Mat对象简介和使用

目录 1、Mat对象与IplImage对象 2、Mat对象使用 3、Mat定义数组 4、相关的代码演示 1、Mat对象与IplImage对象 先看看Mat对象:图片在计算机眼里都是一个二维数组; 在OpenCV中,Mat是一个非常重要的类,用于表示图像或矩阵数据。…

⭐Unity 将电脑打开的窗口画面显示在程序中

1.效果: 下载资源包地址: Unity中获取桌面窗口 2.下载uWindowCapturev1.1.2.unitypackage 放入Unity工程 3.打开Single Window场景,将组件UwcWindowTexture的PartialWindowTitle进行修改,我以腾讯会议为例 感谢大家的观看&#xf…

CSS3实现轮播效果

在我们不使用JS的情况下&#xff0c;是否也可以实现轮播功能呢&#xff1f; 答应是可以的 上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>轮播</title><style>.boss…

激活函数整理

sigmoid函数 import torch from d2l import torch as d2l %matplotlib inline ​ xtorch.arange(-10,10,0.1,requires_gradTrue) sigmoidtorch.nn.Sigmoid() ysigmoid(x) ​ d2l.plot(x.detach(),y.detach(),x,sigmoid(x),figsize(5,2.5)) sigmoid函数连续、光滑、单调递增&am…

python爬取诗词名句网-三国演义,涉及知识点:xpath,requests,自动识别编码,range

页面源代码: <!DOCTYPE html> <html lang="zh"> <head><script src="https://img.shicimingju.com/newpage/js/all.js"></script><meta charset="UTF-8"><title>《三国演义》全集在线阅读_史书典籍_…

RV1126边缘计算AI盒子,支持4-6路1080p视频,2T 算力

1 产品概述 信迈推出基于瑞芯微Rockchip RV1126架构的AI边缘计算主板&#xff0c;RV1126芯片是四核ARM Cortex-A7,1.5GHz&#xff0c; RSIC-V 200MHz CPU &#xff0c;NPU2.0Tops。AI边缘计算主板外围接口丰富&#xff0c;拥有超强扩展性&#xff0c;可广泛应用在智慧安防、工…

docker一键安装

1.把docker_compose_install文件夹放在任意路径&#xff1b; 2.chmod -R 777 install.sh 3.执行./install.sh 兼容&#xff1a;CentOS7.6、麒麟V10服务器版、统信UOS等操作系统。 下载地址&#xff08;本人上传&#xff0c;免积分下载&#xff09;&#xff1a;https://downlo…

JS逆向之加密参数定位

文章目录 前言加密参数的处理步骤加密参数的定位方法搜索断点XHR断点DOM断点EVENT断点 hook 前言 当我们对网络请求进行抓包分析之后&#xff0c;需要用开发者工具对加密参数进行全局搜索。当搜索不到加密参数的时候&#xff0c;应该采取什么解决方法去定位。 还有一个应用场…

【动态规划】C++ 算法458:可怜的小猪

作者推荐 视频算法专题 涉及知识点 动态规划 数学 力扣458:可怜的小猪 有 buckets 桶液体&#xff0c;其中 正好有一桶 含有毒药&#xff0c;其余装的都是水。它们从外观看起来都一样。为了弄清楚哪只水桶含有毒药&#xff0c;你可以喂一些猪喝&#xff0c;通过观察猪是否…

TDengine 签约西电电力

近年来&#xff0c;随着云计算和物联网技术的迅猛发展&#xff0c;传统电力行业正朝着数字化、信息化和智能化的大趋势迈进。在传统业务基础上&#xff0c;电力行业构建了信息网络、通信网络和能源网络&#xff0c;致力于实现发电、输电、变电、配电和用电的实时智能联动。在这…

13.若依代码自动生成功能详解

文章目录 1.代码自动生成功能2.功能的使用3. 代码的导出和使用 1.代码自动生成功能 基于若依的目录结构&#xff0c;若依本身提供了代码生成功能&#xff0c;可以根据数据库表的内容&#xff0c;生成一些基本的CRUD的前后端的功能。本文将生成过程中的一些注意事项&#xff0c…

html 原生网页使用ElementPlus 日期控件el-date-picker换成中文

项目&#xff1a; 原生的html,加jQuery使用不习惯&#xff0c;新html页面导入vue3,element plus做界面&#xff0c;现在需要把日历上英文切成中文。 最终效果&#xff1a; 导入能让element plus日历变成中文脚本&#xff1a; elementplus, vue3对应的js都可以通过创建一个vu…

2023年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:数的输入和输出 输入一个整数和双精度浮点数,先将浮点数保留2位小数输出,然后输出整数。 时间限制:1000 内存限制:65536 输入 一行两个数,分别为整数N(不超过整型范围),双精度浮点数F,以一个空格分开。 输出 一行两个数,分…

首次落地零担快运!商用车自动驾驶跑出交付加速度

即将迈入2024年&#xff0c;还活着的自动驾驶玩家&#xff0c;身上有两个显著标签&#xff1a;选对了细分赛道、会玩。 10月以来&#xff0c;Cruise宣布在美国德州奥斯汀、休斯顿、亚利桑那州凤凰城和加州旧金山全面停止所有自动驾驶出租车队运营服务&#xff0c;通用汽车计划…

Spark与云存储的集成:S3、Azure Blob Storage

在现代数据处理中&#xff0c;云存储服务如Amazon S3和Azure Blob Storage已成为存储和管理数据的热门选择。与此同时&#xff0c;Apache Spark作为大数据处理框架也备受欢迎。本文将深入探讨如何在Spark中集成云存储服务&#xff0c;并演示如何与S3和Azure Blob Storage进行互…

Java 对象的内存布局

目录 一. 前言 二. Java 对象的内存布局 三. Java 对象结构 3.1. 对象头 3.1.1. Mark Word 3.1.2. 类型指针&#xff08;Class Metadata Pointer&#xff09; 3.1.3. 数组长度&#xff08;Length&#xff09; 3.2. 实例数据 3.3. 对齐填充&#xff08;Padding&#xf…