Course
Introducción completa a las redes neuronales gráficas (GNN)
¿Qué es un gráfico?
Un grafo es un tipo de estructura de datos que contiene nodos y aristas. Un nodo puede ser una persona, un lugar o una cosa, y las aristas definen la relación entre nodos. Las aristas pueden ser dirigidas y no dirigidas en función de las dependencias direccionales.
En el ejemplo siguiente, los círculos azules son nodos y las flechas son aristas. La dirección de las aristas define las dependencias entre dos nodos.
Imagen del autor
Conozcamos el complejo conjunto de datos Graph: Jazz Musicians Network. Contiene 198 nodos y 2742 aristas. En el gráfico de comunidades que se muestra a continuación, los nodos de distintos colores representan varias comunidades de músicos de jazz y los bordes que las conectan. Existe una red de colaboración en la que un solo músico mantiene relaciones dentro y fuera de la comunidad.
Gráfico comunitario de Jazz Musicians Network
Los gráficos son excelentes para tratar problemas complejos con relaciones e interacciones. Se utilizan en el reconocimiento de patrones, el análisis de redes sociales, los sistemas de recomendación y el análisis semántico. La creación de soluciones basadas en grafos es un campo completamente nuevo que ofrece una visión enriquecedora de conjuntos de datos complejos e interrelacionados.
Gráficos con NetworkX
En esta sección, aprenderemos a crear un gráfico utilizando NetworkX.
El código de abajo está influenciado por el blog de Daniel Holmberg sobre Graph Neural Networks in Python.
- Crear el objeto DiGraph "H" de networkx
- Añadir nodos con etiquetas, colores y tamaños diferentes
- Añade aristas para crear una relación entre dos nodos. Por ejemplo, "(0,1)" significa que 0 tiene una dependencia direccional con respecto a 1. Crearemos relaciones bidireccionales añadiendo "(1,0)"
- Extraer colores y tamaños en forma de listas
- Traza el gráfico utilizando la función draw de networkx
import networkx as nx
H = nx.DiGraph()
#adding nodes
H.add_nodes_from([
(0, {"color": "blue", "size": 250}),
(1, {"color": "yellow", "size": 400}),
(2, {"color": "orange", "size": 150}),
(3, {"color": "red", "size": 600})
])
#adding edges
H.add_edges_from([
(0, 1),
(1, 2),
(1, 0),
(1, 3),
(2, 3),
(3,0)
])
node_colors = nx.get_node_attributes(H, "color").values()
colors = list(node_colors)
node_sizes = nx.get_node_attributes(H, "size").values()
sizes = list(node_sizes)
#Plotting Graph
nx.draw(H, with_labels=True, node_color=colors, node_size=sizes)
En el siguiente paso, convertiremos la estructura de datos de direccional a un grafo no direccional utilizando la función to_undirected().
#converting to undirected graph
G = H.to_undirected()
nx.draw(G, with_labels=True, node_color=colors, node_size=sizes)
¿Por qué es difícil analizar un gráfico?
Las estructuras de datos basadas en grafos tienen inconvenientes, y los científicos de datos deben comprenderlos antes de desarrollar soluciones basadas en grafos.
- Un grafo existe en un espacio no euclidiano. No existe en el espacio 2D o 3D, lo que dificulta la interpretación de los datos. Para visualizar la estructura en el espacio 2D, hay que utilizar varias herramientas de reducción de la dimensionalidad.
- Los gráficos son dinámicos; no tienen una forma fija. Puede haber dos grafos visualmente diferentes, pero con representaciones de matrices de adyacencia similares. Esto dificulta el análisis de los datos con las herramientas estadísticas tradicionales.
- Un tamaño y una dimensionalidad grandes aumentarán la complejidad del gráfico para las interpretaciones humanas. La estructura densa con múltiples nodos y miles de aristas es más difícil de comprender y extraer información.
¿Qué es una red neuronal gráfica (GNN)?
Las redes neuronales gráficas son tipos especiales de redes neuronales capaces de trabajar con una estructura de datos gráfica. Están muy influidas por las redes neuronales convolucionales (CNN) y la incrustación de grafos. Las GNN se utilizan en la predicción de nodos, aristas y tareas basadas en grafos.
- Las CNN se utilizan para la clasificación de imágenes. Del mismo modo, las GNN se aplican a la estructura de grafos (cuadrícula de píxeles) para predecir una clase.
- Las redes neuronales de recurrencia se utilizan en la clasificación de textos. Del mismo modo, las GNN se aplican a estructuras gráficas en las que cada palabra es un nodo de una frase.
Las GNN se introdujeron cuando las redes neuronales convolucionales no consiguieron resultados óptimos debido al tamaño arbitrario del grafo y a su compleja estructura.
Imagen de Purvanshi Mehta
El gráfico de entrada pasa por una serie de redes neuronales. La estructura del grafo de entrada se convierte en incrustación de grafos, lo que nos permite mantener la información sobre nodos, aristas y contexto global.
A continuación, el vector de características de los nodos A y C pasa por la capa de la red neuronal. Agrega estas características y las pasa a la siguiente capa: neptune.ai.
Lea nuestro tutorial sobre aprendizaje profundo o realice nuestro curso Introducción al aprendizaje profundo para obtener más información sobre algoritmos y aplicaciones de aprendizaje profundo.
Tipos de redes neuronales gráficas
Existen varios tipos de redes neuronales, y la mayoría de ellas presentan alguna variación de las redes neuronales convolucionales. En esta sección conoceremos las GNN más populares.
- Lasredes convolucionales gráficas (GCN ) son similares a las CNN tradicionales. Aprende las características inspeccionando los nodos vecinos. Las GNN agregan los vectores de los nodos, pasan el resultado a la capa densa y aplican la no linealidad mediante la función de activación. En resumen, consta de convolución gráfica, capa lineal y función de activación sin aprendizaje. Existen dos tipos principales de GCN: Redes convolucionales espaciales y redes convolucionales espectrales.
- Las redes de autocodificación de grafos aprenden la representación de grafos mediante un codificador e intentan reconstruir los grafos de entrada con un decodificador. El codificador y los descodificadores están unidos por una capa cuello de botella. Se suelen utilizar en la predicción de enlaces, ya que los Auto-Encoders son buenos a la hora de tratar el equilibrio de clases.
- Las redes neuronales de grafos recurrentes (RGNN ) aprenden el mejor patrón de difusión y pueden manejar grafos multirrelacionales en los que un único nodo tiene múltiples relaciones. Este tipo de red neuronal gráfica utiliza regularizadores para aumentar la suavidad y eliminar la sobreparametrización. Las RGNN utilizan menos potencia de cálculo para producir mejores resultados. Se utilizan en la generación de textos, la traducción automática, el reconocimiento de voz, la generación de descripciones de imágenes, el etiquetado de vídeos y el resumen de textos.
- Las redes neuronales de grafos cerrados (GGNN ) son mejores que las RGNN en la realización de tareas con dependencias a largo plazo. Las redes neuronales gráficas con compuertas mejoran las redes neuronales gráficas recurrentes añadiendo un nodo, una arista y compuertas temporales en las dependencias a largo plazo. De forma similar a las unidades recurrentes con compuerta (GRU), las compuertas se utilizan para recordar y olvidar información en diferentes estados.
Si está interesado en aprender más sobre las redes neuronales recurrentes (RNN), consulte el curso de DataCamp. Le presentará varias arquitecturas de modelos RNNs, marcos Keras y aplicaciones RNN.
Tipos de redes neuronales gráficas Tareas
A continuación, hemos esbozado algunos de los tipos de tareas GNN con ejemplos:
- Clasificación de grafos: se utiliza para clasificar los grafos en varias categorías. Sus aplicaciones son el análisis de redes sociales y la clasificación de textos.
- Clasificación de nodos: esta tarea utiliza etiquetas de nodos vecinos para predecir las etiquetas de nodos que faltan en un grafo.
- Predicción de enlaces: predice el enlace entre un par de nodos en un grafo con una matriz de adyacencia incompleta. Se utiliza habitualmente para las redes sociales.
- Detección de comunidades: divide los nodos en varios clusters basándose en la estructura de los bordes. Aprende de los pesos de las aristas, y de la distancia y los objetos del grafo de forma similar.
- Incrustación de grafos: mapea los grafos en vectores, preservando la información relevante sobre nodos, aristas y estructura.
- Generación de grafos: aprende de la distribución de grafos de muestra para generar una estructura de grafos nueva pero similar.
Imagen del autor
Desventajas de las redes neuronales gráficas
El uso de GNN presenta algunos inconvenientes. Comprenderlos nos ayudará a determinar cuándo utilizar GNNa y cómo optimizar el rendimiento de nuestros modelos de aprendizaje automático.
- La mayoría de las redes neuronales pueden hacerse profundas para obtener un mejor rendimiento, mientras que las GNN son redes poco profundas, en su mayoría de tres capas. Nos limita a la hora de alcanzar el rendimiento más avanzado en grandes conjuntos de datos.
- Las estructuras gráficas cambian constantemente, lo que dificulta el entrenamiento de un modelo.
- El despliegue del modelo a la producción se enfrenta a problemas de escalabilidad, ya que estas redes son costosas desde el punto de vista computacional. Si tienes una estructura de grafos grande y compleja, te resultará difícil escalar las GNN en producción.
¿Qué es una red convolucional gráfica (GCN)?
La mayoría de las GNN son redes convolucionales gráficas, y es importante aprender sobre ellas antes de saltar a un tutorial de clasificación de nodos.
La convolución en GCN es la misma que en las redes neuronales convolucionales. Multiplica las neuronas con pesos (filtros) para aprender de las características de los datos.
Actúa como ventanas deslizantes en imágenes enteras para aprender características de las celdas vecinas. El filtro utiliza el reparto de pesos para aprender varios rasgos faciales en sistemas de reconocimiento de imágenes - Hacia la Ciencia de Datos.
Transfiera ahora la misma funcionalidad a las redes convolucionales gráficas, en las que un modelo aprende las características de los nodos vecinos. La principal diferencia entre GCN y CNN es que está desarrollada para trabajar con estructuras de datos no euclidianas en las que el orden de los nodos y las aristas puede variar.
CNN vs GCN | Fuente de la imagen
Aprende más sobre las CNN básicas siguiendo el tutorial Redes Neuronales Convolucionales (CNN) con TensorFlow.
Existen dos tipos de GCN:
- Las redes convolucionales de grafos espa ciales utilizan características espaciales para aprender de grafos situados en el espacio espacial.
- Las redes convolucionales de grafos espectrales utilizan la descomposición propia de la matriz laplaciana del grafo para la propagación de la información a lo largo de los nodos. Estas redes se inspiran en la propagación de ondas en señales y sistemas.
¿Cómo funcionan los GNN? Creación de una red neuronal gráfica con Pytorch
Construiremos y entrenaremos la Convolución Espectral de Grafos para un modelo de clasificación de nodos. El código fuente está disponible en este libro de trabajo de DataLab para que experimentes y ejecutes tu primer modelo de aprendizaje automático basado en gráficos.
Los ejemplos de codificación están influenciados por la documentación geométrica de Pytorch.
Primeros pasos
Instalaremos el paquete Pytorch, ya que pytorch_geometric se basa en él.
!pip install -q torch
A continuación, utilizaremos la versión torch para instalar torch-scatter y torch-sparse. Después, instalaremos la última versión de pytorch_geometricdesde GitHub.
%%capture
import os
import torch
os.environ['TORCH'] = torch.__version__
os.environ['PYTHONWARNINGS'] = "ignore"
!pip install torch-scatter -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install torch-sparse -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install git+https://github.com/pyg-team/pytorch_geometric.git
Planetoid Cora Dataset
Planetoid es un conjunto de datos de redes de citas de Cora, CiteSeer y PubMed. Los nodos son documentos con vectores de características de 1433 dimensiones y los bordes son enlaces de citas entre artículos de investigación. Hay 7 clases, y entrenaremos el modelo para predecir las etiquetas que faltan.
Tomaremos el conjunto de datos Planetoid Cora y normalizaremos en filas las características de entrada de la bolsa de palabras. A continuación, analizaremos el conjunto de datos y el primer objeto gráfico.
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures
dataset = Planetoid(root='data/Planetoid', name='Cora', transform=NormalizeFeatures())
print(f'Dataset: {dataset}:')
print('======================')
print(f'Number of graphs: {len(dataset)}')
print(f'Number of features: {dataset.num_features}')
print(f'Number of classes: {dataset.num_classes}')
data = dataset[0] # Get the first graph object.
print(data)
El conjunto de datos Cora tiene 2708 nodos, 10.556 aristas, 1433 características y 7 clases. El primer objeto tiene 2708 máscaras de entrenamiento, validación y prueba. Utilizaremos estas máscaras para entrenar y evaluar el modelo.
Dataset: Cora():
======================
Number of graphs: 1
Number of features: 1433
Number of classes: 7
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])
Clasificación de nodos con GNN
Crearemos una estructura de modelo GCN que contenga dos capas GCNConv activación relu y una tasa de abandono de 0,5. El modelo consta de 16 canales ocultos.
Capa GCN:
La W(ℓ+1) es una matriz de pesos transable en la ecuación anterior y Cw,v donestes a un coeficiente de normalización fijo para cada arista.
from torch_geometric.nn import GCNConv
import torch.nn.functional as F
class GCN(torch.nn.Module):
def __init__(self, hidden_channels):
super().__init__()
torch.manual_seed(1234567)
self.conv1 = GCNConv(dataset.num_features, hidden_channels)
self.conv2 = GCNConv(hidden_channels, dataset.num_classes)
def forward(self, x, edge_index):
x = self.conv1(x, edge_index)
x = x.relu()
x = F.dropout(x, p=0.5, training=self.training)
x = self.conv2(x, edge_index)
return x
model = GCN(hidden_channels=16)
print(model)
>>> GCN(
(conv1): GCNConv(1433, 16)
(conv2): GCNConv(16, 7)
)
Visualización de la red GCN no entrenada
Vamos a visualizar las incrustaciones de nodos de redes GCN no entrenadas utilizando sklearn.manifold.TSNE y matplotlib.pyplot. Trazará un nodo de 7 dimensiones incrustando un gráfico de dispersión 2D.
%matplotlib inline
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
def visualize(h, color):
z = TSNE(n_components=2).fit_transform(h.detach().cpu().numpy())
plt.figure(figsize=(10,10))
plt.xticks([])
plt.yticks([])
plt.scatter(z[:, 0], z[:, 1], s=70, c=color, cmap="Set2")
plt.show()
Evaluaremos el modelo y, a continuación, añadiremos datos de entrenamiento al modelo no entrenado para visualizar varios nodos y categorías.
model.eval()
out = model(data.x, data.edge_index)
visualize(out, color=data.y)
Formación GNN
Entrenaremos nuestro modelo en 100 épocas utilizando la optimización de Adam y la función de pérdida de entropía cruzada.
En la función tren, tenemos:
- Borrar el degradado
- Realización de un único pase hacia delante
- Calcular la pérdida utilizando los nodos de entrenamiento
- Calcular el gradiente y actualizar los parámetros
En la función de prueba, tenemos:
- Clase de nodo previsto
- Etiqueta de clase extraída con la mayor probabilidad
- Comprobado cuántos valores se han predicho correctamente
- Crear un ratio de precisión utilizando una suma de predicciones correctas dividida por un número total de nodos.
model = GCN(hidden_channels=16)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
criterion = torch.nn.CrossEntropyLoss()
def train():
model.train()
optimizer.zero_grad()
out = model(data.x, data.edge_index)
loss = criterion(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
return loss
def test():
model.eval()
out = model(data.x, data.edge_index)
pred = out.argmax(dim=1)
test_correct = pred[data.test_mask] == data.y[data.test_mask]
test_acc = int(test_correct.sum()) / int(data.test_mask.sum())
return test_acc
for epoch in range(1, 101):
loss = train()
print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}')
GAT(
(conv1): GATConv(1433, 8, heads=8)
(conv2): GATConv(64, 7, heads=8)
)
.. .. .. ..
.. .. .. ..
Epoch: 098, Loss: 0.5989
Epoch: 099, Loss: 0.6021
Epoch: 100, Loss: 0.5799
Evaluación de modelos
Ahora evaluaremos el modelo en un conjunto de datos no visto utilizando la función de prueba y, como puede ver, obtuvimos unos resultados bastante buenos con una precisión del 81,5%.
test_acc = test()
print(f'Test Accuracy: {test_acc:.4f}')
>>> Test Accuracy: 0.8150
Ahora visualizaremos la incrustación de salida de un modelo entrenado para verificar los resultados.
model.eval()
out = model(data.x, data.edge_index)
visualize(out, color=data.y)
Como podemos ver, el modelo entrenado ha producido una mejor agrupación de nodos para la misma categoría.
Formación del modelo GATConv
En la segunda, sustituiremos las capas GCNConv por GATConv. Graph Attention Networks utiliza capas autoatencionales enmascaradas para solucionar los inconvenientes de GCNConv y lograr resultados de vanguardia.
También puede probar otras capas GNN y jugar con optimizaciones, abandonos y un número de canales ocultos para lograr un mejor rendimiento.
En el código siguiente, acabamos de sustituir GCNConv por GATConv con 8 cabezas de atención en la primera capa y 1 en la segunda capa.
También fijaremos:
- tasa de abandono escolar al 0,6
- canales ocultos a 8
- tasa de aprendizaje 0,005
Hemos modificado la función de prueba para encontrar la precisión de una máscara específica (válida, prueba). Nos ayudará a imprimir las puntuaciones de validación y prueba durante el entrenamiento del modelo. También almacenamos los resultados de la validación y las pruebas en un gráfico de líneas de trazado posterior.
from torch_geometric.nn import GATConv
class GAT(torch.nn.Module):
def __init__(self, hidden_channels, heads):
super().__init__()
torch.manual_seed(1234567)
self.conv1 = GATConv(dataset.num_features, hidden_channels,heads)
self.conv2 = GATConv(heads*hidden_channels, dataset.num_classes,heads)
def forward(self, x, edge_index):
x = F.dropout(x, p=0.6, training=self.training)
x = self.conv1(x, edge_index)
x = F.elu(x)
x = F.dropout(x, p=0.6, training=self.training)
x = self.conv2(x, edge_index)
return x
model = GAT(hidden_channels=8, heads=8)
print(model)
optimizer = torch.optim.Adam(model.parameters(), lr=0.005, weight_decay=5e-4)
criterion = torch.nn.CrossEntropyLoss()
def train():
model.train()
optimizer.zero_grad()
out = model(data.x, data.edge_index)
loss = criterion(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
return loss
def test(mask):
model.eval()
out = model(data.x, data.edge_index)
pred = out.argmax(dim=1)
correct = pred[mask] == data.y[mask]
acc = int(correct.sum()) / int(mask.sum())
return acc
val_acc_all = []
test_acc_all = []
for epoch in range(1, 101):
loss = train()
val_acc = test(data.val_mask)
test_acc = test(data.test_mask)
val_acc_all.append(val_acc)
test_acc_all.append(test_acc)
print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, Val: {val_acc:.4f}, Test: {test_acc:.4f}')
.. .. .. ..
.. .. .. ..
Epoch: 098, Loss: 1.1283, Val: 0.7960, Test: 0.8030
Epoch: 099, Loss: 1.1352, Val: 0.7940, Test: 0.8050
Epoch: 100, Loss: 1.1053, Val: 0.7960, Test: 0.8040
Como podemos observar, nuestro modelo no obtuvo mejores resultados que GCNConv. Requiere la optimización de hiperparámetros o más épocas para lograr resultados de vanguardia.
Evaluación de modelos
En la parte de evaluación, visualizamos las puntuaciones de validación y prueba utilizando el gráfico de líneas de matplotlib.pyplot .
import numpy as np
plt.figure(figsize=(12,8))
plt.plot(np.arange(1, len(val_acc_all) + 1), val_acc_all, label='Validation accuracy', c='blue')
plt.plot(np.arange(1, len(test_acc_all) + 1), test_acc_all, label='Testing accuracy', c='red')
plt.xlabel('Epochs')
plt.ylabel('Accurarcy')
plt.title('GATConv')
plt.legend(loc='lower right', fontsize='x-large')
plt.savefig('gat_loss.png')
plt.show()
Tras 60 épocas, la precisión de validación y prueba ha alcanzado un valor estable de 0,8+/-0,02.
De nuevo, visualicemos la agrupación de nodos del modelo GATConv.
model.eval()
out = model(data.x, data.edge_index)
visualize(out, color=data.y)
Como podemos ver, la capa GATConv ha producido los mismos resultados en la agrupación en la misma categoría de nodos.
Podemos reducir el sobreajuste añadiendo un segundo conjunto de datos de validación y mejorar el rendimiento del modelo experimentando con varias capas GCN de pytoch_geometric.
El código fuente del tutorial está disponible en este libro de trabajo de DataLab. Cree una copia del libro de trabajo que pueda ejecutar.
Añade la habilidad de Aprendizaje Profundo a tu currículum realizando el curso de habilidad de Aprendizaje Profundo en Python. Te introducirá en los algoritmos de aprendizaje profundo, Keras, Pytorch y el framework Tensorflow.
Preguntas frecuentes
¿Para qué sirven las redes neuronales gráficas?
Las redes neuronales de grafos se aplican directamente a conjuntos de datos de grafos y se pueden entrenar para predecir nodos, aristas y tareas relacionadas con los grafos. Se utiliza para la clasificación de grafos y nodos, la predicción de enlaces, la agrupación y generación de grafos y la clasificación de imágenes y textos.
¿Qué es un gráfico en una red neuronal gráfica?
Un grafo es una estructura de datos formada por nodos cuyas conexiones se denominan aristas. Las aristas pueden ser dirigidas y no dirigidas. Tiene formas dinámicas y estructuras multidimensionales. Por ejemplo, en las redes sociales, los nodos son las personas de tu grupo de amigos, y las aristas son las relaciones entre unos y otros.
¿Qué potencia tienen las redes neuronales gráficas?
Las redes neuronales gráficas superan a las redes neuronales convolucionales (CNN) típicas en la clasificación de imágenes y nodos. Muchas variantes de GNN han obtenido resultados punteros tanto en tareas de clasificación de nodos como de grafos - openreview.net.
¿Utilizan las redes neuronales la teoría de grafos?
Sí, las redes neuronales están estrechamente relacionadas con la teoría de grafos, diseñada para trabajar con datos no euclidianos. Algunos de ellos son gráficos en sí mismos o dan salida al gráfico.
¿Qué son las redes convolucionales gráficas?
Las redes convolucionales gráficas son similares a las redes neuronales convolucionales que trabajan con conjuntos de datos gráficos. Consta de convolución gráfica, capa lineal y activación no lineal. Las GNN pasan filtros sobre el grafo, inspeccionando nodos y aristas que pueden utilizarse para clasificar nodos dentro de los datos.
¿Qué es un gráfico en el aprendizaje profundo?
El Graph Deep Learning se conoce como Geometric Deep Learning. Utiliza múltiples capas de red neuronal para lograr un mejor rendimiento. Se trata de un campo de investigación activo en el que los científicos intentan aumentar el número de capas sin comprometer el rendimiento.
Cursos de Python
Course
Recurrent Neural Networks (RNNs) for Language Modeling with Keras
Course
Introduction to Deep Learning with PyTorch
blog
¿Qué es un modelo generativo?
tutorial
Introducción a las redes neuronales profundas
tutorial
Introducción a las redes neuronales convolucionales (CNN)
tutorial
Creación de modelos de redes neuronales (NN) en R
tutorial
Ajuste fino de GPT-3 mediante la API OpenAI y Python
tutorial