日常复现模型,打开日志文件,测试误差部分满屏幕的报错,没截图,大意是:模型输出有空值,无法计算fmax和aupr
然后因为是服务器上跑,不知道怎么启动调试模式,只能使用print大法打出中间变量。类似这个样子:
h_output_ = torch.matmul(self.origin_adj.transpose(0, 1) * self.out_adj_matrix, h_)
# print(5, torch.isnan(self.origin_adj).any())
# print(6, torch.isnan(self.out_adj_matrix).any())
# print(7, torch.isnan(h_).any())
out_ = h_output_ + self.out_edge_bias
# print(8, torch.isnan(out_).any())
out_gate_ = torch.matmul(h_, self.out_gate_weight)
# print(9, torch.isnan(out_gate_).any())
# print(12, self.out_bias_gate)
out_gate_ = out_gate_ + self.out_bias_gate
# print(10, torch.isnan(out_gate_).any())
# print(11, torch.isnan(self.out_bias_gate).any())
最后定位到是self.out_bias_gate里面有空值:
往回查,发现这个参数只定义了,没有初始化:
self.out_bias_gate = Parameter(torch.Tensor(num_nodes, 1))
初始化之后,问题解决:
for param in [self.edge_bias, self.out_edge_bias, self.bias_gate, self.out_bias_gate]:
nn.init.zeros_(param)
但问题依旧不少:首先,用这个模型训练了两个数据集,但是前一个没有问题,到这个就报值为空的错误。其次,在打印中间变量的时候,出现过一次什么都没有改,但是程序成功跑起来了的情况。最后,在一开始debug的时候,为了缩短训练时间,强制将一个epoch的迭代次数设置为10,最后程序也是成功跑起来了。
炼丹果然是一门玄学。
===============更新==============
思来想去,对于第一个问题,两个数据集一个可以成功跑起来一个不能。而这两个模型在定义self.out_bias_gate的时候,只有一个值是不一样的:num_nodes
于是乎我进行了一个简单的实验,得到的结果让人哭笑不得:
?玄学,果然是玄学
|