Error in example of implementation heterogeneous Graph neural network

Hi, I’m trying to implement a neural network example to understand how it works and I get the following error:

C:\GCN\venv\lib\site-packages\torch_geometric\nn\conv\hetero_conv.py:76: UserWarning: There exist node types ({‘t’, ‘g’, ‘c’}) whose representations do not get updated during message passing as they do not occur as destination type in any edge type. This may lead to unexpected behavior.
warnings.warn(
Traceback (most recent call last):
File “C:\GCN\main.py”, line 77, in
out = model(data)
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1736, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1747, in _call_impl
return forward_call(*args, **kwargs)
File “C:\GCN\main.py”, line 29, in forward
out = self.conv1(data.x_dict, data.edge_index_dict)
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1736, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1747, in _call_impl
return forward_call(*args, **kwargs)
File “C:\GCN\venv\lib\site-packages\torch_geometric\nn\conv\hetero_conv.py”, line 119, in forward
src, rel, dst = edge_type
ValueError: too many values to unpack (expected 3)

The code is as follows:

import torch
import torch.nn as nn
import torch.optim as optim
import torch_geometric
from torch_geometric.nn import HeteroConv, GCNConv
from torch_geometric.data import HeteroData
import numpy as np

Definir la red neuronal heterogénea

class HeteroGNN(nn.Module):
def init(self, input_features, output_features):
super(HeteroGNN, self).init()
# Red convolucional para diferentes tipos de nodos, desactivar self-loops
self.conv1 = HeteroConv({
‘generator’: GCNConv(input_features, 64, add_self_loops=False),
‘consumer’: GCNConv(input_features, 64, add_self_loops=False),
‘transformer’: GCNConv(input_features, 64, add_self_loops=False)
}, aggr=‘mean’)

    self.conv2 = HeteroConv({
        'generator': GCNConv(64, 32, add_self_loops=False),
        'consumer': GCNConv(64, 32, add_self_loops=False),
        'transformer': GCNConv(64, 32, add_self_loops=False)
    }, aggr='mean')

    self.fc = nn.Linear(32, output_features)  # Predicción de la tensión de cada nodo

def forward(self, data):
    out = self.conv1(data.x_dict, data.edge_index_dict)
    out = self.conv2(out, data.edge_index_dict)
    out = {key: self.fc(val) for key, val in out.items()}
    return out

Datos de ejemplo

nodos = 4 # Ejemplo: 4 nodos
caracteristicas_generador = np.random.rand(1, 2) # P, Q para generadores
caracteristicas_consumidor = np.random.rand(2, 2) # P, Q para consumidores
caracteristicas_transformador = np.random.rand(1, 2) # V para transformadores

Definir las conexiones entre los nodos

edge_index_generator_to_consumer = torch.tensor([[0, 0], [1, 2]], dtype=torch.long) # Conexiones de generador a consumidores
edge_index_consumer_to_transformer = torch.tensor([[1, 2], [3, 3]], dtype=torch.long) # Conexiones de consumidores a transformadores

Tensiones reales de cada nodo (estas son las etiquetas de salida)

tensiones_reales = torch.tensor([1.05, 1.02, 1.08, 1.01], dtype=torch.float).view(-1, 1)

Convertir a un formato compatible con PyTorch Geometric HeteroData

data = HeteroData()

Añadir características de los nodos a HeteroData

data[‘generator’].x = torch.tensor(caracteristicas_generador, dtype=torch.float)
data[‘consumer’].x = torch.tensor(caracteristicas_consumidor, dtype=torch.float)
data[‘transformer’].x = torch.tensor(caracteristicas_transformador, dtype=torch.float)

Definir las conexiones entre los nodos (tipos de relaciones entre nodos)

data.edge_index_dict = {
(‘generator’, ‘to’, ‘consumer’): edge_index_generator_to_consumer,
(‘consumer’, ‘to’, ‘transformer’): edge_index_consumer_to_transformer
}

print(“Datos de entrada:\n”, data)

Crear la red neuronal

input_features = 2 # Porque cada nodo tiene 2 características (P y Q para generadores/consumidores, V para transformadores)
output_features = 1 # Predecir la tensión de cada nodo
model = HeteroGNN(input_features, output_features)

Configurar el optimizador y la función de pérdida

optimizer = optim.Adam(model.parameters(), lr=0.001)
loss_fn = nn.MSELoss()

Entrenamiento

epochs = 1000
for epoch in range(epochs):
model.train()
optimizer.zero_grad()
out = model(data)
loss = sum(loss_fn(out[key], tensiones_reales) for key in out) / len(out)
loss.backward()
optimizer.step()

if (epoch + 1) % 100 == 0:
    print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

Evaluación

model.eval()
with torch.no_grad():
prediccion_tensiones = model(data)
print("Tensiones predichas: ", prediccion_tensiones)
print("Tensiones reales: ", tensiones_reales)

Thank you very much for your help and time