Section courante

A propos

Section administrative du site

Ajouter un nouvel encodage positionnel

L'un des principaux avantages de cette bibliothèque est sa capacité à intégrer facilement de nouveaux codages positionnels au niveau des noeuds, des arêtes et des graphes. Les codages positionnels sont calculés et intégrés aux encodeurs respectifs. Les plongements cachés de tous les encodeurs PE sont ensuite regroupés (selon qu'ils soient au niveau des nouds, des arêtes ou des graphes), puis intégrés aux couches GNN sous forme d'entités. Les conceptions permettent d'utiliser n'importe quelle combinaison de codages positionnels en modifiant le fichier de configuration. Pour plus de détails sur le traitement des données, veuillez consulter la page de conception de la documentation.

Voici le flux de travail pour le calcul et le traitement des codages positionnels dans la bibliothèque :

Cette bibliothèque étant construite avec PyG, il est recommandé de consulter leur documentation et leurs tutoriels pour plus d'informations.

Nous commençons par modifier le fichier de configuration.

Modifier le fichier de configuration YAML

Calcul du PE brut

Dans ce tutoriel, nous utiliserons le degré de chaque noeud comme encodage positionnel. Commencez par utiliser un fichier de configuration YAML existant, disponible dans expts/configs.

Nous examinons d'abord où les encodages positionnels bruts sont calculés dans le fichier YAML. deg_pos est ajouté à titre d'exemple ci-dessous. Vous pouvez également ajouter ici des paramètres pertinents pour le calcul de l'encodage positionnel, comme «normalize» dans l'exemple :

  1. pos_encoding_as_features:
  2.     pos_types:
  3.       deg_pos: #exemple, centralité du degré
  4.         pos_type: degree
  5.         normalize: False

Spécification des encodeurs pour le PE

Nous souhaitons maintenant spécifier les paramètres des encodeurs associés au PE :

  1. pe_encoders:
  2.     out_dim: 64
  3.     pool: "sum" #choix de mise en commun sur plusieurs encodeurs pe
  4.     last_norm: None #"batch_norm", "layer_norm"
  5.     encoders: 
  6.       deg_pos: #même nom que dans la cellule précédente
  7.         encoder_type: "mlp" #ou vous pouvez spécifier votre propre encodeur spécialisé
  8.         input_keys: ["degree"] #identique au pos_type configuré auparavant
  9.         output_keys: ["feat"] #fonctionnalité de noeud
  10.         hidden_dim: 64
  11.         num_layers: 1
  12.         dropout: 0.1
  13.         normalization: "none"   #"batch_norm" ou "layer_norm"
  14.         first_normalization: "layer_norm"   #"batch_norm" ou "layer_norm"

Calculer l'encodage positionnel

Nous souhaitons ensuite calculer le degré brut de chaque noeud du graphe moléculaire.

Ajouter une fonction pour calculer le PE

Accédez à graphium/features et ajoutez un nouveau fichier deg.py pour ajouter la fonction de calcul du PE.

  1. from typing import Tuple, Union, Optional
  2.  
  3. from scipy import sparse
  4. from scipy.sparse import spmatrix
  5. import numpy as np
  6.  
  7. def compute_deg(adj: Union[np.ndarray, spmatrix], normalize: bool) -> np.ndarray:
  8.     """
  9.     Calculer le codage positionnel du degré du noeud
  10.  
  11.     Paramètres :
  12.        adj : matrice d'adjacence
  13.        normalize : indique si le degré de tous les noeuds est normalisé à [0,1] ou non
  14.     Retourne :
  15.       Tableau 2D avec une forme (num_nodes, 1) spécifiant le degré (sortant) de chaque noeud
  16.     """
  17.     
  18.     #premier adj converti en matrice creuse scipy si ce n'est pas déjà fait
  19.     if type(adj) is np.ndarray:
  20.         adj = sparse.csr_matrix(adj)
  21.     
  22.     #https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.sum.html
  23.     degs = adj.sum(axis=0) #somme sur chaque ligne
  24.     
  25.     if (normalize): #normaliser la séquence de degrés à [0,1]
  26.         degs = degs / np.max(degs)
  27.     return degs

Test avec une matrice jouet

Nous allons ici tester si notre code calcule correctement les degrés de chaque noeud.

  1. adj = np.identity(5) #créer une matrice d'identité
  2. normalize = True
  3.  
  4. degs = compute_deg(adj, normalize=normalize)
  5.  
  6. degs

on obtiendra un résultat ressemblant à ceci :

matrix([[1., 1., 1., 1., 1.]])

Ajouter à positional_encoding.py

Pour calculer le nouveau PE avec tous les PE existants, nous devons ajouter la fonction que nous avons écrite dans graphium/feature/positional_encoding.py. Modifiez la fonction graph_positional_encoder en ajoutant la logique pos_type == "degree"

Ajouter un encodeur existant

Afin de regrouper tous les encodages positionnels, nous devons ajouter un encodeur pour traiter l'encodage positionnel brut calculé et garantir que la dimension de sortie de tous les encodeurs pe est identique. Lors de la conception de l'encodeur, vous pouvez utiliser un encodeur existant ou créer un encodeur spécialisé.

Ici, il suffit de spécifier MLPEncoder dans le fichier YAML et la bibliothèque transmettra automatiquement l'encodage positionnel brut à un encodeur mlp en fonction des arguments d'entrée. Notez que dans cet exemple, l'encodeur prend en compte le pe stocké au niveau de la clef d'entrée, puis le transmet à la clef de sortie.

  1. encoders: 
  2.   deg_pos: 
  3.     encoder_type: "mlp" 
  4.     input_keys: ["degree"] 
  5.     output_keys: ["feat"] # fonctionnalité de noeud
  6.     hidden_dim: 64
  7.     num_layers: 1
  8.     dropout: 0.1
  9.     normalization: "none"   #"batch_norm" ou "layer_norm"
  10.     first_normalization: "layer_norm"   #"batch_norm" ou "layer_norm"

Ajouter un encodeur spécialisé

Vous pouvez également ajouter un encodeur spécialisé, tel que laplacian_pe, pour les vecteurs propres et les valeurs propres laplaciens. Pour cela, nous pouvons ajouter un nouveau fichier deg_pos_encoder.py dans graphium/nn/encoders. À titre d'exemple et de modèle, veuillez consulter MLPEncoder.

Notez que tous les nouveaux encodeurs doivent être inhérents à la classe BaseEncoder et implémenter les méthodes abstraites suivantes :

Méthode Description
forward Fonction forward de l'encodeur, comment traiter l'entrée
parse_input_keys Comment analyser les clefs d'entrée
parse_output_keys Comment analyser les clefs de sortie

Ajouter les clefs aux espaces

Pour trouver directement les encodeurs corrects dans le fichier YAML, nous devons spécifier quelle clef correspond à quelle classe.

Nous pouvons maintenant modifier le fichier yaml pour utiliser notre nouvel encodeur :

  1. encoders: 
  2.   deg_pos: 
  3.     encoder_type: "deg_pos_encoder" 
  4.     input_keys: ["degree"] 
  5.     output_keys: ["feat"] # fonctionnalité de noeud
  6.     hidden_dim: 64
  7.     #toute autre clef pouvant être utilisée pour l'initialisation


Dernière mise à jour : Samedi, le 4 janvier 2025