# GraphSAGE

## 传播公式

GraphSAGE的更新embedding的思路非常简单：

## DGL实现邻居采样

### 同构图

``````import torch
import dgl

src = torch.LongTensor(
[0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10,
1, 2, 3, 3, 3, 4, 5, 5, 6, 5, 8, 6, 8, 9, 8, 11, 11, 10, 11])
dst = torch.LongTensor(
[1, 2, 3, 3, 3, 4, 5, 5, 6, 5, 8, 6, 8, 9, 8, 11, 11, 10, 11,
0, 0, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10])
g = dgl.graph((src, dst))

g, [5], sampler,
batch_size=1, shuffle=True, drop_last=False, num_workers=4)
for input_nodes, output_nodes, blocks in dataloader:
print(input_nodes) # 输入的节点数
print(output_nodes) # 输出的节点数
print(blocks)
for i in range(len(blocks)):
left, right = blocks[i].edges()
u = [int(input_nodes[l]) for l in left]
v = [int(input_nodes[r]) for r in right]
print("u_v", u, v)
print("此块输入节点", blocks[i].srcdata)
print("此块输出节点", blocks[i].dstdata)
print("*" * 10)
print("="*10)
``````

``````sampler = dgl.dataloading.NeighborSampler([1, 2, 3])
``````

### 异构图

``````import dgl
import torch
import dgl
g = dgl.heterograph({
('user', 'follows', 'user') : ([0, 1, 2, 3, 3, 4], [1, 2, 1, 1, 4, 0]),
('user', 'plays', 'game') : ([0, 1, 1, 2], [1, 1, 2, 3]),
('store', 'sells', 'game')  :([0, 0, 2, 3, 5], [2, 1, 2, 3, 4]),
("game", "absorbed", "user") : ([1, 2], [1, 1]),
("store", "bought", "user") : ([3], [1])})

g, {"user":torch.tensor([1])}, sampler,
batch_size=1, shuffle=True, drop_last=False, num_workers=4)
for input_nodes, output_nodes, blocks in dataloader:
print(input_nodes)
print(output_nodes)
for i in range(len(blocks)):
print("此块输入节点", blocks[i].srcdata)
print("此块输出节点", blocks[i].dstdata)
print("*" * 10)
print("="*10)
print(blocks)
``````

``````sampler = dgl.dataloading.NeighborSampler([1, 1])
``````

``````import dgl
import torch
import dgl
g = dgl.heterograph({
('user', 'follows', 'user') : ([0, 1, 2, 3, 3, 4], [1, 2, 1, 1, 4, 0]),
('user', 'plays', 'game') : ([0, 1, 1, 2], [1, 1, 2, 3]),
('store', 'sells', 'game')  :([0, 0, 2, 3, 5], [2, 1, 2, 3, 4]),
("game", "absorbed", "user") : ([1, 2], [1, 1]),
("store", "bought", "user") : ([3], [1])})

{('user', 'follows', 'user'): 2,  # follows关系采样2个
('user', 'plays', 'game'):1,
('store', 'sells', 'game'):1,
("game", "absorbed", "user"):1,
("store", "bought", "user"):1}] * 2)
g, {"user":torch.tensor([1])}, sampler,
batch_size=1, shuffle=True, drop_last=False, num_workers=4)
for input_nodes, output_nodes, blocks in dataloader:
print(input_nodes)
print(output_nodes)
for i in range(len(blocks)):
print("此块输入节点", blocks[i].srcdata)
print("此块输出节点", blocks[i].dstdata)
print("*" * 10)
print("="*10)
print(blocks)
``````

# 参考

https://www.bilibili.com/video/BV1K5411H7EQ?p=10&vd_source=f57738ab6bbbbd5fe07aae2e1fa1280f

Inductive Representation Learning on Large Graphs

https://docs.dgl.ai/guide_cn/minibatch-custom-sampler.html

THE END

)">