关键点: 1.理解图结构的形式 2.如何使用邻接矩阵实现其图结构形式 3.GCN卷积是如何实现节点特征更新的 核心公式: 特征提取: 处理好的x 代表节点特征,然后*权重,再*邻接。 A尖换元后: forward函数 传播规则: loss: 1.数据处理有价值的代码: 对labels 列,进行 one hot 编码。 就是将 有限个 不管是什么类型的数据,用 不同顺序的01数表示出来。 def encode_onehot(labels): classes = set(labels) //for i,c in enumerate(classes): // print(i,c) classes_dict = {c: np.identity(len(classes))[i, :] for i, c in enumerate(classes)} //print(classes_dict) labels_onehot = np.array(list(map(classes_dict.get, labels)), dtype=np.int32) return labels_onehot labels = encode_onehot(idx_features_labels[:, -1]) 还能把1的位置转换成一维的 labels = torch.LongTensor(np.where(labels)[1]) 同理,给了很杂乱的 结点input,可以用 dic去编码。{原label:现label} idx = np.array(idx_features_labels[:, 0], dtype=np.int32) idx_map = {j: i for i, j in enumerate(idx)} 随后用编码过的节点,去 编码边 edges_unordered = 边数据 edges = np.array(list(map(idx_map.get, edges_unordered.flatten())),dtype=np.int32).reshape(edges_unordered.shape) 给了边 构建 邻接矩阵且为稀疏矩阵 adj = sp.coo_matrix((np.ones(edges.shape[0]), (edges[:, 0], edges[:, 1])), shape=(labels.shape[0], labels.shape[0]), dtype=np.float32) print(adj) 计算转置矩阵将 有向图转化为无向图 adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) 归一化函数 def normalize(mx): rowsum = np.array(mx.sum(1)) #矩阵行求和 r_inv = np.power(rowsum, -1).flatten() ##求和的倒数 r_inv[np.isinf(r_inv)] = 0.#由于原本为0的数求倒数后可能会产生极大值,这里设置极大值为0 r_mat_inv = sp.diags(r_inv) ##构造对角线矩阵 mx = r_mat_inv.dot(mx) return mx adj = normalize(adj + sp.eye(adj.shape[0])) #对应论文中公式,加上了I矩阵 这种归一化方式,将不再单单地对领域节特征点取平均,它不仅 考虑了节点i ii的 度,也考虑了邻接节点j jj的度, 当邻居节点 j jj 度数较大时,它在聚合时贡献地会更少 2.缺点: 第一,GCN需要将整个图放到内存和显存,这将非常耗内存和显存,处理不了大图; 第二,GCN在训练时需要知道整个图的结构信息(包括待预测的节点), 这在现实某些任务中也不能实现(比如用今天训练的图模型预测明天的数据,那么明天的节点是拿不到的)。
标签:总结,知识,labels,edges,GCN,classes,np,adj,节点 From: https://blog.csdn.net/weixin_74152658/article/details/140620669