在计算交叉熵之前需要用softmax函数将每个元素映射到[0,1]区间。
torch.nn.functional.cross_entropy中内置了softmax函数。
如果cuda版本不对应,在torch.tensor().cuda()
/torch.tensor.to(device)
时会导致tensor的值全0的情况。
从cuda: i
移动到cuda: j
有可能会出现tensor的值全0的情况,统一cuda。
保存tensor时记得.cpu()
或者保存成.cpu().data.numpy()
格式
graph convolution network的batch写法:
batch采样
g
:要输入GCN的图
train_idx
: 训练集的节点
sampler
: dgl.dataloading.MultiLayerNeighborSampler
类
sample_list = [3,4] #第一层GCN取3个邻居,第二层GCN取4个邻居
sampler = dgl.dataloading.MultiLayerNeighborSampler(sample_list)
train_dataloader = dgl.dataloading.DataLoader(g,train_idx,sampler,device=device, batch_size=64,shuffle=True,drop_last=False,num_workers=0)
for batch, (input_nodes, output_nodes, blocks) in enumerate(train_dataloader):
sample_node_id = blocks[-1].dstdata[dgl.NID]
sample_node_new_id = blocks[-1].dstnodes()
print('batch:', batch)
print('DataLoader对每个节点ID重新排序',sample_node_new_id)
print('采样的节点的ID', sample_node_id)
返回值:
batch
: 第几个batch
input_nodes
:对于每个batch要计算的64个节点,最开始需要输入的节点。即该batch的64个节点+它的邻居的采样。
output_nodes
:一个batch要计算的64个节点。
blocks
:每一层GCN的输入图,第i个block由第i层的输入顶点和第i层的输出顶点(第i+1层的输入顶点)组成。
以两层GCN为例子:
- blocks[0] : 第一层GCN,输入是input_nodes,输出是dataloader计算出来的,计算batch的64个节点+64个节点所需要的邻居
- blocks[1]:第二层GCN,输入是blocks[0]的输出,输出是64个节点
GCN写法
- 函数介绍
GraphConv
: graph的卷积层,要几层GCN就有几个GraphConv函数。初始化定义时传入参数input_dim
,output_dim
, 激活函数activation
。在使用时用.forward(g, h)
,g
是dgl.DGLGraph类,h
是输入节点的embedding。
from dgl.nn.pytorch import GraphConv
class GCN(nn.Module):
def __init__(self, node_feat_dim, hidden_dim):
super(GCN, self).__init()
self.conv1 = GraphConv(node_feat_dim, hidden_dim, activation=torch.nn.LeakyReLU())
self.conv2 = GraphConv(hidden_dim, hidden_dim, activation=torch.nn.LeakyReLU())
self.conv3 = GraphConv(hidden_dim, hidden_dim, activation=lambda x: x) #最后输出不要用激活函数(有的激活函数会把负数归0)