En djupare insikt i grafneurala nätverk
Grafneuronätverk (GNNs) har blivit en kraftfull djupinlärningsarkitektur för att förstå komplex, sammanlänkad data. Till skillnad från traditionella neurala nätverk som arbetar med indata av fast storlek, som bilder eller sekvenser, är GNNs utformade för att förstå relationer som fångar hur enheter kopplas samman, påverkar varandra och interagerar inom ett grafnät. Detta gör dem särskilt värdefulla inom områden där struktur spelar roll, från sociala nätverk och molekylkemi till rekommendationssystem och bedrägeribekämpning.
I den här artikeln kommer vi att bryta ner de grundläggande idéerna bakom GNN:er, utforska hur de har utvecklats och lyfta fram de verkliga utmaningar de hjälper till att lösa. Du kommer också att lära dig hur GNN:er implementeras i praktiken, med ett praktiskt exempel byggt med PyTorch-biblioteket.
Viktiga punkter
- Graph Neural Networks (GNNs) fungerar utmärkt för att modellera relationer inom sammankopplad data, vilket gör dem idealiska för uppgifter där struktur och beroenden är viktiga.
- GNN:er generaliserar traditionell djupinlärning till grafformat, vilket möjliggör lärande från noder, kanter och deras kopplingar.
- Populära GNN-arkitekturer, såsom Graph Convolutional Networks (GCNs), Graph Attention Networks (GATs) och GraphSAGE, erbjuder olika sätt att samla och sprida information mellan noder.
- Verkliga tillämpningar av GNNs sträcker sig över analys av sociala nätverk, prediktion av molekylära egenskaper, rekommendationssystem, bedrägeribekämpning och kunskapsgrafer.
- Att implementera GNN:er är tillgängligt med moderna ramverk som PyTorch Geometric, vilket förenklar datahantering, meddelandeflöde och modellkonstruktion.
- En praktisk implementering visar GNN-arbetsflödet, inklusive att ladda grafdata, definiera en modell, träna och utvärdera resultat.
- GNN:er fortsätter att utvecklas snabbt, med framsteg som förbättrar skalbarhet, effektivitet och prestanda vid hantering av allt större och mer komplexa grafer.
Vad är grafneuronätverk?
Grafneuronätverk, eller GNN:er för kort, är en relativt ny typ av neuralt nätverk som kan arbeta med data strukturerad som grafer. Grafer är i princip en samling objekt, representerade som noder, och relationerna mellan dessa objekt, representerade som kanter som förbinder noderna, och GNN:er kan hantera både riktade grafer, där kanterna har en riktning, och oriktade grafer, där kanterna inte har någon specifik riktning. Dessa grafer kan också variera avsevärt i storlek och form. Arkitekturen för ett GNN består av flera lager, där varje lager tar information från det föregående lagret. Vi matar GNN med en graf som representeras som en uppsättning noder och kanter, tillsammans med deras tillhörande egenskaper.
Hur fungerar grafneurala nätverk?
Grafneuronala nätverk, eller GNN:er för kort, handlar om att lära sig mönster mellan noder i ett nätverk. Huvudidén är att varje nod skickar meddelanden till sina närliggande noder och delar information om sig själv.
- I en GNN utbyter varje nod information med de noder den är kopplad till, vilket hjälper modellen att gradvis förstå hela grafstrukturen.
- Varje nod skapar ett "meddelande" med sina egna egenskaper och egenskaperna hos sina närliggande noder.
- Samtidigt genererar och skickar närliggande noder sina egna meddelanden tillbaka.
- När en nod tar emot dessa meddelanden uppdaterar den sitt interna tillstånd genom att samla all inkommande information.
- Detta upprepade meddelandeutbyte gör att kunskap kan flöda genom grafen, vilket gör att noder kan lära sig om delar av grafen bortom sina närmaste grannar.
- Genom att stapla flera lager av denna process kan GNN:er lära sig mer komplexa och djupare samband.
- Med varje tillagd lager bygger modellen rikare och mer meningsfulla funktionsrepresentationer av grafen.
Att implementera ett grafneuronätverk i PyTorch
Cora-dataset
Cora-datasetet är en populär benchmark som används av forskare som arbetar med grafrepresentationinlärning. Detta dataset innehåller en mängd vetenskapliga publikationer indelade i sju kategorier som "Case Based", "Genetic Algorithms", "Neural Networks", "Probabilistic Methods", "Reinforcement Learning" och "Rule Learning." Cora-datasetet har funnits under en tid och förblir en resurs som många projekt inom detta område återkommer till. Det ger ett sätt att utvärdera hur effektivt din modell kan analysera både textinnehållet i dokumenten och det sammankopplade nätverket av citat mellan dem. Många betydande artiklar om grafneurala nätverk har använt Cora för att utvärdera prestanda på dessa dubbla uppgifter. Den är uppbyggd som en graf med publikationerna som noder och citeringar mellan dem som kanter som förbinder noderna. Varje dokument är kopplat till en funktionsvektor som representerar dess innehåll. Utmaningen här är att utveckla en modell som kan analysera citeringsgrafen, innehållsvektorerna och relationerna mellan dem för att förutsäga vilken av de sju klasserna en viss publikation tillhör.
Datapreprocessering
Vi installerar PyTorch Geometric-biblioteket med kommandot:
pip install torch_geometricVi kan sedan använda PyTorch Geometric-biblioteket för att ladda och förbehandla datasetet.
from torch_geometric.datasets import Planetoid
import torch_geometric.transforms as T
dataset = Planetoid(root='data/Cora', name='Cora', transform=T.NormalizeFeatures())Planetoid-klassen laddar upp Cora-datasetet och normaliserar funktionsvektorerna. Vi kan få den förbehandlade datan med hjälp av datasetet, vilket ger oss ett Data-objekt med dessa attribut:
- x: en matris med nodfunktioner med formen ‘(antal_noder, antal_funktioner)’
- edge_index: kantanslutningsmatris med formen ‘(2, num_edges)’
- y: en vektor av nodetiketter med formen ‘(num_nodes)’
- train_mask, val_mask, test_mask: booleska maskar som visar vilka noder som är för träning, validering och testning.
Modellarkitektur
När man bygger ett grafneuralt nätverk är det mycket viktigt att välja rätt modellarkitektur. Vi kommer att gå igenom en grundläggande implementering med hjälp av PyTorchs torch_geometric-bibliotek. Vi kommer att använda ett grafkonvolutionsnätverk, vilket fungerar som en bra utgångspunkt för olika grafinlärningsuppgifter.
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)- I koden ovan importerade vi torch och torch.nn.functional för att få tillgång till några användbara moduler och funktioner för neurala nätverk. Sedan definierade vi en GNN-klass som ärver från torch och nn.Module.
- I init-metoden definierade vi två konvolutionslager med hjälp av GCNConv-modulen från PyTorch Geometric. Detta möjliggör en enkel implementering av grafkonvolutioner. Vi har lagt till ett enkelt linjärt lager.
- Framåtpassagen skickar först indata genom de två konvolutionslagren, och applicerar ReLU-aktivering varje gång. Sedan går den genom det linjära lagret och slutligen genom log softmax för att komprimera outputen.
På bara några rader kod kan vi bygga ett trevligt litet grafneuronätverk!
Självklart är detta ett enkelt exempel, men vi kan se hur PyTorch och PyTorch Geometric låter oss snabbt prototypa och iterera på grafneurala nätverksarkitekturer. GCNConv-lagren gör det mycket enkelt att integrera grafstruktur i våra modeller.
Träning
För träning kommer vi att använda korsentropiförlust och Adam-optimeraren. Vi kan dela upp datan i tränings-, validerings- och testset med hjälp av de maskattributen på Data-objektet.
# 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}')
Träningsfunktionen gör en träningsomgång och returnerar förlusten. Testfunktionen kontrollerar hur modellen presterar på tränings-, validerings- och testuppsättningarna och returnerar noggrannheten. Vi tränade modellen i 500 epoker och skrev ut tränings- och testnoggrannheterna vid varje epok.
Beräkna noggrannheten hos GNN-modellen
Koden nedan definierar en funktion för att beräkna hur exakt modellen är på hela datasetet. Funktionen compute_accuracy() byter modellen till utvärderingsläge, genomför ett framåtpass och förutspår etiketter för varje nod. Den jämför dessa förutspådda etiketter med de faktiska etiketterna och beräknar antalet korrekta förutsägelser. Sedan divideras antalet korrekta förutsägelser med det totala antalet noder i datasetet för att få noggrannhetsprocenten.
@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}")I det här fallet var modellens noggrannhet på Cora-datasetet 0,8006. Det betyder att modellen korrekt kunde förutsäga klassens etikett ungefär 80 % av gångerna. Det är ganska bra, men inte perfekt. Noggrannhet ger oss en snabb, övergripande bild av hur bra modellen presterar totalt sett. Men man måste gräva djupare för att verkligen förstå var den lyckas och var den har problem.
För att få en djupare förståelse för modellens effektivitet rekommenderas det att överväga andra utvärderingsmått såsom precision, recall, F1-score och förvirringsmatris. Dessa mått ger insikt i modellens prestation på olika aspekter, såsom att korrekt identifiera positiva och negativa fall samt hantera obalanserade dataset. Så även om 80 % noggrannhet är bra, vill vi ha mer kontext innan vi deklarerar denna modell som en stor framgång. Endast noggrannhetsmåttet ger inte hela bilden av vad som händer under huven. Men det är en bra utgångspunkt för att bedöma prestanda.
Utvärdering
Vi kan utvärdera hur GNN presterar med hjälp av saker som noggrannhet, precision, återkallning och F1-poäng. Men vi kan också visualisera nodinbäddningarna som modellen lär sig med hjälp av t-SNE. Det tar de högdimensionella inbäddningarna och projicerar dem i 2D, vilket gör det möjligt för oss att visualisera dem.
# 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()Observera: Läsaren kan köra koden ovan. Den kommer att visa ett punktdiagram som kan tolkas. Koden använder t-SNE för att visa de inlärda nodinbäddningarna i ett 2D-punktdiagram, vilket är ett smart sätt att visualisera högdimensionell data. Låt oss gå igenom vad som händer:
- Varje punkt i diagrammet representerar en nod i datasetet. X- och y-axlarna är de två dimensionerna som t-SNE har pressat in inbäddningarna i. Färgen på varje punkt representerar den sanna etiketten för motsvarande nod i datasetet.
- Noder som har liknande inbäddningar bör ha liknande etiketter, så de kommer att klustra tillsammans på diagrammet. Å andra sidan kommer noder med väldigt olika inbäddningar troligen ha olika etiketter, så de kommer att ligga längre ifrån varandra.
- Sammanfattningsvis ger diagrammet en tydlig bild av relationerna mellan noder baserat på deras inlärda inbäddningar. Du kan se grupper bildas som måste ha någon underliggande likhet. Det är ett praktiskt sätt att titta in i modellen och förstå hur den organiserar begrepp.
Potentiella utmaningar och överväganden
- Med 2708 noder och 5429 kanter anses Cora-datasetet vara på den mindre sidan. Detta kan hämma GNN:s effektivitet, vilket kräver användning av mer avancerade metoder som dataförstärkning och överföringsinlärning.
- Cora-datasetet består av en typ av nod och en typ av kant, vilket gör det till ett homogent nätverk. Detta kan begränsa GNN:s tillämplighet när det används på mer komplexa nätverk som involverar olika nod- och kanttyper.
- Att välja lämpliga värden för hyperparametrar, såsom antalet dolda lager, antalet dolda enheter och inlärningshastigheten, kan ha stor inverkan på prestandan hos GNN och kräver noggrann justering.
Vanliga frågor
- 1. Vad är ett grafneuronätverk (GNN)?
En GNN är ett neuralt nätverk som är utformat för att arbeta med grafstrukturerad data. Det lär sig representationer på nod-, kant- eller grafnivå genom att samla information från närliggande noder.
- 2. Hur skiljer sig en GNN från ett traditionellt neuralt nätverk?
Traditionella nätverk hanterar rutnätsliknande data (bilder, sekvenser), medan GNN:er kan modellera oregelbundna, sammanlänkade strukturer såsom sociala nätverk eller molekylära grafer.
- 3. Vilka typer av problem används GNN:er för?
De används ofta för nodklassificering, länkprediktion, grafklassificering, rekommendationer, bedrägeribeslut och prediktion av molekylära egenskaper.
- 4. Vad är meddelandeöverföring i GNNs?
Meddelandeförmedling är den centrala mekanismen där noder utbyter information med sina grannar, uppdaterar inbäddningar och lär sig kontextuella relationer.
- 5. Skalerar GNN:er väl till mycket stora grafer?
Skalning kan vara utmanande på grund av minnesanvändning och utvidgning av närområdet. Tekniker som sampling (GraphSAGE), mini-batches och distribuerad träning hjälper.
- 6. Vilka programmeringsbibliotek är bäst för att implementera GNN:er?
Populära ramverk inkluderar PyTorch Geometric (PyG) och Deep Graph Library (DGL), som båda erbjuder färdiga lager och verktyg för att bygga GNN-modeller.
- 7. Är GNN:er lämpliga för realtidsapplikationer?
Ja, beroende på modellens komplexitet. Lättviktiga arkitekturer och samplingsbaserade metoder hjälper till att uppnå nästan realtidsprestanda.
- 8. Kan GNN:er hantera dynamiska eller föränderliga grafer?
Ja, dynamiska GNN-varianter kan bearbeta grafer som förändras över tid, vilket är användbart för trafikprognoser, tidsberoende rekommendationer och avvikelsedetektering.
- 9. Vilken dataprocessering krävs för GNN:er?
Du behöver vanligtvis förbereda närhetsinformation, nod-/kant-egenskaper och säkerställa att grafen är korrekt formaterad för det bibliotek du har valt.
- 10. Är GNN:er tolkbara?
Tolkbarheten förbättras med verktyg som uppmärksamhetsmekanismer och GNNExplainer, som lyfter fram inflytelserika noder och länkar.
Slutsats
I den här artikeln gick vi igenom de grundläggande koncepten bakom grafneuronala nätverk (GNN) och undersökte hur de kan tillämpas inom olika områden. GNN är särskilt lämpade för att arbeta med grafstrukturerad data, vilket gör det möjligt för modeller att resonera kring komplexa relationer som finns i sociala nätverk, molekylära grafer, transportsystem och mer.
För att demonstrera dessa idéer i praktiken använde vi det populära Cora-datasetet—en riktmärke för grafinlärning. I detta dataset representeras varje publikation som en nod, och citaten mellan dem bildar kanterna. Vårt mål var att använda både de textuella egenskaperna hos varje artikel och citatkopplingarna för att förutsäga dess kategori.
Vi förberedde datasetet med hjälp av PyTorch Geometric-biblioteket, normaliserade funktionsvektorerna och delade upp data i tränings-, validerings- och testset. Vi byggde sedan en enkel GNN med grafkonvolutionslager, följt av en linjär klassificerare, och tränade den med korsentropi-förlust och Adam-optimerare. Slutligen utvärderade vi modellens prestanda genom att mäta dess noggrannhet.
Även om det finns många ytterligare tekniker och förbättringar man skulle kunna utforska, erbjuder detta projekt en solid introduktion till hur GNN:er fungerar och hur effektiva de kan vara för att lära sig från komplexa relationella data.
Resurser
- Bygga neurala nätverk från grunden: Del 1
- Vad är djupinlärning? En nybörjarguide till neurala nätverk
- Förklarade djupa inlärningsarkitekturer: ResNet, InceptionV3, SqueezeNet
- PyTorch 101: Lär dig djupinlärning med PyTorch
Tack för att du lär dig tillsammans med Linux-Console.net-communityn.


