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.

Graph Neural Network (GNN) with Adaptive Neighborhood Aggregation for Node Representation Learning

原文地址: https://www.cveoy.top/t/topic/jOyF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录