From e6ff4123744860044059eeecf90b1ead86b7af54 Mon Sep 17 00:00:00 2001 From: ashawkey Date: Mon, 20 Nov 2023 15:05:54 +0800 Subject: [PATCH] update --- .../image-20231120100645841.png | Bin 0 -> 15950 bytes .../image-20231120102716151.png | Bin 0 -> 7935 bytes .../image-20231120113854817.png | Bin 0 -> 18226 bytes .../image-20231120114151607.png | Bin 0 -> 39982 bytes docs/math/quaternion.md | 312 +++++++++++++++++- docs/writings/rebuttals.md | 103 ++---- 6 files changed, 324 insertions(+), 91 deletions(-) create mode 100644 docs/math/quaternion.assets/image-20231120100645841.png create mode 100644 docs/math/quaternion.assets/image-20231120102716151.png create mode 100644 docs/math/quaternion.assets/image-20231120113854817.png create mode 100644 docs/math/quaternion.assets/image-20231120114151607.png diff --git a/docs/math/quaternion.assets/image-20231120100645841.png b/docs/math/quaternion.assets/image-20231120100645841.png new file mode 100644 index 0000000000000000000000000000000000000000..f68bedc4019f8a2454613677af2406721f9ed4e2 GIT binary patch literal 15950 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 literal 0 HcmV?d00001 diff --git a/docs/math/quaternion.assets/image-20231120102716151.png b/docs/math/quaternion.assets/image-20231120102716151.png new file mode 100644 index 0000000000000000000000000000000000000000..fedd7f3c9ac69c55b4910323561cce4e94cb4642 GIT binary patch literal 7935 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 Ref & Credits: https://github.com/Krasjet/quaternion -### Basics about complex number + +### Basics about complex number $\mathbb C$ $$ i^2 = -1 \\ z = a + bi = \begin{bmatrix}a &-b \\ b & a\end{bmatrix} \\ +z_1z_2=z_2z_1 \\ + ||z|| = \sqrt{a^2 + b^2} = \sqrt{z \bar z} $$ @@ -16,24 +20,31 @@ $$ ### 2D Rotation -Multiply with a complex number equals **scaling and rotating**. +2D rotation (counter-clockwise by $\theta$) can be represented by: +$$ +\mathbf{v'} = \begin{bmatrix}\cos\theta &-\sin\theta \\ \sin\theta & \cos\theta\end{bmatrix} \mathbf{v} +$$ +A complex number can represents a 2D vector. + +Multiply it with a complex number equals **scaling and rotating** in the 2D plane: let $\theta = \arccos \frac{b}{\sqrt{a^2+b^2}}, r=||z||=\sqrt{a^2+b^2}$: $$ - z = \begin{bmatrix}a &-b \\ b & a\end{bmatrix} = \sqrt{a^2+b^2} \begin{bmatrix} \frac {a} {\sqrt{a^2+b^2}} & \frac {-b} {\sqrt{a^2+b^2}} \\ \frac{b}{\sqrt{a^2+b^2}} & \frac{a} {\sqrt{a^2+b^2}}\end{bmatrix} = r \begin{bmatrix}\cos \theta & - \sin \theta \\ \sin \theta & \cos \theta\end{bmatrix} \\ = r(\cos\theta + i\sin\theta) \\ -= re^{i\theta} += re^{i\theta} $$ +Therefore, we also have $v' = zv$ if the scaling factor $r=||z||=1$. + + ### 3D Rotation 3D rotation can be represented by three **Euler angles** $(\theta, \phi, \gamma)$, but it relies on the axes system and can lead to Gimbal Lock. - $$ \mathbf R_x(\theta) = @@ -60,14 +71,299 @@ $$ 0&0&0&1\\ \end{bmatrix} \\ $$ -Another representation is **axis-angle**, i.e., rotation $\theta$ degree along axis $\textbf {u} = (x, y, z)^T$. ($||\mathbf u|| = 1$ so there are still only 3 Degree of Freedom.) +Another representation is **axis-angle**: rotation $\theta$ degree along axis $\textbf {u} = (x, y, z)^T$, where $||\mathbf u|| = 1$. + +(There are still only 3 Degree of Freedom) + +![image-20231120100645841](quaternion.assets/image-20231120100645841.png) + +which leads to the **Rodrigues' Rotation Formula**: +$$ +\mathbf v' = \cos\theta\mathbf v + (1 - \cos\theta)(\mathbf u \cdot \mathbf v)\mathbf u + \sin\theta(\mathbf u\times\mathbf v) +$$ + + + +### Basics about Quaternion $\mathbb H$ + +$$ +q = a + bi + cj + dk = \begin{bmatrix}a,b,c,d\end{bmatrix}^T \quad (a, b, c, d \in \mathbb R) \\ +||q||=\sqrt{a^2 + b^2 + c^2 + d^2} +$$ + +where +$$ +i^2=j^2=k^2=ijk=-1 +$$ +by left-multiplying $i$ or right-multiplying $k$ to $ijk$, we have: +$$ +ij=k, jk=i +$$ +further left-multiplying $i$ or right-multiplying $j$ to $ij$ and similar to $jk$, we have: +$$ +kj=-i, ik=-j,ji=-k +$$ +lastly right-multiplying $i$ to $ji$, we have: +$$ +ki=j +$$ +which leads to an important difference with Complex number: +$$ +q_1q_2 \neq q_2q_1 +$$ +![image-20231120102716151](quaternion.assets/image-20231120102716151.png) + +The matrix formulation of multiplication: +$$ +q_1 = a + bi + cj + dk, q_2=e+fi+gj+hk \\ +q_1q_2=\begin{bmatrix} +a & -b & -c & -d \\ +b & a & -d & c \\ +c & d & a & -b \\ +d & -c & b & a +\end{bmatrix} +\begin{bmatrix} +e \\ f \\ g \\ h +\end{bmatrix} \\ +q_2q_1=\begin{bmatrix} +a & -b & -c & -d \\ +b & a & d & -c \\ +c & -d & a & b \\ +d & c & -b & a +\end{bmatrix} +\begin{bmatrix} +e \\ f \\ g \\ h +\end{bmatrix} +$$ +A more concise form can be represented by hybrid scalar-vector form (Grafman Product): +$$ +q_1 = [a, \mathbf v], q_2=[e, \mathbf{u}] \\ +\mathbf v = [b, c, d]^T, \mathbf{u}=[f,g,h]^T \\ +q_1q_2=[ae-\mathbf v \cdot \mathbf u,a\mathbf u+e\mathbf v+\mathbf v \times \mathbf u] +$$ + +#### Pure quaternion + +the real part equals 0. +$$ +v = [0, \mathbf v], u=[0, \mathbf u] \\ +vu=[-\mathbf v\cdot\mathbf u, \mathbf v\times\mathbf u] +$$ + +#### Inverse + +$$ +qq^{-1} = q^{-1}q = 1 +$$ + +#### Conjugate + +$$ +q=[s, \mathbf u] \rightarrow q^* = [s, -\mathbf u] \\ +(q^*)^* = q \\ +qq^*=q^*q=||q||^2=[s^2 + \mathbf u \cdot \mathbf u, 0] \\ +||q||=||q^*|| \\ +q_1^*q_2^*=(q_2q_1)^* +$$ + +And we get a method to calculate the inverse: +$$ +q^{-1} = \frac {q^*} {||q||^2} = [\frac s {s^2 + \mathbf u \cdot \mathbf u}, \frac {-\mathbf{u}} {s^2 + \mathbf u \cdot \mathbf u} ]\\ +$$ +which also indicates: +$$ +||q^{-1}|| = \frac 1 {||q||} \\ +(q^{-1})^{-1} = q +$$ + + +### Quaternion for 3D Rotation + +A pure quaternion can represent a 3D vector: $v=[0, \mathbf v]$ + +A unit quaternion can represent a 3D rotation: $||q||=1$ + +And we can rewrite the Rodrigues' Rotation Formula in a new form! + +To rotate $\mathbf{v}$ for $\theta$ degree along axis $\textbf {u} = (x, y, z)^T$, where $||\mathbf u|| = 1$, + +define +$$ +v = [0, \mathbf v], q=[\cos\frac\theta 2, \sin\frac\theta 2 \mathbf u] \\ +$$ +note that $$||q||=1$$, we have: +$$ +v'=qvq^*=qvq^{-1} +$$ + +> To understand it, we still need to decompose it: +> $$ +> v'=q(v_{||}+v_{\perp})q^* = qv_{||}q^*+qv_{\perp}q^*=qq^*v_{||}+qqv_\perp = v_{||}+qqv_\perp +> $$ +> where +> $$ +> qq = [\cos\theta, \sin\theta \mathbf u] +> $$ +> (rotate $\frac \theta 2$ twice equals rotate $\theta$) + +Inversely, given a unit quaternion $q=[a, \mathbf b]$, we can get the rotation angle and axis by: +$$ +\theta = 2 \arccos a\\ +\mathbf u = \frac {\mathbf {b}} {\sin\theta} +$$ + +#### Matrix form + +Very complicated form... + +![image-20231120114151607](quaternion.assets/image-20231120114151607.png) + +#### Composition of rotation -The Rodrigues' Rotation Formula: +Just do it sequentially, $$ -\mathbf v' = \cos\theta\mathbf v + (1 - \cos\theta)(\mathbf u \mathbf v)\mathbf u + \sin\theta(\mathbf u\times\mathbf v) +v' = q_2(q_1vq_1^*)q_2^* = (q_2q_1)v(q_2q_1)^* $$ +First apply $q_1$ then apply $q_2$ leads to equal rotation of $q_2q_1$. +Note that the order matters! $q_1q_2 \ne q_2q_1$. + + + +#### Double cover + +One 3D rotation can be represented with TWO quaternions: $q$ and $-q$. $$ +(-q)v(-q)^*=qvq^* \\ +-q = [-\cos\frac\theta 2, -\sin\frac\theta 2 \mathbf u] = [\cos(\pi - \frac\theta 2), \sin(\pi-\frac\theta 2) (-\mathbf u)] +$$ + + +![image-20231120113854817](quaternion.assets/image-20231120113854817.png) + +Notice that the matrix form is exactly the same for $-q$ and $q$, since all of the elements are multiplication of two coefficients! + + +#### Euler power form + +$$ +e^{\mathbf u \theta}=\cos \theta + \mathbf u\sin\theta \\ +v' = e^{\mathbf u \frac\theta 2} v e^{-\mathbf u \frac \theta 2} $$ + + +### Implementation + +```python +import torch + +def norm(q): + # q: (batch_size, 4) + + return torch.sqrt(torch.sum(q**2, dim=1, keepdim=True)) + +def normalize(q): + # q: (batch_size, 4) + + return q / (norm(q) + 1e-20) + +def conjugate(q): + # q: (batch_size, 4) + + return torch.cat([q[:, 0:1], -q[:, 1:4]], dim=1) + +def inverse(q): + # q: (batch_size, 4) + + return conjugate(q) / (torch.sum(q**2, dim=1, keepdim=True) + 1e-20) + + +def from_vectors(a, b): + # get the quaternion from two 3D vectors, such that b = qa. + # a: (batch_size, 3) + # b: (batch_size, 3) + # note: a and b don't need to be unit vectors. + + q = torch.empty(a.shape[0], 4, device=a.device) + q[:, 0] = torch.sqrt(torch.sum(a**2, dim=1)) * torch.sqrt(torch.sum(b**2, dim=1)) + torch.sum(a * b, dim=1) + q[:, 1:] = torch.cross(a, b) + q = normalize(q) + + return q + +def from_axis_angle(axis, angle): + # get the quaternion from axis-angle representation + # axis: (batch_size, 3) + # angle: (batch_size, 1), in radians + + q = torch.empty(axis.shape[0], 4, device=axis.device) + q[:, 0] = torch.cos(angle / 2) + q[:, 1:] = normalize(axis) * torch.sin(angle / 2) + + return q + +def as_axis_angle(q): + # get the axis-angle representation from quaternion + # q: (batch_size, 4) + + q = normalize(q) + angle = 2 * torch.acos(q[:, 0:1]) + axis = q[:, 1:] / torch.sin(angle / 2) + + return axis, angle + +def from_matrix(R): + # get the quaternion from rotation matrix + # R: (batch_size, 3, 3) + + q = torch.empty(R.shape[0], 4, device=R.device) + q[:, 0] = 0.5 * torch.sqrt(1 + R[:, 0, 0] + R[:, 1, 1] + R[:, 2, 2]) + q[:, 1] = (R[:, 2, 1] - R[:, 1, 2]) / (4 * q[:, 0]) + q[:, 2] = (R[:, 0, 2] - R[:, 2, 0]) / (4 * q[:, 0]) + q[:, 3] = (R[:, 1, 0] - R[:, 0, 1]) / (4 * q[:, 0]) + + return q + +def as_matrix(q): + # get the rotation matrix from quaternion + # q: (batch_size, 4) + + R = torch.empty(q.shape[0], 3, 3, device=q.device) + R[:, 0, 0] = 1 - 2 * (q[:, 2]**2 + q[:, 3]**2) + R[:, 0, 1] = 2 * (q[:, 1] * q[:, 2] - q[:, 0] * q[:, 3]) + R[:, 0, 2] = 2 * (q[:, 1] * q[:, 3] + q[:, 0] * q[:, 2]) + R[:, 1, 0] = 2 * (q[:, 1] * q[:, 2] + q[:, 0] * q[:, 3]) + R[:, 1, 1] = 1 - 2 * (q[:, 1]**2 + q[:, 3]**2) + R[:, 1, 2] = 2 * (q[:, 2] * q[:, 3] - q[:, 0] * q[:, 1]) + R[:, 2, 0] = 2 * (q[:, 1] * q[:, 3] - q[:, 0] * q[:, 2]) + R[:, 2, 1] = 2 * (q[:, 2] * q[:, 3] + q[:, 0] * q[:, 1]) + R[:, 2, 2] = 1 - 2 * (q[:, 1]**2 + q[:, 2]**2) + + return R + +def mul(q1, q2): + # q1: (batch_size, 4) + # q2: (batch_size, 4) + # return: q1 * q2: (batch_size, 4) + + q = torch.empty_like(q1) + q[:, 0] = q1[:, 0] * q2[:, 0] - q1[:, 1] * q2[:, 1] - q1[:, 2] * q2[:, 2] - q1[:, 3] * q2[:, 3] + q[:, 1] = q1[:, 0] * q2[:, 1] + q1[:, 1] * q2[:, 0] + q1[:, 2] * q2[:, 3] - q1[:, 3] * q2[:, 2] + q[:, 2] = q1[:, 0] * q2[:, 2] - q1[:, 1] * q2[:, 3] + q1[:, 2] * q2[:, 0] + q1[:, 3] * q2[:, 1] + q[:, 3] = q1[:, 0] * q2[:, 3] + q1[:, 1] * q2[:, 2] - q1[:, 2] * q2[:, 1] + q1[:, 3] * q2[:, 0] + + return q + +def apply(q, a): + # q: (batch_size, 4) + # a: (batch_size, 3) + # return: q * a * q^{-1}: (batch_size, 3) + + q = normalize(q) + q_inv = conjugate(q) + + return mul(mul(q, torch.cat([torch.zeros(q.shape[0], 1, device=q.device), a], dim=1)), q_inv)[:, 1:] +``` + diff --git a/docs/writings/rebuttals.md b/docs/writings/rebuttals.md index 957fee8ec..d063d0907 100644 --- a/docs/writings/rebuttals.md +++ b/docs/writings/rebuttals.md @@ -1,100 +1,37 @@ -Thanks for the reviewers’ constructive comments. As recognized by the reviewers, we address the problem of graph learning from incomplete graph data based on similarity preservation in the feature space. The effectiveness of our method is validated on various datasets, with low latency and memory consumption. +### Openreview markdown -=== -[Common Question] of : More discussion and interpretation to the results and why our method performs better. -We discuss the experimental results from the following three aspects. -1) Compared with GCN and GMNN with fixed graphs as input, we outperform by 3.5% and 0.9% on average respectively on three datasets. This is because fixed graphs capture limited similarities between each pair of nodes, while we learn latent correlations among nodes with new connectivities and edge weights, showing the superiority of graph learning. -2) Compared with GLCN and GAT that learn only edge weights based on existing connectivities in graphs, we outperform by 3.1% and 2.3% on average. This is because we learn new connectivities that fully capture latent correlations between nodes. -3) Compared with AGCN that learns both edge weights and connectivities but is task driven with no data prior, we outperform by 2.0% on average. This is because the proposed cross-space Graph Laplacian Regularizer enforces smoothness of the input data with respect to the graph over the feature space and achieves similarity-preserving mapping on graphs, thus leading to better and more robust results. -=== -Response to : -[Q1] Analysis on why the new objective discloses similarity +Thank you for your valuable time and insightful comments! We have tried to address your concerns in the updated manuscript and our rebuttal text: -We provide analysis in the spatial domain and spectral domain respectively below. -1) In the spatial domain, by minimizing the cross-space GLR as objective in Eq. 4, when two nodes are dissimilar in the input space, the learned edge weight tends to be small, enforcing the distance in the new feature space to be large. Therefore, GLR preserves the similarity between the new feature space and the input space. -2) From a graph spectral view, the GLR term can be rewritten as -x' L x = x' (U Λ U') x = (U' x)' Λ (U' x) = a' Λ a = Σ λ_i {a_i}^2, -where L is the Laplacian matrix, U and Λ denote eigenvectors and eigenvalues of L, a is the transform coefficient vector and \lambda_i is the i-th eigenvalue. Minimizing this term essentially penalizes high-frequency components (a_i w.r.t. large \lambda_i). Pairs of dissimilar nodes have larger variations, corresponding to high-frequency components, so minimizing GLR tends to learn smaller edge weights to penalize high-frequency components. +**Q1: questions** -[Q2] How the similarity structure of graph changed after applying RGLN? +replies. -Fig. 5 of our submission shows the change in similarity structure of a graph: -1) If the provided graph is incomplete or unavailable as in Fig. 5(a), our proposed method learns more latent connectivities, as shown in Fig. 5 (b). -2) After applying RGLN, similar nodes keep similar while dissimilar nodes are pushed away. As in Fig. 5, the connectivities of three similar node pairs in Fig. 5(a) are still preserved in (b) (dark orange blocks), while many dissimilar node pairs are also captured in (b) (light yellow blocks). +[1] references -=== -Response to : -[Q1] The datasets used are small in the paper, why not use DBLP dataset? +We hope our responses satisfactorily address your queries. Please let us know to address any further concerns impacting your review. -1) The size of our used Pubmed dataset (V=18230, E=79612, D=500, K=3) is comparable to DBLP dataset (V=17716, E=105734, D=1639, K=4). Besides, with our dense adjacency matrix and low-rank assumption in distance metric learning, the number of edges (E) and dimension of features (D) will have little influence on the performance. So we consider our experiments sufficient to support our idea. -2) We choose the most commonly used datasets mainly for fair comparison with other graph learning methods, since these methods haven’t used DBLP dataset. -[Q2] It is better to use dynamic graph in different timestamp instead of dropping out edges for missing ratio. -The experiment on missing edges aims to evaluate the robustness of the proposed method when the provided graph is incomplete (with missing edges), since robustness to missing edges is important in practice. We will consider extending our method to dynamic graph sequence learning. -=== -Response to : -[Q] May also cite and discuss some graph matching papers -We will cite and discuss the suggested relevant papers. These papers study the problem of similarity learning for graphs including cross-graph affinity learning as well as cross-graph embedding for topology recovery, which are related to our work in terms of learning similarities in graphs. On the other hand, while these papers focus on learning cross-graph similarity for matching, we focus on similarity learning inside a single graph to capture the data correlation. Also, while both our method and the suggested paper [3] predict missing edges to recover graph topology, we focus on prediction from one single graph. +### CMT pdf -------------- +```latex +% helper script +\usepackage[dvipsnames]{xcolor} +\newcommand{\rtext}[1]{\noindent \textcolor{brown}{\textbf{\underline{#1}}}} +\newcounter{qcounter} +\setcounter{qcounter}{1} +\newcommand{\qtext}[1]{\noindent \textcolor{blue}{\textbf{Q\theqcounter\stepcounter{qcounter}: #1}}} +% in document +We thank all the reviewers for their efforts in reviewing this manuscript and their constructive comments. +\rtext{Response to Reviewer \#1} -Thanks for your valuable comments and suggestions. -Common questions: -\1. Novelty (Reviewer 1 & 2) -Though related, our model is not an integration of GLCN and AGCN. -1) We are the first to pose a joint learning problem of the underlying graphs and node features at EACH layer in GCNNs, which aims to optimize the entire network model. -2) GLCN assumes the edge connectivity in the graph is known and only learns a non-negative function as edge weights, while our method learns both edge connectivity and edge weights, which is more encompassing. -3) Different from the task-driven AGCN where the Mahalanobis distance metric M is learned by minimizing the cross-entropy only, our model is both task-driven and data-adaptive by optimizing M via both the GLR and cross-entropy. Also, instead of assuming a general M in AGCN, we assume M is low rank to reduce number of parameters. +\qtext{questions} +replies +``` -\2. Purpose of GLR loss (Reviewer 1 & 3) -The motivation and analysis of using GLR loss is discussed in the second subsection of “Background in Spectral Graph Theory”. Specifically, minimizing GLR forces the graph to capture the similarity of the graph signal, thus optimizing the underlying graph. -We can further provide theoretical analysis from the frequency domain. That is, the GLR term x^T L x can also be written as the sum of the transform coefficients of x weighted by the eigenvalues of L. Since a larger eigenvalue corresponds to a higher-frequency transform coefficient, minimizing GLR essentially penalizes high-frequency components, thus leading to a low-pass and smooth graph signal with respect to the graph. - -Reviewer 1 -\1. Graph signal and features -Graph signals are data defined on vertices of a graph. In point clouds, if we treat each point as a node in a graph, the 3D coordinate of each point is the graph signal. In citation networks, the input features of each node are the graph signals. In general, graph signals are set as the input data/features on nodes in the experiments. In contrast, features in our context refer to latent features extracted from graph convolution. - -\2. Point cloud classification and graph classification -Point cloud classification problem can be viewed as graph classification problem as we build a graph for each point cloud and classify point clouds based on graphs. We will make it clearer. - -\3. Standard deviation -Since not all methods we compare in the paper provide standard deviation, we didn't present it in the table. For our experiments, the standard deviations for Citeseer, Cora and Pubmed are 0.0046, 0.0035, 0.0038 respectively. - -\4. Complexity -Sparse implementations of GCN have time complexity of O(|E|FC) where |E| is the number of edges, F is the input feature dimension and C is the output feature dimension. Dense implementations of graph convolution operations including our method all have time complexity of O(N^2 FC), where N is the number of nodes. This work is a first attempt to jointly optimize the underlying graph and node features at each layer, with the reduction of computation complexity considered as future work. - -Reviewer 2 -\1. Difference with previous similarity learning approaches -Graph matching problems learn the similarity of nodes between different graphs while we learn the similarity of different nodes inside one graph, like the self-attention operation. - -\2. Subsampling -For the Pubmed dataset, we simply choose the first 10000 nodes to evaluate all methods. The overall accuracy actually decreases compared to that of performing on the entire dataset, since fewer number of nodes are used for training, resulting in training data with less information. - -\3. Clarification -We will clarify the aspects the reviewer suggested. To make it clear, this paper is related to the family of graph-based methods, because we focus on the joint learning of graphs and node features without assumptions on the input data. Besides, the recovery of graph structure from pairwise affinity is defined in Eq. 8. - -\4. Graph learning -Thanks for the valuable comments. We choose a fully connected graph topology mainly for simplicity and effectiveness. In future, we will consider discretization / projection step to yield new connectivity. Though the idea of building a different graph across different layers was previously proposed in DynGraphCNN, they are not learning / optimizing a different graph across layers but perform empirical k-NN construction of graphs. - -Reviewer 3 -\1. Presentation -We will rephrase and properly discuss DGCNN and FeaStNet in the intro. To make it clear, DGCNN builds graphs based on the empirical k-NN method across different layers, while we explicitly learn / optimize the graph based on vertex features. FeaStNet applies metric learning only on local neighbors while we learn a global fully-connected graph. We will also rephrase the term “Joint”. - -\2. Solve R -R is updated via back propagation and is solved within the network. We will compare the final energy between the network's solution and the global one. - -\3. Eq. 11 -Eq. 11 is improvement of GCN where $\tilde A=\Lambda^{-\frac 1 2}(A+I)\Lambda^{-\frac 1 2}$. Specifically, we replace the identity matrix $I$ (meaning adding self-loop) with a learned graph $A^*$ of the current layer for optimized graph representation. In our method, $\Lambda_{ii}=\sum_j(A_{ij}+A^*_{ij})$, i.e., the degree matrix computed from (A+A^*). Note that we omit subscripts here for simple notations. - -\4. cross entropy loss -Actually, as shown in Fig. 2, we only employ the cross entropy loss to the last layer, and use graphs learned from all the layers to compute the GLR loss. We will make it clearer. - -\5. Low-rank approximation of the mahalnobis matrix M -In the first layer, K is the dimension of input features (3703, 1433, 500 for Citeseer, Cora, Pubmed respectively), and is thus much larger than S=16. In the second layer, we choose S=K=16 without further reducing the feature dimension. \ No newline at end of file