Setup
GNN에 대한 설명을 시작하기에 앞서서,
graph G에 대해서
- V는 vertex의 set
- A는 adjacency matrix
- X∈Rm×|V|는 node feature의 matrix
- v는 V에 속한 node
- N(v)는 v의 neighbor의 집합
위와 같이 정의를 해두고 시작해보자.
A Naive Approach
먼저 가장 간단하고 naive한 방식을 한번 생각해보자. 그냥 Graph의 Adjacency matrix에 Feature을 append해서 그걸 GNN의 input으로 사용하면 어떨까?
이 방식에는 여러가지 문제가 존재한다. 먼저 파라미터의 수가 node의 개수만큼 들어가게 되어 모델이 굉장히 무거워진다. 또한 training example이 1개밖에 없어 모델이 제대로 학습될 수 없고, graph의 크기가 달라지면 모델이 동작할 수 없게된다. 또한 원래 Graph에는 Node의 순서가 존재하지 않지만 Adjacency matrix는 순서에 의존적이기 때문에 모델이 Node의 순서에 sensitive하게 된다.
Idea : Convolutional Networks
Naive한 방법에서 위와같은 문제들이 발생하여 CNN 방식을 Graph에 generalize 해서 사용하고자 한다.
이미지에서 CNN을 사용할 땐 정해진 크기의 window를 이미지 전체에 특정 간격으로 slide하며 진행한다.
하지만 Graph는 이미지와 달리 격자형태가 아닌 복잡한 형태를 지니고 있어 window를 정의하고 sliding이라는 것을 정의하기 힘들다. 따라서 각 Node의 주변 이웃들로부터 메시지를 수집해서 하나의 새로운 메시지를 만드는 것이 아이디어이다.
이를 위해 첫 step에서 Node Computation Graph를 정하고, 두번째 step에서 information을 transform/propagate한다. 이때의 Computation Graph가 Graph의 underlying하는 구조를 의미한다.
Idea : Aggregate Neighbors
최종적으로 만들어진 형태가 위와 같이 이웃 간의 로컬한 네트워크 정보를 이용하여 Node Embedding을 만드는 방식이다. 이를 여러 layer로 만들면, 전체 네트워크에 대한 정보를 담을 수 있게 된다.
위와같은 Computation Graph를 모든 Node들이 갖는다. 이때 각 Node는 이웃들로부터 받는 정보들을 aggregate/transform 해서 본인의 정보로 만들게 된다.
가장 우측의 Layer인 0번째 Layer의 input으로는 해당 Node의 feature vector(ex. xA)가 들어간다. 그 다음 Layer부터는 이전 Layer에서 전달받은 정보와 자신의 feature vector의 정보를 합쳐서 다음 Layer로 전달한다. 따라서 모델의 깊이에 따라 예를들어 Layer-k embedding은 Target Node로부터 k hop 떨어진 Node들로부터 정보를 받는 것이다.
이때, 각 Node가 이웃들로 받은 정보를 aggregate/transform하는 과정에서 사용하는 함수는 순서에 무관해야하고, 함수의 파라미터가 학습이 되어야한다. 그러한 함수는 일단은 위 그림에서 네모 형태의 Black Box로 나타나 있다.
Neighborhood Aggregation
가장 기본적인 방식은 이웃의 정보를 평균내는 것이다. 이때 사용되는 공식은 아래와 같다.
수식이 복잡해보이지만 내용은 단순하다.
윗 줄의 초록색 부분은 최초의 0번째 Layer의 Embedding이 Node feature와 같다는 것을 의미한다.
그 이후의 Layer를 계산할 때는 그 이전 Layer의 Embedding에 Matrix Bl을 곱하고, N(v)에 속하는 v의 이웃 u에 대한 Layer l의 Embedding의 평균을 구하여 matrix Wl을 곱한다.
그리고 그 둘을 더한 후, ReLU와 같은 non-linear 활성화 함수에 곱한다. 이를 l회만큼 여러 회차 iteration을 진행하면, 최종 Layer L에서의 Embedding(h(L)v)은 결론적으로 zv와 같게 된다.
이것이 Deep Encoder이다.
그렇다면 이러한 모델을 어떻게 학습시켜야 할까?
위에서 본 수식에서 우리는 weight Matrix Wl과 Bl을 학습시킬 수 있다. 이러한 Embedding을 loss function에 feeding하여 SGD를 통해 weight parameter를 학습시키는 것이다.
이를 위해 먼저 앞에서 본 수식을 행렬식으로 변경해보자.
Model Parameters
먼저 위와같이 모든 Node의 h(l)값을 concat한 후, transpose하여 행렬 Hl로 만든다.
그리고 D를 diagonal matrix(대각선으로만 값이 있고 나머지는 0으로 채워진 행렬)로 정하고, 값은 Dv,v=Deg(v)=|N(v)|로 정하여 대각선마다 해당 행의 Node의 이웃 수가 되도록 한다. 그러면 D−1v,v=1/|N(v)|이 되므로 아래와 같이 공식을 치환할 수 있다.
그리고 최종적으로는 아래와 같이 변형할 수 있다.
이러한 과정이 모든 GNN에서 가능한 것은 아니다. aggregation function이 복잡한 경우에는 행렬로 표현이 불가능 할 수 있다.
How to train a GNN
GNN을 학습시키는 과정은 이전 강의들에서 다룬 기본 NN 학습 과정과 유사하다.
Graph 내에서 유사한 Node들은 유사한 Embedding을 가질 것이므로, Graph 내에서의 유사도(yu,v)와 임베딩 공간에서의 유사도(zu,zv)의 오차가 최대한 적도록 해야한다. 이때, Graph 내의 유사도는 random walk 등으로 측정할 수 있다.
이를 수식으로 나타내면 아래와 같고, yu,v가 1에 가까울수록 u와 v가 유사하다. 그리고 CE는 cross entropy, DEC는 decoder를 의미한다.
Cross entropy loss를 계산할 때는 아래와 같은 수식을 이용한다. 아래는 node classification task를 위한 수식이다.
σ(zTvθ)가 0에 가까우면 수식의 뒷부분이 남고, 1에 가까우면 수식의 앞부분이 남게된다. 예를들어 class label yv가 0인 경우가 toxic, 1인 경우가 non-toxic이었다면, σ(zTvθ)가 0에 가까운 경우 non-toxic, 1에 가까운 경우 toxic으로 classification 된다.
Model Design : Overview
Inductive Capability
모든 Node들에 대해 parameter W와 B는 공유되어 사용된다. 또한 W와 B는 임베딩 차원과 크기에만 좌우되고, 그래프의 크기와 무관하게 사용할 수 있기 때문에, 한 그래프에서 학습시킨 모델을 다른 그래프에 적용시킬 수 있고, 시간에 따라 변화하는 그래프에서도 사용할 수 있다.
Summary
출처, 더 궁금하다면?
Stanford CS224W: Machine Learning with Graphs | 2021 | Lecture 6.3 - Deep Learning for Graphs