{"notes":[{"id":"graph-learning/graphsage","category":"graph-learning","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"GraphSAGE","subtitle":"サンプリングで点呼","author":"Z. Yuan","paperDate":"2017-06-07","publishedOn":"2023-10-21","world":"external/graphsage","paperTitle":"Inductive Representation Learning on Large Graphs","paperUrl":"https://arxiv.org/abs/1706.02216","bibliography":{"title":"Inductive Representation Learning on Large Graphs","authors":["William L. Hamilton","Rex Ying","Jure Leskovec"],"url":"https://arxiv.org/abs/1706.02216","pdfUrl":"https://arxiv.org/pdf/1706.02216v4","codeUrl":"https://github.com/williamleif/GraphSAGE","preprint":{"id":"1706.02216","submittedOn":"2017-06-07","url":"https://arxiv.org/abs/1706.02216"},"publication":{"venue":"NeurIPS","year":2017,"kind":"conference","url":"https://papers.nips.cc/paper_files/paper/2017/hash/5dd9db5e033da9c6fb5ba83c7a7ebea9-Abstract.html"},"citation":"@misc{graphlearninggraphsage2017,\n  title = {{Inductive Representation Learning on Large Graphs}},\n  author = {William L. Hamilton and Rex Ying and Jure Leskovec},\n  year = {2017},\n  eprint = {1706.02216},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1706.02216}\n}\n","citationPath":"/content/papers/citations/graph-learning/graphsage.1a0b3fd6e8b8.bib"},"thumbnail":{"src":"/content/papers/assets/88f6d9397f20155603c7ee0daef374fb944aac5fb73ed6573a573560b5b9c6aa.png","width":1090,"height":384},"locale":"ja","path":"/content/papers/ja/graph-learning/graphsage.66cf75c22e3b.md","headings":[{"id":"問題設定","text":"問題設定","depth":2},{"id":"transductive-と-inductive","text":"transductive と inductive","depth":3},{"id":"隣が多すぎる","text":"隣が多すぎる","depth":3},{"id":"解決方法","text":"解決方法","depth":2},{"id":"アルゴリズム","text":"アルゴリズム","depth":3},{"id":"隣接ノードを抽出する","text":"隣接ノードを抽出する","depth":3},{"id":"三つの集約器","text":"三つの集約器","depth":3},{"id":"ラベルなしでも学べる","text":"ラベルなしでも学べる","depth":3},{"id":"wl-テストとの関係","text":"WL テストとの関係","depth":3},{"id":"議論","text":"議論","depth":2},{"id":"三つのデータセット","text":"三つのデータセット","depth":3},{"id":"主な結果","text":"主な結果","depth":3},{"id":"速度とサンプリングのトレードオフ","text":"速度とサンプリングのトレードオフ","depth":3},{"id":"その後","text":"その後","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"graph-learning/gat","relation":"citing","topic":""}]},{"id":"graph-learning/gat","category":"graph-learning","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"GAT","subtitle":"隣の重みにも差がある","author":"Z. Yuan","paperDate":"2017-10-30","publishedOn":"2023-11-10","world":"external/gat","paperTitle":"Graph Attention Networks","paperUrl":"https://arxiv.org/abs/1710.10903","bibliography":{"title":"Graph Attention Networks","authors":["Petar Veličković","Guillem Cucurull","Arantxa Casanova","Adriana Romero","Pietro Liò","Yoshua Bengio"],"url":"https://arxiv.org/abs/1710.10903","pdfUrl":"https://arxiv.org/pdf/1710.10903v3","codeUrl":"https://github.com/PetarV-/GAT","preprint":{"id":"1710.10903","submittedOn":"2017-10-30","url":"https://arxiv.org/abs/1710.10903"},"publication":{"venue":"ICLR","year":2018,"kind":"conference","url":"https://arxiv.org/abs/1710.10903"},"citation":"@misc{graphlearninggat2017,\n  title = {{Graph Attention Networks}},\n  author = {Petar Veličković and Guillem Cucurull and Arantxa Casanova and Adriana Romero and Pietro Liò and Yoshua Bengio},\n  year = {2017},\n  eprint = {1710.10903},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1710.10903}\n}\n","citationPath":"/content/papers/citations/graph-learning/gat.402fa57986a5.bib"},"thumbnail":{"src":"/content/papers/assets/1a68144470e25ef01f2cd6ccf405483bc7960ca1cc9f7ebf5991060fb3a92010.png","width":1124,"height":540},"locale":"ja","path":"/content/papers/ja/graph-learning/gat.605c9e3ac92e.md","headings":[{"id":"問題設定","text":"問題設定","depth":2},{"id":"解決方法","text":"解決方法","depth":2},{"id":"注意ヘッド一つ","text":"注意ヘッド一つ","depth":3},{"id":"マルチヘッド","text":"マルチヘッド","depth":3},{"id":"コストと性質","text":"コストと性質","depth":3},{"id":"議論","text":"議論","depth":2},{"id":"実験設定","text":"実験設定","depth":3},{"id":"主な結果","text":"主な結果","depth":3},{"id":"何を学んだか","text":"何を学んだか","depth":3},{"id":"著者が挙げる制約","text":"著者が挙げる制約","depth":3},{"id":"静的な注意","text":"静的な注意","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"graph-learning/gcn","relation":"referenced","topic":""},{"id":"graph-learning/graphsage","relation":"referenced","topic":""}]}],"text":"Reddit には毎分新しい投稿、YouTube には毎日新しい動画が増えます。推薦システムは新ノードの表現を、全グラフの再訓練なしに、その場で計算できると好都合です。\n\n2017 年以前の主流の埋め込みではできませんでした。DeepWalk や node2vec はノードごとにベクトルを学ぶ対応表のようなもので、新ノードは表にありません。GCN は特徴量を入力しますが、論文は全グラフ同時訓練で、毎ステップ隣接行列全体をメモリに置きます。\n\nStanford の William Hamilton、Rex Ying、Jure Leskovec は、学ぶ対象を替えました。ノードのベクトルではなく、「隣からベクトルを計算する方法」という関数を学びます。学習後は、特徴量と隣接ノードさえあれば新ノードにも適用できます。\n\n## 問題設定\n\n### transductive と inductive\n\n論文は問題を二種類に分けます。\n\n**transductive**（トランスダクティブ）は、訓練時に全グラフが見えており、一部ノードだけラベルがない設定です。GCN 論文の半教師あり分類が該当します。**inductive**（帰納的）は、訓練後に未知のノードや、まったく新しいグラフが現れる設定です。\n\n著者は inductive のほうが難しいと考えます。位置の丸暗記に頼れず、局所構造と特徴量から役割を見分ける必要があります。訓練時に見ない新ノードを、既存ノードと整合する空間に置かなければなりません。\n\n既存の埋め込みの大半は transductive で、新ノードに対応させるにはテスト時にも最適化を何回か行うため、遅くなります。\n\n### 隣が多すぎる\n\nもう一つは規模です。Reddit は 232,965 投稿で、同じユーザーがコメントした投稿同士を結び、平均で一件あたり 492 エッジがあります。\n\n二ステップ以内の全隣接ノードを見ると、一ノードの計算が数十万ノードに及び、バッチの時間やメモリが予測できません。\n\n## 解決方法\n\n### アルゴリズム\n\nGraphSAGE は SAmple and aggreGatE、サンプリングと集約から来ています。順伝播は $K$ ラウンドで、各ノード $v$ で三つの処理をします。\n\n$$\nh^k_{\\mathcal N(v)}=\\mathrm{AGGREGATE}_k\\left(\\left\\{h^{k-1}_u,\\ \\forall u\\in\\mathcal N(v)\\right\\}\\right)\n$$\n\n$$\nh^k_v=\\sigma\\left(W^k\\cdot\\mathrm{CONCAT}\\left(h^{k-1}_v,\\ h^k_{\\mathcal N(v)}\\right)\\right)\n$$\n\n$$\nh^k_v\\leftarrow h^k_v/\\left\\|h^k_v\\right\\|_2\n$$\n\n隣の表現を一つのベクトルに集約し、自分の前ラウンドの表現と**連結**し、重み行列と非線形性を適用、最後に L2 正規化します。$h^0_v$ は入力特徴量、第 $K$ ラウンドの出力が埋め込みです。\n\nGCN との最大の違いは連結です。GCN は自分も隣の一つとして加重平均し、全員が一つの $W$ を使います。GraphSAGE は自分と隣を分け、別々の重みを使う形です。著者は深さをまたぐ一種の skip connection と見ており、実験で明確に改善します。\n\n[![原論文 Figure 1：左から三段階。目標ノードの周囲で一ステップと二ステップ先を抽出し、特徴量を集約器で目標へ戻し、集約した表現でグラフの文脈とラベルを予測する。](/content/papers/assets/88f6d9397f20155603c7ee0daef374fb944aac5fb73ed6573a573560b5b9c6aa.png)](/content/papers/assets/88f6d9397f20155603c7ee0daef374fb944aac5fb73ed6573a573560b5b9c6aa.png)\n\n*原論文 Figure 1（Hamilton ら）、[**PDF 2 ページ**](https://arxiv.org/pdf/1706.02216v4#page=2)より。原キャプションは省略。*\n\n### 隣接ノードを抽出する\n\n$\\mathcal N(v)$ は全隣接集合ではなく、**固定個数を一様抽出**したものです。ラウンドごとに引き直します。第 $i$ ラウンドに $S_i$ 個なら、一バッチは $O\\left(\\prod_{i=1}^KS_i\\right)$ に固定されます。$K=2$、$S_1\\cdot S_2\\le500$ で十分よく、実験では $S_1=25$、$S_2=10$ です。\n\nReddit の平均次数で、差を計算しましょう。\n\n```python\nS1, S2 = 25, 10                 # 一層目で 25、二層目でさらに各 10 を抽出\navg_deg = 492                   # Reddit の平均次数\nprint(\"抽出後、一目標から最大:\", 1 + S1 + S1 * S2, \"ノード\")\nprint(\"抽出なし、二歩以内の上限:     \", 1 + avg_deg + avg_deg ** 2, \"ノード\")\n```\n\n```text\n抽出後、一目標から最大: 276 ノード\n抽出なし、二歩以内の上限:      242557 ノード\n```\n\n二つ目は重複する隣接ノードを差し引いていない粗い上限ですが、すでに全体の 232,965 ノードを超えます。抽出なしでは、一ノードの二層表現を得るだけで、ほぼ全グラフを読むことになります。\n\nミニバッチ訓練では、目標から外へ必要な隣を抽出し、外から内へ層ごとに計算します。再帰で実際に必要なノードだけを計算します。\n\n六ノードのグラフで、各ノード二つを抽出し、平均集約器で一層動かします。\n\n```python\nimport numpy as np\nnp.set_printoptions(precision=2, suppress=True)\nrng = np.random.default_rng(0)\n\nneighbors = [[1, 2], [0, 2, 3], [0, 1, 3, 4, 5], [1, 2], [2], [2]]\nh = rng.random((6, 3))                       # 六ノード、各 3 次元特徴量\nW = rng.normal(size=(4, 6))                  # 連結後 6 次元 → 出力 4 次元\n\ndef sage_layer(h, neighbors, W, S):\n    out = []\n    for v, nbrs in enumerate(neighbors):\n        picked = rng.choice(nbrs, size=S, replace=len(nbrs) < S)   # 隣が不足すれば重複抽出\n        h_nb = h[picked].mean(0)                                    # mean 集約\n        z = np.maximum(W @ np.concatenate([h[v], h_nb]), 0)          # 自分と隣を連結して W を掛ける\n        out.append(z / (np.linalg.norm(z) + 1e-12))                  # L2 正規化\n    return np.array(out)\n\nh1 = sage_layer(h, neighbors, W, S=2)\nprint(h1.shape)\nprint(h1)\n```\n\n```text\n(6, 4)\n[[0.96 0.12 0.   0.24]\n [0.74 0.   0.19 0.64]\n [0.99 0.   0.   0.16]\n [0.95 0.3  0.   0.  ]\n [0.71 0.   0.   0.7 ]\n [0.81 0.   0.13 0.57]]\n```\n\n2 番には隣が五つあっても二つだけを取り、4、5 番には一つしかないので繰り返し抽出します。公式 TensorFlow 実装も、各ノードに固定長の隣接表を作り、不足分は重複抽出で埋め、バッチごとに表からランダムに $S$ 個取ります。\n\n$W$ はノードに依存しないので、新ノードにも特徴量と隣があれば同じ `sage_layer` を使えます。\n\n### 三つの集約器\n\n隣接ノードに順序はありません。集約器には順列不変性と、学習可能で十分な表現力が欲しくなります。三つを試しています。\n\n- **Mean**：要素ごとの平均。自分を連結せず $\\{v\\}\\cup\\mathcal N(v)$ を平均して重みを掛ける GCN 風の版も作り、convolutional 集約器と呼びます。\n- **LSTM**：もっとも表現力がありますが、LSTM は順序を見ます。毎回隣をランダムに並べ替えて入力する折衷案です。\n- **Pooling**：各隣接ノードを全結合一層に通し、要素ごとの最大値 $\\max\\left(\\left\\{\\sigma\\left(W_{\\text{pool}}h_{u}+b\\right)\\right\\}\\right)$ を取ります。max を mean に替えても差は小さいとしています。\n\n### ラベルなしでも学べる\n\nタスクのラベルがない場合、グラフに基づく損失を使います。\n\n$$\nJ_{\\mathcal G}(z_u)=-\\log\\sigma\\left(z_u^\\top z_v\\right)-Q\\cdot\\mathbb{E}_{v_n\\sim P_n(v)}\\log\\sigma\\left(-z_u^\\top z_{v_n}\\right)\n$$\n\n$v$ は固定長ランダムウォークで $u$ の近くに現れるノード、$v_n$ は負例、$Q$ は負例数です。DeepWalk に似た目的ですが、$z_u$ は対応表ではなく隣の特徴量から計算します。ラベルがあれば交差エントロピーに置き換えるか、加えれば済みます。\n\n### WL テストとの関係\n\n$K$ をノード数、重みを単位行列、集約器をハッシュにすれば、アルゴリズム 1 は Weisfeiler-Lehman のグラフ同型テストになります。GraphSAGE は WL の連続近似と見られますが、目的は同型判定でなく、有用なノード表現の学習です。\n\n## 議論\n\n### 三つのデータセット\n\n実験はすべて inductive 設定です。\n\n- **引用ネットワーク**：Web of Science の生物関連六分野、2000〜2005 年の論文。302,424 ノード、平均次数 9.15。2000〜2004 年で訓練し、2005 年の分野を予測します。\n- **Reddit**：2014 年 9 月の大規模な 50 subreddit の投稿。最初の 20 日で訓練し、その後の投稿の subreddit を予測します。\n- **PPI**：一グラフが一種類の人体組織に対応するタンパク質相互作用グラフ。訓練 20、検証 2、テスト 2 グラフで、121 種の機能ラベルを予測します。テストグラフは訓練で一切見ません。\n\n### 主な結果\n\n| 方法 | 引用ネットワーク | Reddit | PPI |\n| --- | ---: | ---: | ---: |\n| 元の特徴量 | 0.575 | 0.585 | 0.422 |\n| DeepWalk + 特徴量 | 0.701 | 0.691 | — |\n| GraphSAGE-GCN | 0.772 | 0.930 | 0.500 |\n| GraphSAGE-mean | 0.820 | 0.950 | 0.598 |\n| GraphSAGE-LSTM | 0.832 | **0.954** | **0.612** |\n| GraphSAGE-pool | **0.839** | 0.948 | 0.600 |\n\n教師あり版の micro-F1 です。GCN 風は三つとも集約器の最下位で、PPI ではほかと約 0.1 差があります。mean との最大の違いは、自分と隣の連結がないことです。\n\n教師あり・なしを三データセットで比べる六設定の Wilcoxon 検定では、LSTM、pool、mean は GCN 風を有意に上回り、LSTM と pool の差は有意ではありません。六設定だけなので検出力には限界があるとも認めています。\n\n系列用の LSTM が無順序の隣接集合でもよく働いたのは、著者にも少し意外だったようです。\n\n### 速度とサンプリングのトレードオフ\n\n[![原論文 Figure 2：A は Reddit の訓練・テスト時間で、DeepWalk のテストが GraphSAGE より大幅に長い。B は引用ネットワークで、一層の抽出数を数個から 60 個超に増やすと micro-F1 が約 0.78 から約 0.83 へ上がり、時間も増え続ける。](/content/papers/assets/ff62a5b1aa8349edd927fc6014fd713adf4d76672507efe1a7527ff6ecdc45ca.png)](/content/papers/assets/ff62a5b1aa8349edd927fc6014fd713adf4d76672507efe1a7527ff6ecdc45ca.png)\n\n*原論文 Figure 2（Hamilton ら）、[**PDF 7 ページ**](https://arxiv.org/pdf/1706.02216v4#page=7)より。原キャプションは省略。*\n\n左図の訓練時間は近く、GraphSAGE-LSTM が最遅です。しかしテスト時の DeepWalk は新ノードでウォークと SGD をやり直すため、100〜500 倍遅くなります。\n\n右図では、抽出を増やすほど F1 は上がりますが、利得は急速に小さくなり、時間は増え続けます。$K=2$ は $K=1$ より平均 10%〜15% 改善し、$K>2$ はさらに 0%〜5% の改善に対し、時間が 10〜100 倍かかります。\n\n### その後\n\n論文の最後では、PPI をさらに改善するなら Chen と Zhu の後続研究を参照するよう勧めています。PPI 向けに調整し、dropout、layer normalization、新しいサンプリングを加えた仕事です。\n\n翌年、Rex Ying、Hamilton、Leskovec は Pinterest と PinSage を発表しました。30 億ノードのグラフで 75 億サンプルを使って訓練し、Pinterest の推薦エンジンとして配備しています。[PinSage 要旨](https://arxiv.org/abs/1806.01973v1)\n\n## 結論\n\nGraphSAGE は対応表でなく関数を学びます。隣を抽出してバッチのコストを固定し、大規模グラフもミニバッチ訓練できるようにします。自分と隣に別の重みを掛けるだけで、GCN 風の平均をかなり上回ります。\n\n自分の大規模グラフなら、$K=2$、$S_1=25$、$S_2=10$ の mean でベースラインを作れます。PyTorch Geometric の `SAGEConv` と `NeighborLoader` が、抽出とミニバッチを担当してくれます。\n","imageSizes":{"/content/papers/assets/88f6d9397f20155603c7ee0daef374fb944aac5fb73ed6573a573560b5b9c6aa.png":{"width":1090,"height":384},"/content/papers/assets/ff62a5b1aa8349edd927fc6014fd713adf4d76672507efe1a7527ff6ecdc45ca.png":{"width":1092,"height":336}}}
