Error in example of implementation heterogeneous Graph neural network

Diego_Paul_Guachichu: <p>Hi, I’m trying to implement a neural network example to understand how it works and I get the following error:</p>
<p>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.<br>
warnings.warn(<br>
Traceback (most recent call last):<br>
File “C:\GCN\main.py”, line 77, in <br>
out = model(data)<br>
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1736, in _wrapped_call_impl<br>
return self._call_impl(*args, **kwargs)<br>
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1747, in _call_impl<br>
return forward_call(*args, **kwargs)<br>
File “C:\GCN\main.py”, line 29, in forward<br>
out = self.conv1(data.x_dict, data.edge_index_dict)<br>
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1736, in _wrapped_call_impl<br>
return self._call_impl(*args, **kwargs)<br>
File “C:\GCN\venv\lib\site-packages\torch\nn\modules\module.py”, line 1747, in _call_impl<br>
return forward_call(*args, **kwargs)<br>
File “C:\GCN\venv\lib\site-packages\torch_geometric\nn\conv\hetero_conv.py”, line 119, in forward<br>
src, rel, dst = edge_type<br>
ValueError: too many values to unpack (expected 3)</p>
<p>The code is as follows:</p>
<p>import torch<br>
import torch.nn as nn<br>
import torch.optim as optim<br>
import torch_geometric<br>
from torch_geometric.nn import HeteroConv, GCNConv<br>
from torch_geometric.data import HeteroData<br>
import numpy as np</p>
<h1><a name="p-462759-definir-la-red-neuronal-heterognea-1" class="anchor" href="#p-462759-definir-la-red-neuronal-heterognea-1"></a>Definir la red neuronal heterogénea</h1>
<p>class HeteroGNN(nn.Module):<br>
def <strong>init</strong>(self, input_features, output_features):<br>
super(HeteroGNN, self).<strong>init</strong>()<br>
# Red convolucional para diferentes tipos de nodos, desactivar self-loops<br>
self.conv1 = HeteroConv({<br>
‘generator’: GCNConv(input_features, 64, add_self_loops=False),<br>
‘consumer’: GCNConv(input_features, 64, add_self_loops=False),<br>
‘transformer’: GCNConv(input_features, 64, add_self_loops=False)<br>
}, aggr=‘mean’)</p>
<pre><code>    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
</code></pre>
<h1><a name="p-462759-datos-de-ejemplo-2" class="anchor" href="#p-462759-datos-de-ejemplo-2"></a>Datos de ejemplo</h1>
<p>nodos = 4  # Ejemplo: 4 nodos<br>
caracteristicas_generador = np.random.rand(1, 2)  # P, Q para generadores<br>
caracteristicas_consumidor = np.random.rand(2, 2)  # P, Q para consumidores<br>
caracteristicas_transformador = np.random.rand(1, 2)  # V para transformadores</p>
<h1><a name="p-462759-definir-las-conexiones-entre-los-nodos-3" class="anchor" href="#p-462759-definir-las-conexiones-entre-los-nodos-3"></a>Definir las conexiones entre los nodos</h1>
<p>edge_index_generator_to_consumer = torch.tensor([[0, 0], [1, 2]], dtype=torch.long)  # Conexiones de generador a consumidores<br>
edge_index_consumer_to_transformer = torch.tensor([[1, 2], [3, 3]], dtype=torch.long)  # Conexiones de consumidores a transformadores</p>
<h1><a name="p-462759-tensiones-reales-de-cada-nodo-estas-son-las-etiquetas-de-salida-4" class="anchor" href="#p-462759-tensiones-reales-de-cada-nodo-estas-son-las-etiquetas-de-salida-4"></a>Tensiones reales de cada nodo (estas son las etiquetas de salida)</h1>
<p>tensiones_reales = torch.tensor([1.05, 1.02, 1.08, 1.01], dtype=torch.float).view(-1, 1)</p>
<h1><a name="p-462759-convertir-a-un-formato-compatible-con-pytorch-geometric-heterodata-5" class="anchor" href="#p-462759-convertir-a-un-formato-compatible-con-pytorch-geometric-heterodata-5"></a>Convertir a un formato compatible con PyTorch Geometric HeteroData</h1>
<p>data = HeteroData()</p>
<h1><a name="p-462759-aadir-caractersticas-de-los-nodos-a-heterodata-6" class="anchor" href="#p-462759-aadir-caractersticas-de-los-nodos-a-heterodata-6"></a>Añadir características de los nodos a HeteroData</h1>
<p>data[‘generator’].x = torch.tensor(caracteristicas_generador, dtype=torch.float)<br>
data[‘consumer’].x = torch.tensor(caracteristicas_consumidor, dtype=torch.float)<br>
data[‘transformer’].x = torch.tensor(caracteristicas_transformador, dtype=torch.float)</p>
<h1><a name="p-462759-definir-las-conexiones-entre-los-nodos-tipos-de-relaciones-entre-nodos-7" class="anchor" href="#p-462759-definir-las-conexiones-entre-los-nodos-tipos-de-relaciones-entre-nodos-7"></a>Definir las conexiones entre los nodos (tipos de relaciones entre nodos)</h1>
<p>data.edge_index_dict = {<br>
(‘generator’, ‘to’, ‘consumer’): edge_index_generator_to_consumer,<br>
(‘consumer’, ‘to’, ‘transformer’): edge_index_consumer_to_transformer<br>
}</p>
<p>print(“Datos de entrada:\n”, data)</p>
<h1><a name="p-462759-crear-la-red-neuronal-8" class="anchor" href="#p-462759-crear-la-red-neuronal-8"></a>Crear la red neuronal</h1>
<p>input_features = 2  # Porque cada nodo tiene 2 características (P y Q para generadores/consumidores, V para transformadores)<br>
output_features = 1  # Predecir la tensión de cada nodo<br>
model = HeteroGNN(input_features, output_features)</p>
<h1><a name="p-462759-configurar-el-optimizador-y-la-funcin-de-prdida-9" class="anchor" href="#p-462759-configurar-el-optimizador-y-la-funcin-de-prdida-9"></a>Configurar el optimizador y la función de pérdida</h1>
<p>optimizer = optim.Adam(model.parameters(), lr=0.001)<br>
loss_fn = nn.MSELoss()</p>
<h1><a name="p-462759-entrenamiento-10" class="anchor" href="#p-462759-entrenamiento-10"></a>Entrenamiento</h1>
<p>epochs = 1000<br>
for epoch in range(epochs):<br>
model.train()<br>
optimizer.zero_grad()<br>
out = model(data)<br>
loss = sum(loss_fn(out[key], tensiones_reales) for key in out) / len(out)<br>
loss.backward()<br>
optimizer.step()</p>
<pre><code>if (epoch + 1) % 100 == 0:
    print(f'Epoch {epoch + 1}, Loss: {loss.item()}')
</code></pre>
<h1><a name="p-462759-evaluacin-11" class="anchor" href="#p-462759-evaluacin-11"></a>Evaluación</h1>
<p>model.eval()<br>
with torch.no_grad():<br>
prediccion_tensiones = model(data)<br>
print("Tensiones predichas: ", prediccion_tensiones)<br>
print("Tensiones reales: ", tensiones_reales)</p>
<p>Thank you very much for your help and time</p>