graph相关论文阅读笔记

一些graph相关常见的符号说明

符号shape说明
AN x N邻接矩阵,当点i与点j之间有边时, A i , j = 1 A_{i,j} = 1 Ai,j=1
DN x N点的度阵,对角阵, D i i D_{ii} Dii表示点i的度
LN x N拉普拉斯阵, L = D − A L = D - A L=DA,可能有多种定义
PN x N转移概率矩阵, P = D − 1 A P = D^{-1}A P=D1A P i , j P_{i,j} Pi,j表示从点i转移到点j的概率

GNN survey2018: Deep Learning on Graphs: A Survey

gnn的survey,把模型分为下面5类:
在这里插入图片描述

graph RNN

这一类的模型比较少,比较有名的有:gnn, gated-gnn,

graph CNN

是gnn里面最火的一种,大概可以分成2种解决思路:

  1. spatial/vertex domain,空间域,考虑节点的邻居进行卷积,很像传统的卷积
  2. spectral domain,频谱域,先用Fourier变换把图转化到频域上,再对频域上的结果做卷积,本质上是借助图的拉普拉斯矩阵的特征值和特征向量来研究图

spectral domain的模型
频谱域的解决思路,由于需要计算拉普拉斯矩阵,所以需要遍历图的所有点,因此计算复杂度比较高。比较著名的文章有下面这几篇:
Spectral networks and locally connected networks on graphs
Deep convolutional networks on graph-structured data
Convolutional neural networks on graphs with fast localized spectral filtering
Semi-supervised classification with graph convolutional networks
Cayleynets: Graph convolutional neural networks with complex rational spectral filters

spatial domain的模型
MPNN:提出一个框架,可以把spectral domain的模型学习过程也概括进来
GAT,graphSAGE,gn框架

一些常见的花活也可以加进来,比如attention机制,residual connections等

graph autoencoders/GAE

SDNE

graph reinforcement learning

graph adversarial methods

Graph embedding survey2017: A Comprehensive Survey of Graph Embedding: Problems, Techniques and Applications

这是一篇KDD17年的论文,感觉是当前比较好的一篇,可惜年代也比较久了,比较靠近21年的survey还没有找到。

graph embedding的分类
在这里插入图片描述
专注上图中右边这一块

Matrix Factorization
这块相关的方法都属于比较老的

Deep Learning
使用random walk这里,包含:DeepWalk, node2vec, EGES
不使用random walk这里,包含:SDNE, GCN, GNN

Edge Reconstruction
核心思想:embedding后的line关系应该和embedding之前的相似
包含:LINE


DeepWalk: Online Learning of Social Representations

baseline一般的存在,把word2vec的思想迁移到网络结构的数据中(不了解word2vec看这里的word2vec部分)

DeepWalk采用了skip-gram架构,context word对应图中的”邻居节点“。在选择邻居节点时,DeepWalk采用的随机游走策略,也即从当前节点开始,随机选择当前节点的邻居节点,邻居节点的个数是一个可调节的超参数。因为邻居节点是随机选出来的,所以context word既有可能是该节点的邻居节点(BFS),也有可能从某个邻居节点开始就一直深入(DFS)

LINE: Large-scale Information Network Embedding

改进自deepwalk,区别在于:

  1. context word/邻居节点选取:只考虑直接相连的邻居(一次BFS)(二阶相似度)
  2. 目标函数:增加了一个目标项,考虑当前节点的权重在整个网络中的权重(一阶相似度)
  3. 训练加速edge sampling:类似negative sampling

适用范围:大量节点、有向边/无向边均可、有权重边/无权重边均可

具体来说,LINE生成embedding的方法是,利用一阶相似度和二阶相似度分别训练模型,得到基于一阶相似度的embedding和基于二阶相似度的embedding,然后再把2个embedding拼接起来作为节点的embedding

不管是基于哪种相似度,都是以分布的距离作为优化函数,分布的距离即原空间中的经验分布和embedding空间中的softmax分布的距离。

基于一阶相似度生成的embedding

原空间的经验分布
定义原先维度的空间中 v i , v j v_i, v_j vi,vj之间的相似度为:
p ^ 1 ( v i , v j ) = w i , j W W = ∑ i , j w i , j \hat {p}_1(v_i, v_j) = \frac{w_{i,j}}{W} \\ W = \sum_{i,j} w_{i,j} p^1(vi,vj)=Wwi,jW=i,jwi,j
其中:

  • w i , j w_{i, j} wi,j是节点 v i v_i vi v j v_j vj之间相连的边的权重
  • W是图中所有边的权重之和

embedding空间的分布
定义节点 v i , v j v_i, v_j vi,vj的embedding分别为 u ⃗ i , u ⃗ j \vec{u}_i, \vec{u}_j u i,u j,则 v i , v j v_i, v_j vi,vj的相似度是:
p 1 ( v i , v j ) = s i g m o i d ( u ⃗ i u ⃗ j ) = 1 1 + e x p ( − u i ⃗ ∗ u j ⃗ ) = σ ( u ⃗ i u ⃗ j ) p_1(v_i, v_j) = sigmoid(\vec{u}_i\vec{u}_j) = \frac{1}{1 + exp ( - \vec{u_i} * \vec{u_j})} = \sigma(\vec{u}_i\vec{u}_j) p1(vi,vj)=sigmoid(u iu j)=1+exp(ui uj )1=σ(u iu j)

优化目标/分布相似度
O 1 O_1 O1为两个分布之间的距离,用KL散度来衡量(KL散度具体可见这里),所以有:
O 1 ( p ^ 1 , p 1 ) = d i s t a n c e ( p ^ 1 ( v i , u i ) , p 1 ( v i , u i ) ) = ∑ p ^ 1 l o g p ^ 1 p 1 = ∑ p ^ 1 l o g    p ^ 1 − ∑ p ^ 1 l o g    p 1 = − H ( p ^ 1 ) + H ( p ^ 1 , p 1 ) \begin{aligned} O_1(\hat{p}_1, p_1) &= distance(\hat{p}_1(v_i, u_i), p_1(v_i, u_i)) \\ &= \sum \hat{p}_1 log\frac{\hat{p}_1}{p_1} \\ &= \sum \hat{p}_1 log\; \hat{p}_1 - \sum \hat{p}_1 log \; p_1 \\ &= -H(\hat{p}_1) + H(\hat{p}_1, p_1) \\ \end{aligned} O1(p^1,p1)=distance(p^1(vi,ui),p1(vi,ui))=p^1logp1p^1=p^1logp^1p^1logp1=H(p^1)+H(p^1,p1)

注意到:

  1. − H ( p ^ 1 ) -H(\hat{p}_1) H(p^1)是低维空间的概率分布熵,是一个定值,所以直接忽略
  2. 经验分布里的W是一个定值,也可以忽略

继续推导可得:
O 1 ( p ^ 1 , p 1 ) = − H ( p ^ 1 ) + H ( p ^ 1 , p 1 ) = H ( p ^ 1 , p 1 ) = − ∑ p ^ 1 l o g    p 1 = − ∑ i , j w i , j l o g    p 1 ( v i , v j ) \begin{aligned} O_1(\hat{p}_1, p_1) &= -H(\hat{p}_1) + H(\hat{p}_1, p_1) \\ &= H(\hat{p}_1, p_1) \\ &= -\sum \hat{p}_1 log \; p_1 \\ &= - \sum_{i, j} w_{i,j}log\;p_1(v_i, v_j) \end{aligned} O1(p^1,p1)=H(p^1)+H(p^1,p1)=H(p^1,p1)=p^1logp1=i,jwi,jlogp1(vi,vj)

注意
一阶相似度只能用于无向图

基于二阶相似度生成embedding

核心思想借鉴word2vec,即认为邻居相似的节点相似。不管是skip-gram架构还是CBOW架构,都是基于这个思想的。这里采用的是skip-gram架构。

原空间的经验分布
定义由中心点 v i v_i vi推出邻居节点 v j v_j vj的概率为:
p ^ 2 ( v j ∣ v i ) = w i , j d i \begin{aligned} \hat{p}_2(v_j | v_i ) &= \frac{w_{i,j}}{d_i} \end{aligned} p^2(vjvi)=diwi,j
其中:

  • w i , j w_{i, j} wi,j是节点 v i v_i vi v j v_j vj之间边的权重
  • d i d_i di是节点 v i v_i vi出度,即节点 v i v_i vi所有边的权重和

embedding空间的分布
定义:
当一个节点v作为邻居节点时,其低维度向量表示为 U v ′ ⃗ \vec{U'_v} Uv
当一个节点v作为中心点时,其低维度向量表示为 U v ⃗ \vec{U_v} Uv
其实上面2个embedding是一样的,只是为了下面的表达式好写。

由中心点 v i v_i vi推出邻居节点 v j v_j vj的概率为:
p 2 ( v j ∣ v i ) = p ( v j , v i ) p ( v i ) = s o f t m a x ( U ⃗ j , U ⃗ i ) = e x p ( U j ′ ⃗ ∗ U i ⃗ ) ∑ k ∈ ∣ V ∣ e x p ( U k ′ ⃗ ∗ U i ⃗ ) \begin{aligned} p_2(v_j | v_i ) &= \frac {p(v_j, v_i)} {p(v_i)} \\ &= softmax(\vec{U}_j, \vec{U}_i) = \frac {exp(\vec{U'_j} * \vec{U_i} )}{\sum_{k \in |V|} exp(\vec{U'_k} * \vec{U_i})} \end{aligned} p2(vjvi)=p(vi)p(vj,vi)=softmax(U j,U i)=kVexp(Uk Ui )exp(Uj Ui )
其中:|V|是中心点 v i v_i vi的所有直接相邻的邻居节点

优化目标/分布的相似度
类似地,优化目标是最小化 O 2 O_2 O2,其中 O 2 O_2 O2是原空间中经验分布和embedding空间分布的距离,同样用KL散度衡量,有:
O 2 = ∑ ( i , j ) ∈ E λ i ∗ d i s t a n c e ( p ^ 2 ( ⋅ ∣ v i ) , p 2 ( ⋅ ∣ v i ) ) O_2 = \sum_{(i, j) \in E} \lambda_i * distance(\hat{p}_2 (\cdot | v_i), p_2 (\cdot | v_i)) O2=(i,j)Eλidistance(p^2(vi),p2(vi))
其中:

  • λ i \lambda_i λi是节点 v i v_i vi的权重,在文章中直接将 λ i = d i \lambda_i = d_i λi=di,即节点 v i v_i vi的出度(节点 v i v_i vi所有边的权重和)

再用KL散度推导后得到:
O 2 = − ∑ ( i , j ) ∈ E λ i p ^ 2 l o g    p 2 ( v j ∣ v i ) = − ∑ ( i , j ) ∈ E d i w i , j d i l o g    p 2 ( v j ∣ v i ) = − ∑ ( i , j ) ∈ E w i , j l o g    p 2 ( v j ∣ v i ) \begin{aligned} O_2 &= - \sum_{(i,j) \in E} \lambda_i \hat{p}_2log\;p_2(v_j | v_i) \\ &=- \sum_{(i,j) \in E} d_i \frac{w_{i, j}}{d_i} log\;p_2(v_j | v_i) \\ &=- \sum_{(i,j) \in E} w_{i, j} log\;p_2(v_j | v_i) \end{aligned} O2=(i,j)Eλip^2logp2(vjvi)=(i,j)Edidiwi,jlogp2(vjvi)=(i,j)Ewi,jlogp2(vjvi)

Edge sampling

因为计算一阶、二阶相似度,需要用到所有节点,计算量太大了,所以考虑用edge sampling优化,edge sampling和negative sampling相似(negative sampling的逻辑可见这里

也就是计算优化目标 O 2 O_2 O2时,这么计算:
O 2 = l o g    σ ( U j ′ ⃗ T ∗ U i ⃗ ) + ∑ n = 1 K l o g    σ ( − U n ′ ⃗ T ∗ U i ⃗ ) O_2 = log \;\sigma(\vec{U'_j}^T * \vec{U_i}) + \sum_{n = 1}^K log \; \sigma(-\vec{U'_n}^T * \vec{U_i}) O2=logσ(Uj TUi )+n=1Klogσ(Un TUi )
其中后面一项中,下标为n(1~K个)的点,都是从noise distribution中抽取的点

特例处理

邻居很少的节点
在二阶相似度里,用到邻居的邻居来补充context word,即此时节点i和节点j的二阶相似度为:
w i , j = ∑ k ∈ N ( i ) w i , k w k , j d k w_{i,j} = \sum_{k \in N(i)}w_{i,k}\frac{w_{k, j}}{d_k} wi,j=kN(i)wi,kdkwk,j

新增的节点
对于新增的节点的embedding,通过优化下列任一目标:
O 1      o r      O 2 O_1 \;\; or \;\; O_2 O1orO2
改变原先节点的embedding,只改变新节点的embedding来最小化距离

node2vec: Scalable Feature Learning for Networks

改进自DeepWalk,区别在于:

  1. 邻居节点的选取:用两个参数p, q控制的随机游走出来的节点

优化目标
仍然和word2vec的skip-gram相似,希望能最大化P’,其中P’为:
P ′ = ∑ u ∈ V l o g    p [ N s ( u ) ∣ f ( u ) ] = ∑ u ∈ V [ − l o g Z u + ∑ n i ∈ N s ( u ) f ( n i ) ⋅ f ( u ) ] \begin{aligned} P' &= \sum_{u \in V} log \;p[N_s(u) | f(u)] \\ &= \sum_{u \in V}[-log Z_u + \sum_{n_i \in N_s(u)}f(n_i) \cdot f(u)] \end{aligned} P=uVlogp[Ns(u)f(u)]=uV[logZu+niNs(u)f(ni)f(u)]
其中:

  1. N s ( u ) N_s(u) Ns(u)是节点u的邻居节点
  2. f(u)是降维后u的向量表示
  3. Z u = ∑ n ∈ V e x p ( f ( n ) ⋅ f ( u ) ) Z_u = \sum_{n \in V} exp(f(n) \cdot f(u)) Zu=nVexp(f(n)f(u)),当节点全集 V V V过大时,这一项通常用negative sampling来缩减计算复杂度

node2vec创新在邻居节点的选取上,使用了有偏的随机游走方式

假设当前已经从节点t走到节点v,则定义从节点v向其他节点(节点x)的转移概率 π v x \pi_{vx} πvx为:
π v x = α p q ( t , x ) ⋅ ω v x \pi_{vx} = \alpha_{pq}(t, x) \cdot \omega_{vx} πvx=αpq(t,x)ωvx
其中 α p q ( t , x ) \alpha_{pq}(t, x) αpq(t,x)为:
α p q ( t , x ) = { 1 p    d t x = 0 1    d t x = 1 1 q    d t x = 2 \alpha_{pq}(t, x)= \begin{cases} \frac{1}{p} & \; d_{tx} = 0 \\ 1 & \; d_{tx} = 1 \\ \frac{1}{q} & \; d_{tx} = 2 \end{cases} αpq(t,x)=p11q1dtx=0dtx=1dtx=2
其中 d t x d_{tx} dtx表示节点t到节点x的距离,讨论情况:

  • p,可以理解成再走回上一个节点的概率倒数,如图,从v到t的概率是 1 p \frac{1}{p} p1
    • 如果p>1,则 1 p < 1 \frac{1}{p} < 1 p1<1,不会再走重复的节点(回头路)
    • 如果p<1,则 1 p > 1 \frac{1}{p} > 1 p1>1,会走重复的节点(回头路)
  • q,可以理解成,从v节点向更远处走的概率倒数,如图,向更远处的点 x 2 , x 3 x_2, x_3 x2,x3的概率是 1 q \frac{1}{q} q1
    • 如果q > 1,则 1 q < 1 \frac{1}{q} < 1 q1<1,倾向于BFS
    • 如果q < 1,则 1 q > 1 \frac{1}{q} > 1 q1>1,倾向于DFS

BFS和DFS倾向对节点embedding的影响
BFS的游走方式,训练出来的embedding,会更看重节点的结构信息,也即具有相似结构的节点embedding更相似。
DFS的游走方式,更能体现节点的“宏观”邻居,然而有过拟合的风险。

SDNE/Structural Deep Network Embedding

改进自LINE,区别在于:

  1. 一阶相似度不同:一阶相似度对应的损失,变成了encoder输出两两之间的差别,目的仍然是对local structure建模
  2. 二阶相似度不同:二阶相似度对应的损失,是原始输入和原始输入经过encoder-decoder后的差别,目的是对global structure建模。不再依赖随机游走等策略选择context word然后用word2vec架构了,而是直接encoder-decoder

Loss函数:
L = L 2 n d + α L 1 s t + ν L r e g = ∑ i = 1 n ∥ ( x ^ i − x i ) ⊗ b i ∥ 2 + α ∑ i , j = 1 n s i , j ∥ y i − y j ∥ 2 + ν 2 ∑ k = 1 K ( ∥ W K ∥ 2 + ∥ W ^ K ∥ ) \begin{aligned} L &= L_{2nd} + \alpha L_{1st} + \nu L_{reg} \\ &= \sum_{i = 1}^n \lVert (\hat{x}_i - x_i) \otimes b_i \lVert ^ 2 + \alpha \sum_{i, j = 1}^n s_{i, j} \lVert y_i - y_j \rVert ^ 2 + \frac{\nu}{2} \sum_{k = 1}^K (\lVert W^K \rVert ^ 2 + \lVert \hat{W}^K \rVert) \end{aligned} L=L2nd+αL1st+νLreg=i=1n(x^ixi)bi2+αi,j=1nsi,jyiyj2+2νk=1K(WK2+W^K)
其中:

  1. n为图的节点总数
  2. x i x_i xi是邻接矩阵S的第i行, x ^ i \hat{x}_i x^i x i x_i xi经过encoder-decoder后的输出,即 x ^ i = D e c o d e r ( E n c o d e r ( x i ) \hat{x}_i = Decoder(Encoder(x_i) x^i=Decoder(Encoder(xi)
  3. b i = { 1 , i f s i , j = 0 β > 0 , e l s e \begin{aligned}b_i = \begin{cases} 1, &if\quad s_{i, j} = 0 \\ \beta > 0, &else\end{cases}\end{aligned} bi={1,β>0,ifsi,j=0else
  4. s i , j s_{i, j} si,j是邻接矩阵中对应第i个节点和第j个节点的关系,即若(i, j)之间存在边,则为1,否则为0
  5. y i y_i yi是encoder中输入为第i个节点的输出,文中用的是DNN,即 y i = E n c o d e r ( x i ) = D N N ( x i ) y_i = Encoder(x_i) = DNN(x_i) yi=Encoder(xi)=DNN(xi)
  6. W K W^K WK是encoder的第K层的weight matrix, W ^ K \hat{W}^K W^K是decoder的第K层的weight matrix

EGES/Billion-scale Commodity Embedding for E-commerce Recommendation in Alibaba

改进自DeepWalk,主要改进点:

  1. 建图,图是根据业务场景自己建的
  2. 把其他embedding和graph embedding融合在一起了(加权平均的方式)

item建图:有向、有权图
对所有user,抽取1个session内user依次看过的item,先看的item指向后看的item,边的权重为该序列的出现次数

计算item embedding
建完图之后,用DeepWalk计算embedding,然后与其他的embedding(from side information)求加权平均得到最终的embedding,加权平均的权重,是对item对应的embedding求softmax,如:
假设共有5个embedding,其中emb0是graph embedding,其他4个emb1, emb2, emb3, emb4都是从side information计算出来的embedding,那么emb0的第i行第j列对应的权重为:
W i , j e m b 0 = e e m b 0 i , j e e m b 0 i , j + e e m b 1 i , j + e e m b 2 i , j + e e m b 3 i , j + e e m b 4 i , j W^{emb0}_{i,j} = \frac{e^{emb0_{i,j}}}{e^{emb0_{i,j}} + e^{emb1_{i,j}} + e^{emb2_{i,j}} + e^{emb3_{i,j}} + e^{emb4_{i,j}}} Wi,jemb0=eemb0i,j+eemb1i,j+eemb2i,j+eemb3i,j+eemb4i,jeemb0i,j

GCN/Semi-Supervised Classification with Graph Convolutional Networks

参考:http://tkipf.github.io/graph-convolutional-networks/
这里丢弃比较复杂的数学推导,从神经网络的角度来理解:
对GCN来说,每层的传递为:
H ( l + 1 ) = f ( H ( l ) , A ) = σ ( A H ( l ) W ( l ) ) \begin{aligned} H^{(l + 1)} &= f(H^{(l)}, A) \\ &=\sigma(AH^{(l)}W^{(l)}) \end{aligned} H(l+1)=f(H(l),A)=σ(AH(l)W(l))
其中:

  1. f ( ⋅ ) f(·) f()是传递的函数,在GCN中 H ( l + 1 ) = f ( H ( l ) , A ) = σ ( A H ( l ) W ( l ) ) H^{(l + 1)} = f(H^{(l)}, A) = \sigma(AH^{(l)}W^{(l)}) H(l+1)=f(H(l),A)=σ(AH(l)W(l)) W ( l ) W^{(l)} W(l)是第l层的参数
  2. A是图的邻接矩阵,A.shape = N x NN是节点的个数
  3. H ( 0 ) = X , H ( L ) = Z H^{(0)} = X, H^{(L)} = Z H(0)=X,H(L)=Z X X X是输入的feature,X.shape = N x DD是特征个数, Z Z Z是最终学出来的GCN feature,Z.shape = N x FF是GCN feature个数

上述方法有2个缺点:

  1. A作为邻接矩阵, A i i = 0 A_{ii} = 0 Aii=0,除非在图中有自环
  2. 邻接矩阵没有归一化,可能会导致feature scale不同

解决方法也比较简单:

  • 对问题1,给邻接矩阵加上一个单位阵 I I I,即使用 A ^ = A + I \hat{A} = A + I A^=A+I
  • 对问题2,把增加了单位阵 I I I后的邻接矩阵归一化,保证邻接矩阵每行的和为1,即使用 D ^ − 1 2 A ^ D ^ 1 2 \hat{D}^{-\frac{1}{2}}\hat{A}\hat{D}^{\frac{1}{2}} D^21A^D^21,其中 D ^ \hat{D} D^是增加了自环后的节点度矩阵,是一个对角阵

最终GCN的传播为:
H ( l + 1 ) = f ( H ( l ) , A ) = σ ( D ^ − 1 2 A ^ D ^ 1 2 H ( l ) W ( l ) ) H^{(l + 1)} = f(H^{(l)}, A) = \sigma(\hat{D}^{-\frac{1}{2}}\hat{A}\hat{D}^{\frac{1}{2}}H^{(l)}W^{(l)}) H(l+1)=f(H(l),A)=σ(D^21A^D^21H(l)W(l))

详细的数学推导,可以参考这里:如何理解 Graph Convolutional Network(GCN)? - superbrother的回答 - 知乎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
时空图Transformer (Graph Transformer)是一种基于自注意力机制的新型预测框架,用于准确预测人群轨迹。它利用Transformers来学习时间、空间和时空注意力的关系,提供了一种简洁有效的解决方案。具体地,时空图Transformer使用了空间图Transformer和时间图Transformer来捕捉人与人之间的交互,并通过在空间Transformer和时间Transformer之间进行交错来提取行人之间的时空交互。另外,时空图Transformer还引入了TGConv,一种基于Transformer的图卷积机制,用于改进基于注意力的图卷积,从而能够更好地捕捉更复杂的社交互动。此外,为了处理时间序列数据建模时的问题,时空图Transformer还引入了一个可读写图形内存模块,用于在预测期间对嵌入执行平滑操作。总体而言,时空图Transformer是一种简单而有效的策略,用于预测人群轨迹并建模行人之间的时空交互关系。 [2 [3<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【ECCV2020】Spatio-Temporal Graph Transformer Networks for Pedestrian Trajectory Prediction](https://blog.csdn.net/zn0412/article/details/120829830)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [论文阅读笔记7——TransMOT: Spatial-Temporal Graph Transformer for MOT](https://blog.csdn.net/wjpwjpwjp0831/article/details/121359323)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值