[英]IndexError: Dimension out of range (expected to be in range of [-1, 0], but got -2) with torch_geometry
I have some trouble with IndexError in my GCN code.我在 GCN 代码中遇到了 IndexError 问题。 The error occurred on the GCNConv layer.错误发生在 GCNConv 层上。 I cannot understand why self.node_dim is included in the size function which is shown in the error code.我不明白为什么 self.node_dim 包含在错误代码中显示的大小 function 中。
How can I solve this problem?我怎么解决这个问题? data.x is node_feature in which the number of feature for each node is just one and the number of node is 2058. data.x 是 node_feature ,其中每个节点的特征数仅为 1,节点数为 2058。
Thanks in advance.提前致谢。
''' '''
class GCNEncoder(torch.nn.Module):
def __init__(self, in_channels, out_channels):
super(GCNEncoder, self).__init__()
self.conv1 = GCNConv(in_channels, out_channels, cached=True)
self.conv2 = GCNConv(out_channels, out_channels, cached=True)
def forward(self, x, edge_index):
x = self.conv1(x, edge_index).relu()
return self.conv2(x, edge_index)
class OurGAE(torch.nn.Module):
def __init__(self, num_features, out_chennels, node):
super(OurGAE, self).__init__()
self.encoder = GCNEncoder(num_features, out_channels)
self.linear = nn.Linear(out_channels, len(node))
def encode(self, node_feature, edge_lst):
z = self.encoder(node_feature, edge_lst)
return z
def predict(self, z):
predicted_node_features = self.linear(z)
return predicted_node_features
############ train model #######
dataset = OurDataset(one_node_feature, super_edge_lst)
out_channels = 16
num_features = dataset.num_features
model = OurGAE(num_features, out_channels, node)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
epochs = 100
criterion = nn.MSELoss()
#model.train()
for epoch in range(1, epochs + 1):
loss_ep = 0
for data in dataset:
optimizer.zero_grad()
x = data.x.to(device)
edge_lst = data.edge_index.to(device)
z = model.encode(x, edge_lst)
super_z = z[-1]
predicted_x = model.predict(super_z)
loss = criterion(x.reshape(-1), predicted_x)
loss.backward()
optimizer.step()
loss_ep += loss.cpu().detach().data.numpy()
if epoch % 1 == 0:
print(f"epoch: {epoch}, loss : {loss_ep}") '''
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-103-9dd243b81c8e> in <module>
71 edge_lst = data.edge_index.to(device)
72
---> 73 z = model.encode(x, edge_lst)
74
75 super_z = z[-1]
<ipython-input-103-9dd243b81c8e> in encode(self, node_feature, edge_lst)
36
37 def encode(self, node_feature, edge_lst):
---> 38 z = self.encoder(node_feature, edge_lst)
39 return z
40
~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
725 result = self._slow_forward(*input, **kwargs)
726 else:
--> 727 result = self.forward(*input, **kwargs)
728 for hook in itertools.chain(
729 _global_forward_hooks.values(),
<ipython-input-103-9dd243b81c8e> in forward(self, x, edge_index)
15
16 def forward(self, x, edge_index):
---> 17 x = self.conv1(x, edge_index).relu()
18 return self.conv2(x, edge_index)
19
~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
725 result = self._slow_forward(*input, **kwargs)
726 else:
--> 727 result = self.forward(*input, **kwargs)
728 for hook in itertools.chain(
729 _global_forward_hooks.values(),
~/anaconda3/lib/python3.8/site-packages/torch_geometric/nn/conv/gcn_conv.py in forward(self, x, edge_index, edge_weight)
159 if cache is None:
160 edge_index, edge_weight = gcn_norm( # yapf: disable
--> 161 edge_index, edge_weight, x.size(self.node_dim),
162 self.improved, self.add_self_loops)
163 if self.cached:
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got -2)
TLDR: reshape your data-points to [num_nodes, num_node_features]
=> [2058, 1]
before constructing the dataset. TLDR:在构建数据集之前,将您的数据点重塑为[num_nodes, num_node_features]
=> [2058, 1]
。
It looks like the OurDataset
you created doesn't fit the assumptions of the graph dataset.看起来您创建的OurDataset
不符合图形数据集的假设。 I just assume this is because you have only one feature at each node, and you most probably didn't reshape the data before passing it to the Dataset.我只是假设这是因为您在每个节点上只有一个功能,并且您很可能在将数据传递给数据集之前没有重塑数据。
Taken from the documentation : Data Handling of Graphs取自文档:图形的数据处理
from torch_geometric.data import Data
edge_index = torch.tensor([[0, 1, 1, 2], [1, 0, 2, 1]], dtype=torch.long)
x_wrong_dims = torch.tensor([-1, 0, 1], dtype=torch.float)
data_wrong_dims = Data(x=x_wrong_dims, edge_index=edge_index)
data_wrong_dims.x.size()
# torch.Size([3])
data_wrong_dims.x.size(-2)
# IndexError: Dimension out of range (expected to be in range of [-1, 0], but got -2)
x_correct_dims = torch.tensor([-1, 0, 1], dtype=torch.float).reshape([-1, 1])
data_correct_dims = Data(x=x_correct_dims, edge_index=edge_index)
data_correct_dims.x.size()
# torch.Size([3, 1])
data_correct_dims.x.size(-2)
# 3
As to the question why gcn_norm
uses the x.size(self.node_dim)
I would assume that the function has to infer along which dimension to aggregate for the normalization and node_dim is -2 by default which means it aggregates over the second to last dimensions which in the case of the correctly shaped dataset is the num_nodes
dimension.至于为什么gcn_norm
使用x.size(self.node_dim)
的问题,我假设 function 必须推断为标准化聚合的维度,并且node_dim 默认为 -2,这意味着它聚合倒数第二个维度在正确形状的数据集的情况下,是num_nodes
维度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.