Une plongée plus approfondie dans les réseaux de neurones graphiques
Les réseaux de neurones graphes (GNN) sont devenus une architecture d'apprentissage profond puissante pour comprendre des données complexes et interconnectées. Contrairement aux réseaux de neurones traditionnels qui fonctionnent sur des entrées de taille fixe comme les images ou les séquences, les GNN sont conçus pour comprendre les relations qui captent la manière dont 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 fraudes.
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 construit en utilisant 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 sont importantes.
- Les GNN généralisent l'apprentissage profond traditionnel aux formats de graphes, permettant l'apprentissage à partir des nœuds, des arêtes et de leur connectivité.
- Architectures GNN populaires, telles que les réseaux de convolution sur graphes (GCN), les réseaux d'attention sur graphes (GAT) et GraphSAGE, offrent différentes façons d'agréger et de propager l'information à travers les nœuds.
- Les applications réelles 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.
- Mettre en œuvre des GNN est accessible avec les frameworks modernes comme PyTorch Geometric, qui facilite 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 des GNN, incluant 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 améliorant la scalabilité, l'efficacité et la performance dans le traitement de graphes de plus en plus grands et complexes.
Qu'est-ce que les réseaux neuronaux graphiques ?
Les réseaux de neurones graphiques, ou GNN pour faire court, sont un type de réseau de neurones 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 sous forme d’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'intégrations de nœuds pour chaque nœud dans le graphe d'entrée. Ces intégrations représentent les caractéristiques que le réseau a apprises pour chaque nœud. Au lieu de fonctionner uniquement sur des vecteurs, des matrices ou des tenseurs comme un réseau de neurones classique, 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 transmettant 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 pour faire court, 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 à son sujet.
- 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 renvoient leurs propres messages.
- Lorsqu'un nœud reçoit ces messages, il met à jour son état interne en agrégeant toutes les informations entrantes.
- Ce passage répété de messages permet au savoir de circuler à travers le graphe, permettant aux nœuds d'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 plus profondes.
- À chaque couche ajoutée, le modèle construit des représentations de caractéristiques du graphe plus riches et plus significatives.
Implémenter un réseau de neurones graphes dans PyTorch
Jeu de données Cora
Le jeu de données Cora est un benchmark populaire utilisé par les chercheurs travaillant sur l'apprentissage de représentation de graphes. Ce jeu de données comprend un ensemble de publications scientifiques réparties en sept catégories comme « Case Based », « Genetic Algorithms », « Neural Networks », « Probabilistic Methods », « Reinforcement Learning » et « Rule Learning ». Le jeu de données Cora existe depuis un certain temps et reste une ressource de référence 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 comme arêtes reliant les nœuds. Chaque document est associé à un vecteur de caractéristiques représentant son contenu. Le défi ici est de 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 destinés à l'entraînement, à la validation et au test.
Architecture du modèle
Lors de la construction d'un réseau de neurones graphes, choisir la bonne architecture de modèle est très important. Nous allons passer en revue une implémentation de base en utilisant la bibliothèque torch_geometric de PyTorch. Nous allons utiliser un réseau de convolution de graphes, 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 de neurones. 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 implementation facile des convolutions de graphes. Nous avons ajouté une couche linéaire simple.
- La propagation avant passe d'abord 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 la log-softmax pour comprimer les sorties.
En quelques lignes de code, nous pouvons construire un joli petit réseau de neurones graphique !
Évidemment, il s'agit d'un exemple simple, mais on peut voir comment PyTorch et PyTorch Geometric nous permettent de prototyper rapidement et d'itérer sur des architectures de réseaux de neurones graphiques. Les couches GCNConv facilitent grandement l'intégration de la structure du graphe dans nos modèles.
Formation
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 cycle complet d'entraînement et renvoie la perte. La fonction de test vérifie comment le modèle performe 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 affiché 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() met le modèle en mode évaluation, effectue une passe 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 été capable de 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 aller plus en profondeur 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 fournissent des informations sur les performances du modèle sur différents aspects, comme l’identification correcte des cas positifs et négatifs et la gestion des ensembles de données déséquilibrés. Donc, même si une précision de 80 % est solide, il serait préférable d’avoir plus de contexte avant de déclarer ce modèle comme un succès retentissant. La métrique de précision seule ne donne pas une image complète de ce qui se passe en interne. Mais c’est un bon point de départ pour évaluer les performances.
Évaluation
Nous pouvons évaluer les performances du GNN en utilisant des métriques comme la précision, le rappel, l’exactitude et le score F1. Mais nous pouvons aussi visualiser les embeddings des nœuds que le modèle apprend en utilisant le 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 qui peut être interprété. Le code utilise t-SNE pour montrer les embeddings de nœuds appris dans un nuage de points en 2D, ce qui est une manière intelligente de visualiser des données à haute dimension. Voyons ce qui se passe :
- Chaque point sur 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 comprimé les embeddings. La couleur de chaque point représente le label réel du nœud correspondant dans l'ensemble de données.
- Les nœuds ayant des embeddings similaires devraient avoir des étiquettes similaires, donc ils se regrouperont sur le graphique. À l’inverse, les nœuds avec des embeddings très différents auront probablement des étiquettes différentes, donc ils seront plus éloignés les uns des autres.
- Dans l'ensemble, le graphe offre 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 similitude sous-jacente. C'est un moyen pratique de jeter un œ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, le jeu de données Cora est considéré comme relativement petit. Cela pourrait limiter l’efficacité du GNN, nécessitant l’adoption de méthodes plus avancées comme l’augmentation de données et l’apprentissage par transfert.
- Le jeu de données Cora se compose d'un seul type de nœud et d'un seul 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, impliquant des types de nœuds et d'arêtes divers.
- 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 la performance du GNN et nécessite un ajustement minutieux.
FAQ
- 1. Qu'est-ce qu'un réseau neuronal de graphes (GNN) ?
Un GNN est un réseau de neurones conçu pour travailler avec des données structurées en graphes. Il apprend des représentations au niveau des nœuds, des arêtes ou du graphe en agrégeant les informations des nœuds voisins.
- 2. En quoi un GNN diffère-t-il d'un réseau neuronal traditionnel ?
Les réseaux traditionnels traitent des données en grille (images, séquences), tandis que les GNN peuvent modéliser des structures irrégulières et interconnectées, comme les réseaux sociaux ou les graphes moléculaires.
- 3. Quels types de problèmes sont traité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 la transmission de messages dans les GNN ?
La transmission de messages est le mécanisme central par lequel les nœuds échangent des informations avec leurs voisins, mettent à jour les embeddings et apprennent les relations contextuelles.
- 5. Les GNNs s'adaptent-ils bien aux très grands graphes ?
La mise à l'échelle peut être difficile en raison de la mémoire et de l'expansion des voisins. Des techniques comme l'échantillonnage (GraphSAGE), le mini-batch 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 prêtes à l'emploi et des utilitaires pour construire des modèles de GNN.
- 7. Les GNN sont-ils adaptés aux applications en temps réel ?
Oui, cela dépend de la complexité du modèle. Les architectures légères et les approches basées sur l'échantillonnage permettent d'atteindre des performances proches du temps réel.
- 8. Les GNN peuvent-ils gérer des graphes dynamiques ou en évolution ?
Oui, les variantes de GNN dynamiques 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éparation 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/aretes 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 examiné les concepts de base 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 des relations complexes présentes dans les réseaux sociaux, les graphes moléculaires, les systèmes de transport, et bien plus encore.
Pour démontrer ces idées en pratique, nous avons utilisé le célèbre ensemble de données Cora, une référence pour l'apprentissage sur les graphes. Dans cet ensemble, 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 graphique, suivi 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 son exactitude.
Bien qu'il existe de nombreuses techniques et améliorations supplémentaires que l'on pourrait explorer, ce projet offre une introduction solide au fonctionnement des 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 du débutant sur les réseaux neuronaux
- Architectures de Deep Learning expliquées : ResNet, InceptionV3, SqueezeNet
- PyTorch 101 : Apprenez le deep learning avec PyTorch
Merci d'apprendre avec la communauté Linux-Console.net.


