# NARS 第一版-開發文件
###### tags: `國泰專案`

## NARS 概述
1. **產生 K-hop 特徵**
$$
\begin{align}
&H_{v, 0} = input \ feature \ for \ node \ v, \\
&H_{v, l}^{i} = \sum_{u \in N_i(v)} \frac{1}{|N_i(v)|} H_{u, l-1}^{i}.
\end{align}
$$
2. **Weighted Aggregator**
$$
H_{v, l}^{i} = \sum_{i=1}^{K} a_{i, l} \cdot H_{v, l}^{i}
$$ 其中 $K$ 為 **relation subset** 的個數。
3. **SIGN**

## Memory Footprint Optimization
1. **介紹**: 這種方法在每個 step 會抽出一部分的 relation subset,計算該部分特徵對應的 L-hop 特徵,對這些 relation subset 對應的參數進行最佳化,如此一來,可減少 RAM 的開銷,因為記憶體不需要一次儲存所有 relation subset 對應的特徵。
2. **Partial Aggregator 公式**
$$
H_{v, l}^{(t)} = \sum_{G_i \in S^{(t)} \subseteq S} b_{i, l} \cdot H_{v,l}^{i} + \alpha_l H_{v, l}^{(t-1)}
$$ 其中,$S^{(t)}$ 為隨機抽樣 realtion subsets 所形成的集合在 stage $t$。
3. **訓練流程**

## 流程
1. **Weight Aggregator Mode**
```mermaid
graph TD
A["產生 relation subsets"] --> B["產生 K-hop feature (CPU)"] --> C["sample nodes (dataloader)"] --> D["weight aggrgate (GPU)"] --> |forward| E["SIGN (GPU)"] --> |forward| F[loss]
F --> |backward| E
E --> |backward| D
F --> C
```
2. **Partial Weight Aggregator Mode**
```mermaid
graph TD
A["產生 relation subsets"] --> B["抽樣 sampled relation subsets"] --> C["產生 K-hop feature (CPU)"] --> D["sample nodes (dataloader)"] --> E["partial weight aggregate (GPU)"] --> |forward| F["SIGN (GPU)"] --> |forward| G[loss] --> |if epoch % resample_every == 0| B
G --> |backward| F
F --> |backward| E
G --> D
```
3. **Inference**
```mermaid
graph TD
A["sample k hop subgraph"] --> B["產生 K-hop feature"] --> |no grad| C["(partial) weight aggregate"] --> |no grad| D["SIGN"]
```
## 程式設計
1. **資料**
+ **輸出資料**: `g, labels, n_classes, train_nid, val_nid, test_nid`
+ `g`: 異質圖。
+ `label`: **target nodes** 的標籤。
+ `n_classes`: 類別數量。
+ `train_nid, val_nid, test_nid`: **target nodes** 編號。
2. **模型**
+ **relation subsets**
+ `gen_rel_subsets`
+ `read_rel_subsets`
+ **NARS**
+ `NARS_TRAINER` 實例化
+ `NARS_TRAINER.build_model`: 建立 **NARS** 模型。
+ `NARS_TRAINER.compile`: 設置訓練所需的組態,如損失函數,優化器等。
+ `NARS_TRAINER.fit`: 訓練 **NARS** 模型,傳入資料與標籤。
3. **範例**
```python=
import nars_trainer
from nars_utils import read_relation_subsets
...
...
trainer = nars_trainer.NARS_TRAINER()
trainer.build_model(partial, sample_size, num_feats, in_feats, num_hops, num_hidden, num_classes, ff_layer)
trainer.compile(loss_fcn, optimizer, lr, weight_decay, device)
trainer.fit(g, labels, target_node_type, rel_subsets, train_nid, val_nid, test_nid, num_epochs, batch_size)
```
## 總結
1. 計算 K-hop 特徵在 **CPU** 上進行,訓練在 **GPU** 上進行。
2. 模型對 **CPU RAM** 要求較高,對 **GPU RAM** 要求較小,且可由 **batch size** 進行控制。
3. 如果不同 **node type** 有不同的特徵維度,模型會將不同 **node type** 的特徵隨機投影到同一個維度。
+ 隨機投影可能不穩定,**KGE** pretrain 使所有特徵都在同一維度。
6. **Partial Weight Aggregator** 訓練可以避免 overfitting?
## 後續改進
1. 改進計算 K-hop 特徵方法:
+ 使用 dataloader 一次計算一部份的 k-hop 特徵 ([`dgl.khop_out_subgraph`](https://docs.dgl.ai/generated/dgl.khop_out_subgraph.html))
2. 新增支援不同 **metric** 功能 & **progress bar**
3. **Inference** 功能
## 參考資料
1. https://arxiv.org/abs/2011.09679
2. https://colab.research.google.com/drive/1BJ6kbtuBq7EkE4YjmywO2WOTLsfS9_jc?usp=sharing
3. https://hackmd.io/xAbSdg61TTeIenows6AT8w