Skip to main content

· One min read
Hu Chen

G={V,E}\mathcal{G=\{V,E\}}, node set V={v1,...,vn}\mathcal{V}=\{v_1, ..., v_n\} and the undirected edge set E={e1,...,em}\mathcal{E}=\{e_1, ..., e_m\}.

Cause edge is undircted, for edge e=(i,j)e=(i,j), we let i<ji < j.

adjacency matrix A\bold{A}, graph Laplacian matrix L\bold{L}. incidence matrix Δ\Delta as m×nm\times n, define as if e=(i,j)e_{\ell}=(i,j) (i<ji < j), then \ell-th row is:

Δ=(0,...,1,...,1,...,0)\Delta_{\ell} = (0, ..., -1, ..., 1, ..., 0)

From node ii to node jj, edge \ell leaves node ii, and enters node jj.

Then

L=ΔΔ\bold{L} = \Delta^{\top} \Delta

Proof

Lij=k=1mΔkiΔkj\bold{L}_{ij} = \sum_{k=1}^m \Delta_{ki} \Delta_{kj}
  • If i=ji = j, then Lij=k=1mΔki2\bold{L}_{ij}= \sum_{k=1}^m \Delta_{ki}^2, since Δki=1\Delta_{ki}=-1 if edge kk leaves node ii, Δki=1\Delta_{ki}=1 if edge kk enters node ii, Lij\bold{L}_{ij} is degree of node ii
  • If iji \not= j, and there is an edge kk from node ii to node jj, then Δki=1\Delta_{ki}=-1, Δkj=1\Delta_{kj}=1, thus Lij=1\bold{L}_{ij}=-1
  • If iji \not= j, and there is no edge from node ii to node jj, for any edge kk, at least one of Δki\Delta_{ki} and Δkj\Delta_{kj} is 0, thus Lij=0\bold{L}_{ij}=0

· 6 min read
Hu Chen

本文是为了解释 OGB LSC 中使用 DGL 实现 GCNconv 的代码。

GCN

AA 邻接矩阵, A~=A+I\tilde{A}=A+ID~\tilde{D} 是对角度矩阵, D~ii=jA~ij\tilde{D}_{ii}=\sum_j \tilde{A}_{ij}

H(l+1)=D~1/2A~D~1/2H(l)W(l)H^{(l+1)} = \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} H^{(l)} W^{(l)}

要在 GCN 中加入边信息, 对于单个节点的更新

hi(l+1)=jN(i)1N(j)+1N(i)+1ReLU(hj(l)Wn(l)+ejiWe(l))+1N(i)+1ReLU(hi(l)Wn(l)+eiiWe(l))\begin{aligned} h^{(l+1)}_i &= \sum_{j \in N(i)} \frac{1}{\sqrt{N(j)+1}\sqrt{N(i)+1}} \mathrm{ReLU}(h_{j}^{(l)} W_n^{(l)} + e_{ji}W_e^{(l)}) \\ \quad &+ \frac{1}{N(i)+1}\mathrm{ReLU}(h_{i}^{(l)} W_n^{(l)} + e_{ii}W_e^{(l)}) \end{aligned}

假设传入的图 g 是无向图并且没有加入自环(例如,ogb smile2graph 中将分子从SMILES转化为分子图时,没有加入自环)。如下的代码表示 D~\tilde{D},为了节省内存,实际上就是度向量,而且我们没有向 g 中加入自环(当然也可以这样做)。这样每个节点的度至少为1,不会出现 1 / degsinf 的情况。

degs = (g.out_degrees().float() + 1).to(x.device)

接下来对度矩阵取-1/2幂,

deg_inv_sqrt = torch.pow(degs, -0.5).unsqueeze(-1)  # (N, 1)
g.ndata["norm"] = deg_inv_sqrt

使用 apply_edges 为边增加特征 norm

normji=1N(j)+11N(i)+1\mathrm{norm}_{ji}= \frac{1}{\sqrt{N(j)+1}} \frac{1}{\sqrt{N(i)+1}}
g.apply_edges(fn.u_mul_v("norm", "norm", "norm"))

我们不更新边的特征,在每层对原始的边特征做嵌入。节点 jj 传递到节点 iijij \rightarrow i)传递的消息为,

mji(l)=1N(j)+1N(i)+1ReLU(hjlWn(l)+ejiWe(l))m_{ji}^{(l)} = \frac{1}{\sqrt{N(j)+1}\sqrt{N(i)+1}} \mathrm{ReLU}(h^{l}_j W_n^{(l)} + e_{ji}W_e^{(l)})

边的嵌入,根据原始边特征的表示方式可以有两种方案:

  • one-hot + nn.Linear
  • index + nn.Embedding
x = self.linear(x)
g.ndata["x"] = x
g.apply_edges(fn.copy_u("x", "m"))
g.edata["m"] = g.edata["norm"] * F.relu(
g.edata["m"] + edge_embedding)

加下来只需要聚合函数更新节点特征,

hi(l+1)=jN(i)mji(l)h^{(l+1)}_i = \sum_{j \in N(i)} m_{ji}^{(l)}
g.update_all(fn.copy_e("m", "m"), fn.sum("m", "new_x"))

接下来我们还需要两个操作,

  • 第一个是由于我们没有加入自环,所以上述操作不会聚合自己上一层的信息.
  • 在消息传递过程中,我们加入了边的信息,若想等价于先加入自环再作用GCN的效果,我们同时需要传递自环的信息(自环本身就是边),因此为自环设置一个单独的 embedding root_emb = nn.Embedding(1, emb_dim).
out = g.ndata["new_x"] + F.relu(
x + self.root_emb.weight
) / degs.view(-1, 1)

Self-loop feature

设置 root_emb 可以看成是自环的替代方案,否则需要为边的特征加入一维表示该边是否为自环,这种方法,从实现层面可以有两种。

one-hot

如果边的特征使用 one-hot 向量表示的,DGLlife中的 BondFeaturizer 是这样表示的。例如若第一个特征有3个取值,第2个特征有2个取值,对于两条边表示如下

  [1, 0, 0, | 0, 1]
[0, 0, 1, | 1, 0]

则可以这样加入自环,

  [1, 0, 0, | 0, 1, | 0]
[0, 0, 1, | 1, 0, | 0]
[0, 0, 0, | 0, 0, | 1]

之后在 GCNconv 的每层对边特征接一个 nn.Linear,可达到相同的效果。

index

边的特征还可以是由每一个特征对应的 index 表示, 这样可以减少内存的消耗,例如对于上面的例子,边的特征可以表示为

[0, 1]
[2, 0]

通常后面接 nn.Embedding 得到边的嵌入。OGB 中 smiles2graph 是这样得到 边特征 的。 若是加入自环,则可以这样表示加入的自环: 将原始的 index + 1,即每个维度的取值个数都+1,并加入是否自环这一特征,

[1, 2, 0]
[3, 1, 0]
[0, 0, 1]

这样每一维中 index=0 就表示 padding 的特征,设置 nn.Embedding(padding_idx=0) ,对应的 index=0 的向量为0,这样原来图中有的边既不会增加额外信息,又为自环这一特征做了嵌入,达到相同的效果。

Comment

第二种方案需要把 ogb 的涉及到上面的代码 copy 过来做修改,并且又要加入自环,具有额外的空间开销,我想它们是想避免这个问题从而使用相同效果的 root_emb的,可以参考 root_emb issue 中大佬对这个问题的的回复。

Code

代码来自 OGB LSC GCNconv DGL,并稍作修改。BondEncoder 是直接得到分子图中键的嵌入。

class GCNConv(nn.Module):
def __init__(self, emb_dim):
"""
emb_dim (int): node embedding dimensionality
"""
super(GCNConv, self).__init__()

self.linear = nn.Linear(emb_dim, emb_dim)
self.root_emb = nn.Embedding(1, emb_dim)
self.bond_encoder = BondEncoder(emb_dim=emb_dim)

def forward(self, g, x, edge_attr):
with g.local_scope():
x = self.linear(x)
edge_embedding = self.bond_encoder(edge_attr)

# Molecular graphs are undirected
# g.out_degrees() is the same as g.in_degrees()
degs = (g.out_degrees().float() + 1).to(x.device)
deg_inv_sqrt = torch.pow(degs, -0.5).unsqueeze(-1) # (N, 1)
g.ndata["norm"] = deg_inv_sqrt
g.apply_edges(fn.u_mul_v("norm", "norm", "norm"))

g.ndata["x"] = x
g.apply_edges(fn.copy_u("x", "m"))
g.edata["m"] = g.edata["norm"] * F.relu(
g.edata["m"] + edge_embedding
)
g.update_all(fn.copy_e("m", "m"), fn.sum("m", "new_x"))
out = g.ndata["new_x"] + F.relu(
x + self.root_emb.weight
) / degs.view(-1, 1)

return out

Reference

· 12 min read
Hu Chen

Unconditional model

假设有观测变量 x\bold{x}, 真实分布 p(x)p(\bold{x}) 是未知的,我们想用模型 pθ(x)p_{\boldsymbol{\theta}}(\bold{x}) 去近似这个未知分布,参数为 θ\boldsymbol{\theta} :

pθ(x)p(x)(1)p_{\boldsymbol{\theta}}(\bold{x}) \approx p(\bold{x}) \tag{1}

TODO: 最大化极大似然 最大化对数似然 ML = 最小化 KL ML and MAP

我们可以使用最大似然 (Maximum Likelihood) 去找到参数为 θ\boldsymbol{\theta} ,从而得到我们的模型 pθ(x)p_{\boldsymbol{\theta}}(\bold{x})

但是我们不知道 p(x)p(\bold{x}) 是什么样的,例如如果其分布符合多元高斯分布,则可以比较容易的求出。但真实的 p(x)p(\bold{x}) 往往是非常复杂的,x\bold{x} 可以是文本,图片,甚至是graph。

我们知道神经网络模型 (Neural Network, NN) 能够表示复杂的模型,如果使用NN 表示 pθ(x)p_{\boldsymbol{\theta}}(\bold{x}),NN 的参数为 θ\boldsymbol{\theta}。下面以一个样本为例,

  • 假设 xip(x)\bold{x}_i \sim p(\bold{x}) 是一个样本,我们想要最大似然 pθ(xi)p_{\boldsymbol{\theta}}(\bold{x}_i),在 NN 中我们使用梯度下降优化目标函数
  • 我们想要求 pθ(xi)p_{\boldsymbol{\theta}}(\bold{x}_i) 的梯度,去更新 NN 的参数,从而达到最大似然的目的
  • 将已知样本 xi\bold{x}_i 作为 NN 输入,θ\boldsymbol{\theta} 作为 NN 参数,输出为一个预测的概率值,但是我们没有监督信息,无法设计损失函数

因此 pθ(x)p_{\bold{\theta}}(\bold{x}) is intractable.

Deep Latent Variable Models

For the intractbility of pθ(x)p_{\bold{\theta}}(\bold{x}),我们引入隐变量 z\bold{z},对于无条件的观测变量 x\bold{x} ,加入隐变量 z\bold{z},得到联合分布 pθ(x,z)p_{\bold{\theta}}(\bold{x}, \bold{z}),称为隐变量模型,此时 pθ(x)p_{\bold{\theta}}(\bold{x}) 可用边际分布来表示:

pθ(x)=pθ(x,z)dz(2)p_{\bold{\theta}}(\bold{x}) = \int p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) d\bold{z} \tag{2}

也称为 marginal likelihood 或 model evidence。这种在 x\bold{x} 上隐式的分布非常灵活。

我们知道对于隐变量模型:

pθ(x,z)=pθ(z)pθ(xz)(3)p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) = p_{\boldsymbol{\theta}}(\bold{z}) p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) \tag{3}

pθ(z)p_{\boldsymbol{\theta}}(\bold{z}) 称为先验分布 (prior distribution),pθ(xz)p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 是条件分布 (conditional distribution)。

  • z\bold{z} 是离散的,且 pθ(xz)p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 是高斯分布,则 x\bold{x} 是有限混合高斯分布
  • z\bold{z} 是连续的,且 pθ(xz)p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 是高斯分布,则 x\bold{x} 是无限混合高斯分布

若用 NN 表示 pθ(x,z)p_{\boldsymbol{\theta}}(\bold{x}, \bold{z})θ\boldsymbol{\theta} 是 NN 的参数,我们称其为 deep latent variable model (DLVM)。即先验或者条件分布足够简单,例如将 pθ(z)p_{\boldsymbol{\theta}}(\bold{z}) 表示为高斯分布,pθ(xz)p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 表示为伯努利分布。则得到的边际分布 pθ(x)p_{\bold{\theta}}(\bold{x}) 仍然足够复杂,模型具有很强的表达能力。

Example DLVM for multivariate Bernoulli data

假设 DD 维二元数据 x{0,1}D\bold{x} \in \{0,1\}^D,我们让先验的 PDF 为 pθ(z)=N(z;0,I)p_{\boldsymbol{\theta}}(\bold{z}) = N(\bold{z};0,\bold{I}),我们可以把 θ\boldsymbol{\theta} 去掉,因为没有参数。让 logpθ(xz)\text{log}p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 是一个多元伯努利分布,每一维独立,其概率使用 NN 从 z\bold{z} 计算出,

p(z)=N(z;0,I)(4)p(\bold{z}) = N(\bold{z};0,\bold{I}) \tag{4}
p=Decoderθ(z)(5)\bold{p} = \text{Decoder}_{\boldsymbol{\theta}}(\bold{z}) \tag{5}

其中 Decoder 的最后一层接了一个 sigmoid 函数,pjp:0pj1\forall p_j \in \bold{p}: 0 \leq p_j \leq 1x\bold{x} 是一个样本,我们要最大如下的对数似然:

logpθ(xz)=j=1Dlogpθ(xjz)(6)\text{log}p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) = \sum_{j=1}^D \text{log}p_{\boldsymbol{\theta}}(x_j | \bold{z}) \tag{6}

pθ(xjz)p_{\boldsymbol{\theta}}(x_j | \bold{z}) 是一个二元的伯努利分布,

pθ(xjz)={pjif xj=11pjif xj=0(7)p_{\boldsymbol{\theta}}(x_j | \bold{z}) = \begin{cases} p_j & \text{if }x_j = 1 \\ 1 - p_j & \text{if }x_j = 0 \end{cases} \tag{7}

使用统一形式可以表示为,

pθ(xjz)=pjxj(1pj)(1xj)(8)p_{\boldsymbol{\theta}}(x_j | \bold{z}) = p_j^{x_j} (1 - p_j)^{(1-x_j)} \tag{8}

带入 (6)(6) 中可以得到,

logpθ(xz)=j=1Dlogpθ(xjz)=j=1Dxjlogpj+(1xj)log(1pj)(9)\begin{aligned} \text{log}p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) &= \sum_{j=1}^D \text{log}p_{\boldsymbol{\theta}}(x_j | \bold{z}) \\ &= \sum_{j=1}^D x_j \log p_j + (1-x_j) \log (1-p_j) \end{aligned} \tag{9}

因此对于 pθ(x,z)=pθ(z)pθ(xz)=p(z)pθ(xz)p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) = p_{\boldsymbol{\theta}}(\bold{z}) p_{\boldsymbol{\theta}}(\bold{x} | \bold{z})=p(\bold{z}) p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) 是可以求梯度的,我们最大其对数似然,

θlogpθ(x,z)=θlog(p(z)pθ(xz))=θ(logp(z)+logpθ(xz))=θlogpθ(xz)(10)\begin{aligned} \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) &= \nabla_{\boldsymbol{\theta}} \log (p(\bold{z}) p_{\boldsymbol{\theta}}(\bold{x} | \bold{z})) \\ &= \nabla_{\boldsymbol{\theta}} (\log p(\bold{z}) + \log p_{\boldsymbol{\theta}}(\bold{x} | \bold{z})) \\ &= \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\bold{x} | \bold{z}) \end{aligned} \tag{10}

因此 pθ(x,z)p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) is tractable。

根据上述假定,

θpθ(x)=θpθ(x,z)dz(11)\nabla_{\boldsymbol{\theta}} p_{\boldsymbol{\theta}}(\bold{x}) = \int \nabla_{\boldsymbol{\theta}} p_{\boldsymbol{\theta}}(\bold{x} , \bold{z}) d\bold{z} \tag{11}

之前我们知道 pθ(x)p_{\bold{\theta}}(\bold{x}) intractable,但是如果我们引入 DLVM,只要能够对 (11)(11) 积分,我们就可以得到 pθ(x)p_{\bold{\theta}}(\bold{x}) 的梯度,从而使得 pθ(x)p_{\bold{\theta}}(\bold{x}) tractable。

Intractabilities

pθ(x,z)p_{\boldsymbol{\theta}}(\bold{x}, \bold{z}) 是一个 NN 模型,无法对其求积分,因此 (11)(11) 中的积分没有解析解,我们就无法计算梯度。 此外,the intractability of pθ(x)p_{\bold{\theta}}(\bold{x}) 与 后验分布 (Posterior Distributiion) pθ(zx)p_{\bold{\theta}}(\bold{z}|\bold{x}) 的 intractability 有关,

pθ(zx)=pθ(x,z)pθ(x)(12)p_{\bold{\theta}}(\bold{z}|\bold{x}) = \frac{p_{\boldsymbol{\theta}}(\bold{x} , \bold{z})}{p_{\bold{\theta}}(\bold{x})} \tag{12}

联合分布 pθ(x,z)p_{\boldsymbol{\theta}}(\bold{x} , \bold{z}) 由之前的例子我们已经可以算出,tractable 的posterior pθ(zx)p_{\bold{\theta}}(\bold{z}|\bold{x}) 会导致 tractable 的 marginal likelihood pθ(x)p_{\bold{\theta}}(\bold{x}),反之亦然。

为了将 DLVM intractable的后验和学习问题转化为tractable问题,我们引出下面的 inference model。

Encoder or Approximate Posterior

我们引入一个参数推断模型 (inference model) qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z}|\bold{x}) 去近似后验,这个模型也称为 encoderϕ\boldsymbol{\phi} 是推断模型的参数,称为 变分参数 (variational parameters),

qϕ(zx)pθ(zx)(13)q_{\boldsymbol{\phi}}(\bold{z}|\bold{x}) \approx p_{\boldsymbol{\theta}}(\bold{z}|\bold{x}) \tag{13}

我们会解释,这种对后验的近似会帮助最大化 marginal likelihood pθ(x)p_{\boldsymbol{\theta}}(\bold{x})

类似于DLVM,可以使用 NN 表示 qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})ϕ\boldsymbol{\phi} 是 NN 的参数,例如

(μ,logσ)=Encoderϕ(x)(14)(\boldsymbol{\mu},\log \boldsymbol{\sigma}) = \text{Encoder}_{\boldsymbol{\phi}}(\bold{x}) \tag{14}
qϕ(zx)=N(z;μ,diag(σ))(15)q_{\boldsymbol{\phi}}(\bold{z}|\bold{x}) = N(\bold{z};\boldsymbol{\mu}, \text{diag} (\boldsymbol{\sigma}) )\tag{15}

σ\boldsymbol{\sigma} 为标准差 0\geq 0,让 NN 输出为总是 0\geq 0 是困难的,因此加入 logσ\log \boldsymbol{\sigma} 使得 NN 输出不受限制。

Evidence Lower Bound (ELBO)

下面推导,加入 inference model qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z}|\bold{x}) 的好处,对于 marginal likelihood 我们有:

logpθ(x)=Eqϕ(zx)[logpθ(x)]=Eqϕ(zx)[logpθ(x,z)pθ(zx)]=Eqϕ(zx)[log[pθ(x,z)pθ(zx)qϕ(zx)qϕ(zx)]]=Eqϕ(zx)[log[pθ(x,z)qϕ(zx)]]Lθ,ϕ(x)+Eqϕ(zx)[log[qϕ(zx)pθ(zx)]]DKL(qϕ(zx)pθ(zx))(16)\begin{aligned} \log p_{\boldsymbol{\theta}}(\bold{x}) & = \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})}[\log p_{\boldsymbol{\theta}}(\bold{x})] \\ &= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} \Big[\log \frac{p_{\boldsymbol{\theta}}(\bold{x,z})}{p_{\boldsymbol{\theta}}(\bold{z|x})}\Big] \\ &= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} \Big[ \log \Big[\frac{p_{\boldsymbol{\theta}}(\bold{x,z})}{p_{\boldsymbol{\theta}}(\bold{z|x})} \frac{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})}{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})}\Big] \Big]\\ &= \underbrace{\mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} \Big[ \log \Big[\frac{p_{\boldsymbol{\theta}}(\bold{x,z})}{q_{\boldsymbol{\phi}}(\bold{z|x})} \Big] \Big]}_{\mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x})} + \underbrace{\mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} \Big[ \log \Big[\frac{q_{\boldsymbol{\phi}}(\bold{z|x})}{p_{\boldsymbol{\theta}}(\bold{z|x})} \Big] \Big]}_{D_{KL}(q_{\boldsymbol{\phi}}(\bold{z|x}) || p_{\boldsymbol{\theta}}(\bold{z|x}))} \end{aligned} \tag{16}

由上可知,

DKL(qϕ(zx)pθ(zx))0(17)D_{KL}(q_{\boldsymbol{\phi}}(\bold{z|x}) || p_{\boldsymbol{\theta}}(\bold{z|x})) \geq 0 \tag{17}

qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 等于 true posterior distribution 时,上式为0. (16)(16) 中的第一项称为 variational lower bound,或 evidence lower bound (ELBO):

Lθ,ϕ(x)=Eqϕ(zx)[logpθ(x,z)logqϕ(zx)](18)\mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) = \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x})] \tag{18}

由于 KL divergence的非负性,ELBO 是 log-likehood 的 low bound:

Lθ,ϕ(x)=logpθ(x)DKL(qϕ(zx)pθ(zx))logpθ(x)(19)\begin{aligned} \mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) &= \log p_{\boldsymbol{\theta}}(\bold{x}) - D_{KL}(q_{\boldsymbol{\phi}}(\bold{z|x}) || p_{\boldsymbol{\theta}}(\bold{z|x})) \\ &\leq \log p_{\boldsymbol{\theta}}(\bold{x}) \end{aligned} \tag{19}

如果我们可以最大化 ELBO,则

  • 它会近似最大化 marginal likelihood pθ(x)p_{\boldsymbol{\theta}}(\bold{x}),这是我们的目标,意味者我们的生成模型会边得更好
  • 它会最小化我们对 true posterior pθ(zx)p_{\boldsymbol{\theta}}(\bold{z|x}) 和近似分布 qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 之间的距离,所以 qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 会变的更好

SGD on the ELBO

最大化 ELBO 等价于最小化负的 ELBO,如果我们能够求出 ELBO 的梯度,则可以使用 SGD 来优化参数 ϕ\boldsymbol{\phi}θ\boldsymbol{\theta}。ELBO 相对于 generative model parameters θ\boldsymbol{\theta} 的梯度为:

θLθ,ϕ(x)=θEqϕ(zx)[logpθ(x,z)logqϕ(zx)]=Eqϕ(zx)[θ(logpθ(x,z)logqϕ(zx))]=Eqϕ(zx)[θ(logpθ(x,z))]θ(logpθ(x,z))(20)\begin{aligned} \nabla_{\boldsymbol{\theta}} \mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) &= \nabla_{\boldsymbol{\theta}} \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x}) ] \\ &= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\nabla_{\boldsymbol{\theta}}(\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x}))] \\ &= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\nabla_{\boldsymbol{\theta}}(\log p_{\boldsymbol{\theta}}(\bold{x,z}))] \\ &\simeq \nabla_{\boldsymbol{\theta}}(\log p_{\boldsymbol{\theta}}(\bold{x,z})) \\ \end{aligned} \tag{20}

最后一行我们使用 Monte Carlo 模拟去估计第3行的期望,其中 z\bold{z} 是一个 random sampple from qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x})。这是 θLθ,ϕ(x)\nabla_{\boldsymbol{\theta}} \mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) 的一个无偏梯度估计(只需要从下到上证明即可)。

对于 varational parameters ϕ\boldsymbol{\phi} 无偏梯度,由于 ELBO 是对 qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 求期望,而其又是 ϕ\boldsymbol{\phi} 的函数:

ϕLθ,ϕ(x)=ϕEqϕ(zx)[logpθ(x,z)logqϕ(zx)]Eqϕ(zx)[ϕ(logpθ(x,z)logqϕ(zx))](21)\begin{aligned} \nabla_{\boldsymbol{\phi}} \mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) &= \nabla_{\boldsymbol{\phi}} \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x})] \\ &\not= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\nabla_{\boldsymbol{\phi}}(\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x}))] \end{aligned} \tag{21}

在连续隐变量情况下,我们可以使用下面要介绍的重参数化技巧来得到 ELBO ϕ\boldsymbol{\phi} 的无偏梯度。

Reparameterization Trick

Change of variables

(21)(21) 式中对 后验 qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 求期望, 要对随机变量 z\bold{z} given x\bold{x} 求多元积分,而 z\bold{z} 是 通过 NN 得到的,是 ϕ\boldsymbol{\phi}x\bold{x} 的函数,由于 NN 的灵活性,我们可以认为 z\bold{z} 是在 x\bold{x}ϕ\boldsymbol{\phi} 给定情况下,由另外一个随机变量 ϵp(ϵ)\boldsymbol{\epsilon} \sim p(\boldsymbol{\epsilon}) 经过可微和可逆的变换 g\bold{g} 得到的,

z=gϕ(ϵ,x)(22)\bold{z} = \bold{g}_{\boldsymbol{\phi}}(\boldsymbol{\epsilon}, \bold{x}) \tag{22}

这一操作称为 Reparameterization. 忽略 x\bold{x}ϕ\boldsymbol{\phi} ,因为它们都是给定的。则 z=g(ϵ)=(g1(ϵ1,...,ϵn),...,gn(ϵ1,...,ϵn))\bold{z} = \bold{g}(\boldsymbol{\epsilon}) = (g_1(\epsilon_1, ..., \epsilon_n), ..., g_n(\epsilon_1, ..., \epsilon_n))。 由于 g\bold{g} 可逆,因此 存在逆映射 ϵ=(ϵ1,...,ϵn)=(h1(z1,...,zn),...,hn(z1,...,zn))=h(z)\boldsymbol{\epsilon}=(\epsilon_1, ..., \epsilon_n) = (h_1(z_1, ..., z_n), ..., h_n(z_1, ..., z_n))=\bold{h}(\bold{z}),因此我们有 z=g(h(z))\bold{z} = \bold{g} (\bold{h}(\bold{z})),根据链式法则:

zz=ghhz=gϵhz(23)\frac{\partial \bold{z}}{\partial \bold{z}} = \frac{\partial \bold {g}}{\partial \bold{h}} \frac{\partial \bold {h}}{\partial \bold{z}} = \frac{\partial \bold {g}}{\partial \boldsymbol{\epsilon}} \frac{\partial \bold {h}}{\partial \bold{z}} \tag{23}

等式左边是单位矩阵 I\boldsymbol{I},我们对两边取行列式,则有

1=det(I)=det(gϵhz)=det(gϵ)det(hz)(24)1 = \det (\boldsymbol{I}) = \det (\frac{\partial \bold {g}}{\partial \boldsymbol{\epsilon}} \frac{\partial \bold {h}}{\partial \bold{z}}) = \det \Big(\frac{\partial \bold {g}}{\partial \boldsymbol{\epsilon}}\Big) · \det \Big(\frac{\partial \bold {h}}{\partial \bold{z}}\Big) \tag{24}

qϕ(zx)q_{\boldsymbol{\phi}}(\bold{z|x}) 是随机变量函数的概率密度函数,则有

qϕ(zx)=p(ϵ)det(hz)(25)q_{\boldsymbol{\phi}}(\bold{z|x}) = p(\boldsymbol{\epsilon}) \Big| \det \Big( \frac{\partial \bold {h}}{\partial \bold{z}} \Big)\Big| \tag{25}

dzd\bold{z} 做变量替换 z=gϕ(ϵ,x)\bold{z} = \bold{g}_{\boldsymbol{\phi}}(\boldsymbol{\epsilon}, \bold{x}),则有

dz=det(gϵ)dϵ(26)d\bold{z} = \Big| \det \Big( \frac{\partial \bold {g}}{\partial \boldsymbol{\epsilon}}\Big) \Big| d \boldsymbol{\epsilon} \tag{26}

因此

qϕ(zx)dz=p(ϵ)det(gϵ)det(hz)=p(ϵ)dϵ(27)q_{\boldsymbol{\phi}}(\bold{z|x}) d\bold{z} = p(\boldsymbol{\epsilon})\Big| \det \Big( \frac{\partial \bold {g}}{\partial \boldsymbol{\epsilon}}\Big) \Big|·\Big| \det \Big( \frac{\partial \bold {h}}{\partial \bold{z}} \Big)\Big| = p(\boldsymbol{\epsilon}) d \boldsymbol{\epsilon} \tag{27}

Gradient under change of variables

在使用了上面的变量替换之后,对于任何一个随机变量函数 f(z)\boldsymbol{f}(\bold{z}),我们有

Eqϕ(zx)[f(z)]=Ep(ϵ)[f(z)](28)\mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\boldsymbol{f}(\bold{z})] = \mathbb{E}_{p(\boldsymbol{\epsilon})} [\boldsymbol{f}(\bold{z})] \tag{28}

我们可以使用简单的 Monte Carlo 模拟,去估计这个期望的梯度:

ϕEqϕ(zx)[f(z)]=ϕEp(ϵ)[f(z)]=Ep(ϵ)[ϕf(z)]ϕf(z)(29)\begin{aligned} \nabla_{\boldsymbol{\phi}} \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\boldsymbol{f}(\bold{z})] &= \nabla_{\boldsymbol{\phi}} \mathbb{E}_{p(\boldsymbol{\epsilon})} [\boldsymbol{f}(\bold{z})]\\ &= \mathbb{E}_{p(\boldsymbol{\epsilon})}[\nabla_{\boldsymbol{\phi}} \boldsymbol{f}(\bold{z})] \\ &\simeq \nabla_{\boldsymbol{\phi}} \boldsymbol{f}(\bold{z}) \end{aligned} \tag{29}

Gradient of ELBO

根据上面的重参数化,我们可以把 ELBO 写成如下形式:

Lθ,ϕ(x)=Eqϕ(zx)[logpθ(x,z)logqϕ(zx)]=Ep(ϵ)[logpθ(x,z)logqϕ(zx)](30)\begin{aligned} \mathcal{L}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) &= \mathbb{E}_{q_{\boldsymbol{\phi}}(\bold{z}|\bold{x})} [\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x})] \\ &= \mathbb{E}_{p(\boldsymbol{\epsilon})} [\log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x})] \end{aligned} \tag{30}

其中 z=gϕ(ϵ,x)\bold{z} = \bold{g}_{\boldsymbol{\phi}}(\boldsymbol{\epsilon}, \bold{x})。 因从我们可以使用一个简单的 Monte Carlo 模拟估计 ELBO,从 noise p(ϵ)p(\boldsymbol{\epsilon}) 中采样 ϵ\boldsymbol{\epsilon}:

ϵp(ϵ)z=gϕ(x,ϵ)L~θ,ϕ(x)=logpθ(x,z)logqϕ(zx)(31)\begin{aligned} \boldsymbol{\epsilon} &\sim p(\boldsymbol{\epsilon}) \\ \bold{z} &= \bold{g}_{\boldsymbol{\phi}}(\bold{x}, \boldsymbol{\epsilon}) \\ \tilde{\mathcal{L}}_{\boldsymbol{\theta}, \boldsymbol{\phi}}(\bold{x}) &= \log p_{\boldsymbol{\theta}}(\bold{x,z}) - \log q_{\boldsymbol{\phi}}(\bold{z|x}) \end{aligned} \tag{31}

之后我们求出其梯度,利用 minibatch SGD 优化。

Reference

· 2 min read
Hu Chen

提高收敛速度。

Batch Normalization

批量归一化 (Batch Normalization),对于一个DNN,第 ll 层的净输入为 z(l)\boldsymbol{z}^{(l)} 经过仿射变换 (Affine Transformation) =Wa(l1)+b=\boldsymbol{W}\boldsymbol{a}^{(l-1)}+\boldsymbol{b},激活函数 f()f(·)

a(l)=f(Wa(l1)+b)\boldsymbol{a}^{(l)}= f(\boldsymbol{W}\boldsymbol{a}^{(l-1)}+\boldsymbol{b})

In practice,BN before Affine Transformation, after activation function. 对一个中间层的单个神经元进行归一化,使用 Standardization 将净输入 zl\boldsymbol{z}^{l}

Layer Normalization

层归一化 (Layer Normalization) 对一个中间层的所有神经元进行归一化, 在RNN中,净输入 zt\boldsymbol{z}_t 由于会累加前一时刻的状态,会随着时间慢慢变大或变小,从而导致梯度爆炸或者消失,LN可以缓解。

KK 个样本的 mini-batch Z(l)=[z(1,l);...;z(K,l)]\boldsymbol{Z}^{(l)}=[\boldsymbol{z}^{(1,l)};...;\boldsymbol{z}^{(K,l)}],其中每个样本的特征向量用列向量表示,BN 是对矩阵的 Z(l)\boldsymbol{Z}^{(l)} 的每一行进行归一化,LN是对矩阵的每一列进行归一化。

Weight Normalization

不对净输入进行归一化,对权重进行归一化。

· 2 min read
Hu Chen

zsh是功能更强大的命令解释器,linux默认的命令解释器是bash。

zsh下载

查看系统中安装的shell有哪些:

cat /etc/shells

若没有则下载zsh:

sudo apt install zsh

oh-my-zsh

oh-my-zsh是一个已经配置文件,帮助我们配置zsh.

下载

  1. 把 oh-my-zsh 项目clone到用户目录

    git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
  2. 复制模板到用户目录下的.zshrc文件

    cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
  3. 更改默认的shell

    chsh -s /bin/zsh

之后.zshrc就替换掉了原来的.bashrc

主题配置

使用VSCode或者Vim编辑~./zshrc文件,更改主题只需替换ZSH_THEME​​ Theme

conda命令补全

  1. 下载对应插件到.oh-my-zsh​文件夹下:

    git clone https://github.com/esc/conda-zsh-completion $ZSH_CUSTOM/plugins/conda-zsh-completion
  2. 修改.zshrc​文件

    在初始化 oh-my-zsh​ 命令前加入

    fpath+=$ZSH_CUSTOM/plugins/conda-zsh-completion

    .zshrc1

最后在文件末尾中加入

compinit conda

.zshrc2 ‍ conda命令现在感觉有bug... 不是很好用,我又取消了,还是手动打吧。

参考 zsh & oh-my-zsh 的配置与使用 - 知乎 (zhihu.com)

· 5 min read
Hu Chen

默认向量都是列向量。求和符号可以简写。

拉普拉斯矩阵

定义

无向图G=(V,E)G=(V,E)ARn×nA \in \mathbb{R}^{n \times n} 为邻接矩阵,其元素

aij={1if (vi,vj)E0elsea_{ij}=\begin{cases} 1 & \mathrm{if}\ (v_i,v_j) \in E \\ 0 & \mathrm{else} \end{cases}

N(i)N(i)为结点viv_i的邻居,DRn×nD \in \mathbb{R}^{n \times n}为度矩阵,对角矩阵,其元素

dii=j=1naij=jN(i)aijd_{ii}= \sum_{j=1}^n a_{ij}= \sum _{j \in N(i)} a_{ij}

定义拉普拉斯矩阵 (Laplacian matrix) L=DAL=D-A,其元素

lij={diif i=j1if (vi,vj)E0otherwisel_{ij}= \begin{cases} d_i & \mathrm{if}\ i=j \\ -1 & \mathrm{if}\ (v_i,v_j) \in E \\ 0 & \mathrm{otherwise} \end{cases}

正则化表达形式 (symmetric normalized laplacian) Lsym=D1/2LD1/2L_{\mathrm{sym}}=D^{-1/2}LD^{-1/2},其元素

lsym(i,j)={1if i=j1didjif (vi,vj)E0otherwisel_{\mathrm{sym}}(i,j)= \begin{cases} 1 & \mathrm{if}\ i=j \\ \frac{-1}{\sqrt{d_i d_j}} & \mathrm{if}\ (v_i,v_j) \in E \\ 0 & \mathrm{otherwise} \end{cases}

总变差

定义向量x=[x1,x2,,xn]T\boldsymbol{x}=[x_1,x_2,···,x_n]^T,可认为是图信号。则

Lx=(DA)x=DxAx=[,dixij=1naijxj,]T=[,j=1naijxij=1naijxj,]T=[,j=1naij(xixj),]T\begin{aligned} L\boldsymbol{x}=(D-A)\boldsymbol{x}&=D\boldsymbol{x} - A \boldsymbol{x}\\ &=[···, d_ix_i-\sum_{j=1}^{n}a_{ij}x_j,···]^T \\ &= [···,\sum _{j=1}^{n} a_{ij} x_i - \sum _{j=1}^{n} a_{ij} x_j,···]^T \\ &= [···, \sum _{j=1}^{n}a_{ij}(x_i-x_j),···]^T \end{aligned}

分量 j=1naij(xixj)\sum _{j=1}^{n}a_{ij}(x_i-x_j) 可写成 jN(i)(xixj)\sum _{j\in N(i)}(x_i-x_j),由此可知,拉普拉斯矩阵是反映图信号局部平滑度的算子。

接着我们利用上式定义二次型,

xTLx=i=1nxij=1naij(xixj)=i=1nj=1naij(xi2xixj)\begin{aligned} \boldsymbol{x}^TL\boldsymbol{x}&=\sum_{i=1}^{n} x_i \sum _{j=1}^{n}a_{ij}(x_i-x_j) \\ &= \sum_{i=1}^{n}\sum_{j=1}^{n} a_{ij}(x_i^2-x_ix_j) \end{aligned}

调换i,ji,j符号,求和顺序保持不变,我们得到

xTLx=i=1nj=1naij(xi2xixj)=i=1nj=1naij(xj2xixj)\boldsymbol{x}^TL\boldsymbol{x}=\sum_{i=1}^{n}\sum_{j=1}^n a_{ij}(x_i^2-x_ix_j)=\sum_{i=1}^{n}\sum_{j=1}^na_{ij}(x_j^2-x_ix_j)

将等式左右两边相加,于是

xTLx=12i=1nj=1naij(xi22xixj+xj2)=12i=1nj=1naij(xixj)2\begin{aligned} \boldsymbol{x}^TL\boldsymbol{x} &= \frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^n a_{ij}(x_i^2-2x_ix_j+x_j^2) \\ &= \frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^n a_{ij}(x_i-x_j)^2 \end{aligned}

由公式可以看出,二次型 xTLx\boldsymbol{x}^TL\boldsymbol{x} 能刻画图信号的总体平滑度,称为总变差。

来源

拉普拉斯矩阵的定义来源于拉普拉斯算子,nn维欧式空间中的一个二阶微分算子:Δf=i=1n2fxi2\Delta f=\sum_{i=1}^n \frac{\partial ^2 f}{\partial x_i^2}。将该算子退化到离散二维图像空间就是边缘检测算子:

Δf(x,y)=2f(x,y)x2+2f(x,y)y2=[(f(x+1,y)f(x,y))(f(x,y)f(x1,y))]+[(f(x,y+1)f(x,y))(f(x,y)f(x,y1))]=[f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)]4f(x,y)\begin{aligned} \Delta f(x,y) &= \frac{\partial ^2 f(x,y)}{\partial x^2} + \frac{\partial ^2 f(x,y)}{\partial y^2}\\ &= [(f(x+1,y)-f(x,y))-(f(x,y)-f(x-1,y))]\\ &+ [(f(x,y+1)-f(x,y))-(f(x,y)-f(x,y-1))]\\ &= [f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)] -4f(x,y) \end{aligned}

图像处理中通常被当作模板的形式:

[010141010]\begin{bmatrix} 0 & 1 & 0\\ 1 & -4 & 1 \\0 & 1 & 0 \end{bmatrix}

拉普拉斯算子用来描述中心像素与局部上、下、左、右四邻居像素的总的差异,这种性质经常也被用来当作图像上的边缘检测算子。

Laplacian Eigenmaps

假设图 G=(V,E)G=(V,E) 中有 nn 个节点,嵌入维度为 dd,可得到如下 n×dn \times d 矩阵 YY

[y1(1)y1(2)y1(d)y2(1)y2(2)y2(d)yn(1)yn(2)yn(d)]\begin{bmatrix} y_1^{(1)} & y_1^{(2)} & \cdots & y_1^{(d)} \\ y_2^{(1)} & y_2^{(2)} & \cdots & y_2^{(d)} \\ \vdots & \vdots & \ddots& \vdots \\ y_n^{(1)} & y_n^{(2)} & \cdots & y_n^{(d)} \end{bmatrix}

nn 维行向量 yk=[yk(1),yk(2),...,yk(d)]\boldsymbol{y}_k=[y_k^{(1)},y_k^{(2)}, ..., y_k^{(d)}],可表示一个节点的Embedding。

拉普拉斯特征映射(Laplacian Eigenmaps)用于图嵌入中,在图中邻接的节点,在嵌入空间中距离应该尽可能的近。可将其作为一阶相似性的定义,因此可以定义如下的loss function:

L1st=i=1nj=1naijyiyj22\mathcal{L}_{1st}=\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij} ||\boldsymbol{y_i}-\boldsymbol{y_j}||_2^2

nn 维列向量 y(k)=[y1(k),y2(k),,yn(k)]T\boldsymbol{y}^{(k)} = [y_1^{(k)}, y_2^{(k)}, ···,y_n^{(k)}]^T,对应图中所有节点的第 kk 维的值,可指一组图信号。因此可以得到,

L1st=i=1nj=1naijyiyj22=i=1nj=1naijk=1d(yi(k)yj(k))2=k=1di=1nj=1naij(yi(k)yj(k))2=2k=1dy(k)TLy(k)=2tr(YTLY)\begin{aligned} \mathcal{L}_{1st}=\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij} ||\boldsymbol{y_i}-\boldsymbol{y_j}||_2^2&= \sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij} \sum_{k=1}^d (y_{i}^{(k)}-y_{j}^{(k)})^2 \\ &= \sum_{k=1}^d \sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij} (y_{i}^{(k)}-y_{j}^{(k)})^2 \\ &= 2\sum_{k=1}^d \boldsymbol{y}^{(k)T} L \boldsymbol{y}^{(k)} \\ &= 2tr(Y^TLY) \end{aligned}

tr()tr(·) 指矩阵的迹 (trace)。

总变差的另一种推导

对任意nn维列向量 y=[y1,y2,...,yn]T\boldsymbol{y}=[y_1, y_2, ..., y_n]^T,展开可得到,

yTLy=yTDyyTAy=i=1ndiyi2i=1nj=1naijyiyj=12(i=1ndiyi22i=1nj=1naijyiyj+j=1ndjyj2)=12(i=1nj=1naijyi22i=1nj=1naijyiyj+j=1ni=1najiyj2)=12(i=1nj=1naijyi22i=1nj=1naijyiyj+i=1nj=1naijyj2)=12i=1nj=1naij(yiyj)2\begin{aligned} \boldsymbol{y}^TL\boldsymbol{y}&= \boldsymbol{y}^T D \boldsymbol{y} - \boldsymbol{y}^T A \boldsymbol{y}\\ &= \sum_{i=1}^{n} d_iy_i^2- \sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij} y_iy_j\\ &= \frac{1}{2} (\sum_{i=1}^{n} d_iy_i^2 -2\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_iy_j + \sum_{j=1}^{n} d_jy_j^2) \\ &=\frac{1}{2} (\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_i^2 -2\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_iy_j + \sum_{j=1}^{n} \sum_{i=1}^{n} a_{ji}y_j^2) \\ &=\frac{1}{2} (\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_i^2 -2\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_iy_j + \sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}y_j^2) \\ &= \frac{1}{2}\sum_{i=1}^{n} \sum_{j=1}^{n} a_{ij}(y_i-y_j)^2 \end{aligned}

其中利用了 AA 是对称矩阵,aij=ajia_{ij}=a_{ji}

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.