1.代码
class HeatDataset(InMemoryDataset):
"""
Dataset preprocessed with GDC using heat kernel diffusion.
Note that this implementations is not scalable
since we directly calculate the matrix exponential
of the adjacency matrix.
"""
def __init__(self,
name: str = 'Cora',
use_lcc: bool = True,
t: float = 5.0,
k: int = 16,
eps: float = None):
self.name = name
self.use_lcc = use_lcc
self.t = t
self.k = k
self.eps = eps
super(HeatDataset, self).__init__(DATA_PATH)
self.data, self.slices = torch.load(self.processed_paths[0])
@property
def raw_file_names(self) -> list:
return []
@property
def processed_file_names(self) -> list:
return [str(self) + '.pt']
def download(self):
pass
def process(self):
base = get_dataset(name=self.name, use_lcc=self.use_lcc)
# generate adjacency matrix from sparse representation !!!!!!!!由稀疏表示生成邻接矩阵!!!!!
adj_matrix = get_adj_matrix(base)
# get heat matrix as described in Berberidis et al., 2019 !!!!!!!!#如Berberidis等人所述获得热矩阵:!!!!!!
heat_matrix = get_heat_matrix(adj_matrix,
t=self.t)
if self.k:
print(f'Selecting top {self.k} edges per node.')
heat_matrix = get_top_k_matrix(heat_matrix, k=self.k)
elif self.eps:
print(f'Selecting edges with weight greater than {self.eps}.')
heat_matrix = get_clipped_matrix(heat_matrix, eps=self.eps)
else:
raise ValueError
# create PyG Data object
edges_i = []
edges_j = []
edge_attr = []
for i, row in enumerate(heat_matrix):
for j in np.where(row > 0)[0]:
edges_i.append(i)
edges_j.append(j)
edge_attr.append(heat_matrix[i, j])
edge_index = [edges_i, edges_j]
data = Data(
x=base.data.x,
edge_index=torch.LongTensor(edge_index),
edge_attr=torch.FloatTensor(edge_attr),
y=base.data.y,
train_mask=torch.zeros(base.data.train_mask.size()[0], dtype=torch.bool),
test_mask=torch.zeros(base.data.test_mask.size()[0], dtype=torch.bool),
val_mask=torch.zeros(base.data.val_mask.size()[0], dtype=torch.bool)
)
data, slices = self.collate([data])
torch.save((data, slices), self.processed_paths[0])
def __str__(self) -> str:
return f'{self.name}_heat_t={self.t}_k={self.k}_eps={self.eps}_lcc={self.use_lcc}'
2.大致流程
我们只说process()函数,其他的都是一些初始化
1.加载基础数据集(?拉普拉斯矩阵中心化)
2.制作邻接矩阵
3.制作热矩阵 (邻接矩阵--->热矩阵)
4.处理热矩阵 (阈值--->留大去小)
5.边 ---> PyG数据对象 (这个数据对象包含了所有的信息,比如节点特征、边索引、边属性等)
6.数据处理并保存
注释:如果对这些拉普拉斯矩阵,还有邻接矩阵不了解的话,可以去简单学一下图基础
3.细节
1.热矩阵的生成:
制作热矩阵的过程就是根据邻接矩阵和某种函数(如指数函数或其他核函数)来计算每个节点对之间的相似度或权重。
假设你有一盘由五个节点组成的图(节点A、B、C、D、E),它们之间有着不同的连接关系(即邻接矩阵)。为了制作热矩阵,你可以选择使用指数函数来计算每个节点对之间的相似度。具体来说,对于任意两个节点i和j,你可以计算它们的相似度为exp(-t * ||xi - xj||^2),其中xi和xj分别是节点i和j的特征向量,t是一个控制相似度衰减速度的参数。
通过计算每个节点对之间的相似度,你可以得到一个5x5的热矩阵,矩阵中的每个元素表示相应节点对之间的相似度或权重。
2.热矩阵的处理:
处理热矩阵的过程可以根据不同的需求来进行。比如,如果你想要选择每个节点权重最大的k条边,你可以对热矩阵的每一行进行排序,并只保留权重最大的k个元素。
如果你想要选择权重大于某个阈值的边,你可以遍历热矩阵的所有元素,只保留那些权重大于阈值的元素。
根据k和eps参数的值,对热矩阵进行进一步处理。
如果k不为0,则选择每个节点权重最大的k条边;
如果eps不为0,则选择权重大于eps的边;
如果k和eps都为0,则抛出错误。
3.数据保存:
1.
创建PyG数据对象:根据处理后的热矩阵,创建一个PyG数据对象。这个对象包含了节点的特征(x)、边的索引(edge_index)、边的属性(edge_attr)以及训练和验证/测试集的掩码(train_mask, test_mask, val_mask)。
2.
- 数据整理与保存:使用self.collate函数对PyG数据对象进行整理,并保存整理后的数据和切片信息到指定的路径。
4.
如果想让他与别的模型结合,比如测试图扩散对噪音标签训练的影响。
可以去学习一下PyG数据对象,弄清数据的输入和输出,还有数据结构和如何调用。
然后就会一路畅通。