Une exploration approfondie des réseaux de neurones graphiques
Les réseaux de neurones graphiques (GNNs) sont devenus une architecture de deep learning puissante pour interpréter des données complexes et interconnectées. Contrairement aux réseaux de neurones traditionnels qui fonctionnent sur des entrées de taille fixe comme des images ou des séquences, les GNNs sont conçus pour comprendre les relations qui captent comment les entités se connectent, s'influencent et interagissent au sein d'un graphe. Cela les rend particulièrement précieux dans les domaines où la structure est importante, allant des réseaux sociaux et de la chimie moléculaire aux moteurs de recommandation et à la détection de fraude.
Dans cet article, nous allons décomposer les idées principales derrière les GNN, explorer leur évolution et mettre en lumière les défis réels qu'ils aident à résoudre. Vous apprendrez également comment les GNN sont mis en œuvre en pratique, avec un exemple concret réalisé à l'aide de la bibliothèque PyTorch.
Points clés à retenir
- Les réseaux de neurones graphiques (GNN) sont excellents pour modéliser les relations au sein de données interconnectées, ce qui les rend idéaux pour les tâches où la structure et les dépendances ont de l'importance.
- Les GNN généralisent l'apprentissage profond traditionnel aux formats de graphes, permettant d'apprendre à partir des nœuds, des arêtes et de leur connectivité.
- Architectures GNN populaires, telles que les réseaux de neurones convolutionnels graphiques (GCN), les réseaux d'attention graphiques (GAT) et GraphSAGE, offrent différentes façons d'agréger et de propager l'information entre les nœuds.
- Les applications concrètes des GNN couvrent l'analyse des réseaux sociaux, la prédiction des propriétés moléculaires, les systèmes de recommandation, la détection de fraude et les graphes de connaissances.
- La mise en œuvre des GNN est accessible grâce aux frameworks modernes comme PyTorch Geometric, qui simplifient la gestion des données, le passage de messages et la construction de modèles.
- Une mise en œuvre pratique démontre le flux de travail du GNN, y compris le chargement des données de graphe, la définition d’un modèle, l’entraînement et l’évaluation des résultats.
- Les GNN continuent d'évoluer rapidement, avec des avancées qui améliorent la scalabilité, l'efficacité et la performance dans la gestion de graphes de plus en plus grands et complexes.
Qu'est-ce que les réseaux de neurones graphiques ?
Les réseaux neuronaux graphiques, ou GNN pour faire court, sont un type de réseau neuronal relativement récent qui peut travailler avec des données structurées sous forme de graphes. Les graphes sont essentiellement un ensemble d’objets, représentés sous forme de nœuds, et les relations entre ces objets, représentées par des arêtes reliant les nœuds, et les GNN peuvent gérer à la fois des graphes dirigés, où les arêtes ont une direction, et des graphes non dirigés, où les arêtes n’ont pas de direction spécifique. Ces graphes peuvent également varier considérablement en taille et en forme. L’architecture d’un GNN se compose de plusieurs couches, chacune prenant des informations de la couche précédente. Nous alimentons le GNN avec un graphe représenté sous forme d’un ensemble de nœuds et d’arêtes, ainsi que leurs caractéristiques associées. Ce que nous obtenons est un ensemble d'embeddings de nœuds pour chaque nœud dans le graphe d'entrée. Ces embeddings représentent les caractéristiques que le réseau a apprises pour chaque nœud. Au lieu de simplement travailler avec des vecteurs, des matrices ou des tenseurs comme un réseau neuronal normal, les GNN peuvent travailler avec des données structurées sous forme de graphes complets. Cela les rend vraiment flexibles pour travailler avec des données en réseau, comme les réseaux sociaux, les structures moléculaires ou les systèmes de transport. Les mathématiques impliquées sont complexes, mais l'idée générale est qu'ils parcourent le graphe en faisant passer des messages entre les nœuds pour apprendre des représentations utiles.
Comment fonctionnent les réseaux de neurones graphiques ?
Les réseaux de neurones graphiques, ou GNN en abrégé, consistent à apprendre les motifs entre les nœuds d'un réseau. L'idée principale est que chaque nœud envoie des messages à ses nœuds voisins, partageant des informations sur lui-même.
- Dans un GNN, chaque nœud échange des informations avec les nœuds auxquels il est connecté, ce qui aide le modèle à comprendre progressivement la structure complète du graphe.
- Chaque nœud crée un « message » en utilisant ses propres caractéristiques et celles de ses nœuds voisins.
- En même temps, les nœuds voisins génèrent et envoient leurs propres messages en retour.
- Lorsqu'un nœud reçoit ces messages, il met à jour son état interne en agrégeant toutes les informations reçues.
- Ce passage répété de messages permet à la connaissance de circuler à travers le graphe, laissant les nœuds apprendre des parties du graphe au-delà de leurs voisins immédiats.
- En empilant plusieurs couches de ce processus, les GNN peuvent apprendre des relations plus complexes et profondes.
- À chaque couche ajoutée, le modèle construit des représentations de caractéristiques du graphe plus riches et plus significatives.
Implémentation d'un réseau de neurones graphe dans PyTorch
Jeu de données Cora
Le jeu de données Cora est une référence populaire utilisée par les chercheurs travaillant sur l'apprentissage de représentations de graphes. Ce jeu de données comprend un ensemble de publications scientifiques réparties en sept catégories telles que « Étude de cas », « Algorithmes génétiques », « Réseaux de neurones », « Méthodes probabilistes », « Apprentissage par renforcement » et « Apprentissage par règles ». Le jeu de données Cora existe depuis un certain temps et reste une ressource incontournable pour de nombreux projets dans ce domaine. Il permet d'évaluer l'efficacité de votre modèle à analyser à la fois le contenu textuel des documents et le réseau interconnecté de citations entre eux. De nombreux articles remarquables sur les réseaux de neurones graphiques ont utilisé Cora pour évaluer les performances sur ces deux tâches. Il est construit comme un graphe avec les publications en tant que nœuds et les citations entre elles en tant qu'arêtes reliant les nœuds. Chaque document est associé à un vecteur de caractéristiques représentant son contenu. Le défi ici consiste à développer un modèle capable d'examiner le graphe de citations, les vecteurs de contenu et les relations entre eux afin de prédire à laquelle des sept classes appartient une publication donnée.
Prétraitement des données
Nous installons la bibliothèque PyTorch Geometric avec la commande :
pip install torch_geometricNous pouvons ensuite utiliser la bibliothèque PyTorch Geometric pour charger et prétraiter le jeu de données.
from torch_geometric.datasets import Planetoid
import torch_geometric.transforms as T
dataset = Planetoid(root='data/Cora', name='Cora', transform=T.NormalizeFeatures())La classe Planetoid charge le jeu de données Cora et normalise les vecteurs de caractéristiques. Nous pouvons obtenir les données prétraitées à l'aide du jeu de données, ce qui nous donne un objet Data avec ces attributs :
- x : une matrice de caractéristiques des nœuds de forme « (num_nodes, num_features) »
- edge_index : matrice de connectivité des arêtes de forme « (2, num_edges) »
- y : un vecteur d’étiquettes de nœuds de forme « (num_nodes) »
- train_mask, val_mask, test_mask : masques booléens indiquant quels nœuds sont utilisés pour l'entraînement, la validation et le test.
Architecture du modèle
Lors de la construction d'un réseau neuronal graphique, choisir la bonne architecture de modèle est extrêmement important. Nous allons passer en revue une implémentation de base en utilisant la bibliothèque torch_geometric de PyTorch. Nous utiliserons un réseau de convolution graphique, qui constitue un point de départ solide pour diverses tâches d'apprentissage sur les graphes.
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
class GNN(torch.nn.Module):
def __init__(self, in_channels, hidden_channels, out_channels):
super(GNN, self).__init__()
# Define the first graph convolutional layer
self.conv1 = GCNConv(in_channels, hidden_channels)
# Define the second graph convolutional layer
self.conv2 = GCNConv(hidden_channels, out_channels)
# Define the linear layer
self.linear = torch.nn.Linear(out_channels, out_channels)
def forward(self, x, edge_index):
# Apply the first graph convolutional layer
x = self.conv1(x, edge_index)
# Apply the ReLU activation function
x = F.relu(x)
# Apply the second graph convolutional layer
x = self.conv2(x, edge_index)
# Apply the ReLU activation function
x = F.relu(x)
# Apply the linear layer
x = self.linear(x)
# Apply the log softmax activation function
return F.log_softmax(x, dim=1)- Dans le code ci-dessus, nous avons importé torch et torch.nn.functional pour accéder à certains modules et fonctions utiles pour les réseaux neuronaux. Ensuite, nous avons défini une classe GNN héritant de torch et nn.Module.
- Dans la méthode init, nous avons défini deux couches convolutionnelles en utilisant le module GCNConv de PyTorch Geometric. Cela permet une mise en œuvre facile des convolutions sur les graphes. Nous avons ajouté une simple couche linéaire.
- La propagation avant fait d'abord passer l'entrée à travers les deux couches convolutionnelles, en appliquant à chaque fois l'activation ReLU. Ensuite, elle passe par la couche linéaire et enfin par le log softmax pour comprimer les sorties.
En quelques lignes de code, nous pouvons créer un joli petit réseau de neurones graphique !
Évidemment, il s'agit d'un exemple simple, mais nous pouvons voir comment PyTorch et PyTorch Geometric nous permettent de prototyper rapidement et d'itérer sur des architectures de réseaux neuronaux pour graphes. Les couches GCNConv facilitent grandement l'intégration de la structure du graphe dans nos modèles.
Entraînement
Pour l'entraînement, nous utiliserons la perte d'entropie croisée et l'optimiseur Adam. Nous pouvons diviser les données en ensembles d'entraînement, de validation et de test en utilisant ces attributs de masque sur l'objet Data.
# Set the device to CUDA if available, otherwise use CPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Define the GNN model with the specified input, hidden, and output dimensions, and move it to the device
model = GNN(dataset.num_features, 16, dataset.num_classes).to(device)
# Define the Adam optimizer with the specified learning rate and weight decay
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
# Define the training function
def train():
# Set the model to training mode
model.train()
# Zero the gradients of the optimizer
optimizer.zero_grad()
# Perform a forward pass of the model on the training nodes
out = model(dataset.x.to(device), dataset.edge_index.to(device))
# Compute the negative log-likelihood loss on the training nodes
loss = F.nll_loss(out[dataset.train_mask], dataset.y[dataset.train_mask])
# Compute the gradients of the loss with respect to the model parameters
loss.backward()
# Update the model parameters using the optimizer
optimizer.step()
# Return the loss as a scalar value
return loss.item()
# Define the testing function
@torch.no_grad()
def test():
# Set the model to evaluation mode
model.eval()
# Perform a forward pass of the model on all nodes
out = model(dataset.x.to(device), dataset.edge_index.to(device))
# Compute the predicted labels by taking the argmax of the output scores
pred = out.argmax(dim=1)
# Compute the training, validation, and testing accuracies
train_acc = pred[dataset.train_mask].eq(dataset.y[dataset.train_mask]).sum().item() / dataset.train_mask.sum().item()
val_acc = pred[dataset.val_mask].eq(dataset.y[dataset.val_mask]).sum().item() / dataset.val_mask.sum().item()
test_acc = pred[dataset.test_mask].eq(dataset.y[dataset.test_mask]).sum().item() / dataset.test_mask.sum().item()
# Return the accuracies as a tuple
return train_acc, val_acc, test_acc
# Train the model for 500 epochs
for epoch in range(1, 500):
# Perform a single training iteration and get the loss
loss = train()
# Evaluate the model on the training, validation, and testing sets and get the accuracies
train_acc, val_acc, test_acc = test()
# Print the epoch number, loss, and accuracies
print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f}, Test Acc: {test_acc:.4f}')
La fonction d'entraînement effectue un tour complet d'entraînement et renvoie la perte. La fonction de test vérifie comment le modèle fonctionne sur les ensembles d'entraînement, de validation et de test et renvoie l'exactitude. Nous avons entraîné le modèle pendant 500 époques et imprimé les précisions d'entraînement et de test à chaque époque.
Calculer la précision du modèle GNN
Le code ci-dessous définit une fonction pour calculer la précision du modèle sur l'ensemble du jeu de données. La fonction compute_accuracy() passe le modèle en mode évaluation, effectue une propagation avant et prédit les étiquettes pour chaque nœud. Elle compare ces étiquettes prédites avec les étiquettes réelles et calcule le nombre de prédictions correctes. Ensuite, elle divise le nombre de prédictions correctes par le nombre total de nœuds dans le jeu de données pour obtenir le pourcentage de précision.
@torch.no_grad()
def compute_accuracy():
model.eval()
out = model(dataset.x.to(device), dataset.edge_index.to(device))
pred = out.argmax(dim=1)
correct = pred.eq(dataset.y.to(device)).sum().item()
total = dataset.y.shape[0]
accuracy = correct / total
return accuracy
accuracy = compute_accuracy()
print(f"Accuracy: {accuracy:.4f}")Dans ce cas, la précision du modèle sur le jeu de données Cora était de 0,8006. Cela signifie qu'environ 80 % du temps, le modèle a pu prédire correctement l'étiquette de classe. C'est plutôt bien, mais pas parfait. La précision nous donne une vue rapide et globale de la performance du modèle. Mais il faut creuser davantage pour vraiment comprendre où il réussit et où il rencontre des difficultés.
Pour mieux comprendre l’efficacité du modèle, il est recommandé de prendre en compte d’autres métriques d’évaluation telles que la précision, le rappel, le score F1 et la matrice de confusion. Ces métriques permettent d’obtenir des informations sur les performances du modèle dans différents aspects, comme l’identification correcte des cas positifs et négatifs et la gestion des jeux de données déséquilibrés. Ainsi, même si une précision de 80 % est solide, nous aurions besoin de plus de contexte avant de déclarer ce modèle un succès retentissant. La métrique de précision seule ne fournit pas une image complète de ce qui se passe en coulisses. Mais c’est un bon point de départ pour évaluer les performances.
Évaluation
Nous pouvons évaluer les performances du GNN en utilisant des indicateurs comme la précision, la justesse, le rappel et le score F1. Mais nous pouvons aussi visualiser les embeddings des nœuds que le modèle apprend en utilisant t-SNE. Cela prend les embeddings en haute dimension et les projette en 2D, ce qui nous permet de les visualiser.
# Import the necessary libraries
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# Set the model to evaluation mode
model.eval()
# Perform a forward pass of the model on the dataset
out = model(dataset.x.to(device), dataset.edge_index.to(device))
# Apply t-SNE to the output feature matrix to obtain a 2D embedding
emb = TSNE(n_components=2).fit_transform(out.cpu().detach().numpy())
# Create a figure with a specified size
plt.figure(figsize=(10,10))
# Create a scatter plot of the embeddings, color-coded by the true labels
plt.scatter(emb[:,0], emb[:,1], c=dataset.y, cmap='jet')
# Display the plot
plt.show()Remarque : Le lecteur peut exécuter le code ci-dessus. Il affichera un nuage de points interprétable. Le code utilise t-SNE pour montrer les embeddings de nœuds appris dans un nuage de points 2D, ce qui est une manière intelligente de visualiser des données à haute dimension. Voyons ce qui se passe :
- Chaque point dans le graphique représente un nœud dans l'ensemble de données. Les axes x et y sont les deux dimensions dans lesquelles t-SNE a compressé les embeddings. La couleur de chaque point représente l'étiquette réelle du nœud correspondant dans l'ensemble de données.
- Les nœuds qui ont des représentations similaires devraient avoir des étiquettes similaires, donc ils se regrouperont sur le graphique. À l'inverse, les nœuds avec des représentations très différentes auront probablement des étiquettes différentes, donc ils seront plus éloignés les uns des autres.
- Dans l'ensemble, le graphique fournit une représentation claire des relations entre les nœuds en fonction de leurs embeddings appris. On peut voir des groupes se former qui doivent partager une certaine similarité sous-jacente. C'est une manière pratique de jeter un coup d'œil à l'intérieur du modèle et de comprendre comment il organise les concepts.
Défis et considérations potentiels
- Avec 2708 nœuds et 5429 arêtes, l’ensemble de données Cora est considéré comme étant de petite taille. Cela pourrait nuire à l’efficacité du GNN, nécessitant l’adoption de méthodes plus avancées telles que l’augmentation de données et le transfert d’apprentissage.
- Le jeu de données Cora se compose d'un type de nœud et d'un type d'arête, ce qui en fait un réseau homogène. Cela peut limiter l'applicabilité du GNN lorsqu'il est utilisé sur des réseaux plus complexes, qui impliquent différents types de nœuds et d'arêtes.
- La sélection de valeurs appropriées pour les hyperparamètres, tels que le nombre de couches cachées, le nombre d'unités cachées et le taux d'apprentissage, peut avoir un impact significatif sur les performances du GNN et nécessite un ajustement minutieux.
FAQ
- 1. Qu'est-ce qu'un réseau neuronal graphique (GNN) ?
Un GNN est un réseau neuronal conçu pour travailler avec des données structurées en graphe. Il apprend des représentations au niveau des nœuds, des arêtes ou du graphe en agrégant des informations provenant des nœuds voisins.
- 2. En quoi un GNN est-il différent d'un réseau neuronal traditionnel ?
Les réseaux traditionnels gèrent des données en forme de grille (images, séquences), tandis que les GNN peuvent modéliser des structures irrégulières et interconnectées telles que les réseaux sociaux ou les graphes moléculaires.
- 3. Quels types de problèmes sont abordés par les GNN ?
Ils sont couramment utilisés pour la classification de nœuds, la prédiction de liens, la classification de graphes, les recommandations, la détection de fraude et la prédiction des propriétés moléculaires.
- 4. Qu'est-ce que le passage de messages dans les GNN ?
La transmission de messages est le mécanisme central où les nœuds échangent des informations avec leurs voisins, mettent à jour les embeddings et apprennent les relations contextuelles.
- 5. Les GNN s'adaptent-ils bien aux très grands graphes ?
La mise à l’échelle peut être difficile en raison de l’expansion de la mémoire et du voisinage. Des techniques comme l’échantillonnage (GraphSAGE), le mini-batching et l’entraînement distribué aident.
- 6. Quelles bibliothèques de programmation sont les meilleures pour implémenter des GNN ?
Les frameworks populaires incluent PyTorch Geometric (PyG) et Deep Graph Library (DGL), offrant tous deux des couches et des outils prêts à l'emploi pour créer des modèles de GNN.
- 7. Les GNN sont-ils adaptés aux applications en temps réel ?
Oui, selon la complexité du modèle. Les architectures légères et les approches basées sur l'échantillonnage permettent d'atteindre des performances quasi en temps réel.
- 8. Les GNN peuvent-ils gérer des graphes dynamiques ou en évolution ?
Oui, les variantes dynamiques des GNN peuvent traiter des graphes qui évoluent au fil du temps, ce qui est utile pour la prévision du trafic, les recommandations temporelles et la détection d'anomalies.
- 9. Quelle prétraitement des données est nécessaire pour les GNN ?
Vous devez généralement préparer les informations d'adjacence, les caractéristiques des nœuds/arêtes, et vous assurer que le graphe est correctement formaté pour la bibliothèque que vous avez choisie.
- 10. Les GNN sont-ils interprétables ?
L'interprétabilité s'améliore grâce à des outils comme les mécanismes d'attention et GNNExplainer, qui mettent en évidence les nœuds et les arêtes influents.
Conclusion
Dans cet article, nous avons parcouru les concepts fondamentaux des réseaux de neurones graphiques (GNN) et exploré comment ils peuvent être appliqués dans différents domaines. Les GNN sont particulièrement adaptés au traitement des données structurées en graphes, permettant aux modèles de raisonner sur les relations complexes présentes dans les réseaux sociaux, les graphes moléculaires, les systèmes de transport, et plus encore.
Pour démontrer ces idées en pratique, nous avons utilisé le populaire jeu de données Cora — une référence pour l'apprentissage sur les graphes. Dans ce jeu de données, chaque publication est représentée comme un nœud, et les citations entre elles forment les arêtes. Notre objectif était d'utiliser à la fois les caractéristiques textuelles de chaque article et les liens de citation pour prédire sa catégorie.
Nous avons préparé le jeu de données en utilisant la bibliothèque PyTorch Geometric, en normalisant les vecteurs de caractéristiques et en divisant les données en ensembles d'entraînement, de validation et de test. Nous avons ensuite construit un GNN simple en utilisant des couches de convolution de graphes, suivies d'un classificateur linéaire, et l'avons entraîné en utilisant la perte d'entropie croisée avec l'optimiseur Adam. Enfin, nous avons évalué les performances du modèle en mesurant sa précision.
Bien qu'il existe de nombreuses techniques supplémentaires et améliorations que l'on pourrait explorer, ce projet offre une introduction solide à la façon dont fonctionnent les GNN et à leur efficacité pour apprendre à partir de données relationnelles complexes.
Ressources
- Construire des réseaux neuronaux à partir de zéro : Partie 1
- Qu'est-ce que l'apprentissage profond ? Guide pour débutants sur les réseaux neuronaux
- Architectures d'apprentissage profond expliquées : ResNet, InceptionV3, SqueezeNet
- PyTorch 101 : Apprenez l'apprentissage profond avec PyTorch
Merci de apprendre avec la communauté Linux-Console.net.


