Graph Neural Network (GNN) with Adaptive Neighborhood Aggregation for Node Representation Learning
from __future__ import division
from __future__ import print_function
# 导入包
import argparse
import numpy as np
import scipy.sparse as sp
import torch
import torch.nn.functional as F
parser = argparse.ArgumentParser()
parser.add_argument('--seed', type=int, default=42, help='Random seed.')
parser.add_argument('--dataset', type=str,
default='cora', help='type of dataset.')
#parser.add_argument('--hops', type=int, default=20, help='number of hops')
hops =20
r_list = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
args = parser.parse_args()
def sparse_mx_to_torch_sparse_tensor(sparse_mx):
sparse_mx = sparse_mx.tocoo().astype(np.float32)
indices = torch.from_numpy(
np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64))
values = torch.from_numpy(sparse_mx.data)
shape = torch.Size(sparse_mx.shape)
return torch.sparse.FloatTensor(indices, values, shape)
def normalize_adj(mx, r):
'''Row-normalize sparse matrix'''
mx = sp.coo_matrix(mx) + sp.eye(mx.shape[0])# 将邻接矩阵转换为coo格式,然后加上对角线元素
rowsum = np.array(mx.sum(1))# 按行求和
r_inv_sqrt_left = np.power(rowsum, r-1).flatten()# 求行向量的r-1次方,并将结果展平
r_inv_sqrt_left[np.isinf(r_inv_sqrt_left)] = 0.# 如果结果中有inf则赋值为0
r_mat_inv_sqrt_left = sp.diags(r_inv_sqrt_left)
r_inv_sqrt_right = np.power(rowsum, -r).flatten()# 求行向量的-r次方,并将结果展平
r_inv_sqrt_right[np.isinf(r_inv_sqrt_right)] = 0.# 如果结果中有inf则赋值为0
r_mat_inv_sqrt_right = sp.diags(r_inv_sqrt_right)
adj_normalized = mx.dot(r_mat_inv_sqrt_left).transpose().dot(r_mat_inv_sqrt_right).tocoo()# 计算D^ r_t-1 A^ ~ D^ -r_t,DAD
return sparse_mx_to_torch_sparse_tensor(adj_normalized)
def run(args):
adj = torch.tensor([
[1., 1., 0., 0., 0., 0., 0., 1., 0., 0.],
[1., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 1.],
])
features=torch.tensor([
[1., 1.2, 0., 0., 0., 0., 0., 1., 0.2, 0.],
[1., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.5, 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 1., 0., 0., 0., 0., 0.],
[0., 0., 2., 0., 0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0.4, 0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 1.],
])
n_nodes, feat_dim = features.shape
# 迭代hop次
for hop in range(hops, hops+1): # hop为迭代次数n
# 设置
input_features = 0.
for r in r_list:
adj_norm = normalize_adj(adj, r)
features_list = []
features_list.append(features) #
features_list.append(torch.spmm(adj_norm, features_list[-1]))
# 计算权重
weight_list = []
norm_fea = torch.norm(features, 2, 1).add(1e-10)
for fea in features_list:
norm_cur = torch.norm(fea, 2, 1).add(1e-10)
temp = torch.div((features*fea).sum(1), norm_fea)
temp = torch.div(temp, norm_cur)
weight_list.append(temp.unsqueeze(-1))
weight = F.softmax(torch.cat(weight_list, dim=1), dim=1)
input_feas = []
for i in range(n_nodes):
fea = 0.
for j in range(hop+1):
if j < len(features_list):
fea += (weight[i][j]*features_list[j][i]).unsqueeze(0)
input_feas.append(fea)
input_feas = torch.cat(input_feas, dim=0)
if r == r_list[0]:
input_features = input_feas
else:
temp = []
temp.append(input_features.unsqueeze(0))
temp.append(input_feas.unsqueeze(0))
input_features = torch.cat(temp, dim=0).max(0)[0]
sim = torch.sigmoid(torch.mm(input_features, input_features.T))
if __name__ == '__main__':
run(args)
The error message 'index 2 is out of bounds for dimension 0 with size 2' suggests that you are trying to access an element at index 2 in a tensor of size 2. This usually happens when you are iterating over a list or tensor and the index you are using goes beyond the bounds of the list/tensor. In this case, the issue is likely in the loop where you are calculating the weighted sum of features:
for j in range(hop+1):
if j < len(features_list):
fea += (weight[i][j]*features_list[j][i]).unsqueeze(0)
Here, you are iterating over range(hop+1), which means that j will go from 0 to hop. However, features_list only has two elements (features from the current layer and features from the previous layer). Therefore, when j is 2 or greater, you are trying to access an element beyond the bounds of features_list.
The fix is to add a check to ensure that j is within the bounds of features_list:
for j in range(hop+1):
if j < len(features_list):
fea += (weight[i][j]*features_list[j][i]).unsqueeze(0)
This code ensures that you are not accessing elements that are out of bounds and should resolve the error you are encountering.
原文地址: https://www.cveoy.top/t/topic/jOyF 著作权归作者所有。请勿转载和采集!