Building a Knowledge Graph with Tensor Entity Features in TGraphX
Knowledge graph embedding is well-studied for graphs where entities are represented by scalar embeddings. But real knowledge graphs often have entities with rich features: images of the described entities, text embeddings, biological sequence vectors, or volumetric scientific data. TGraphX's KG module supports these multimodal entity features alongside standard KGE scoring functions.
This tutorial walks through building a knowledge graph with tensor entity features, training a TransE-based embedding model, and extending to multimodal entities with image features.
Prerequisites
You should be familiar with:
- Basic TGraphX API (see what is a TGX graph)
- What knowledge graph embedding is (link prediction via triple scoring)
Part 1: Basic Knowledge Graph Construction
A knowledge graph stores facts as triples (head, relation, tail). Each element is an integer index into the entity/relation vocabulary.
import torch
from tgraphx.kg import KnowledgeGraph, TransEModel, KGTrainer, KGTrainingConfig
# 10 entities, 3 relations
# Triples: [head, relation, tail]
triples = torch.tensor([
[0, 0, 1], # entity_0 --relation_0--> entity_1
[1, 0, 2],
[2, 1, 3],
[3, 1, 4],
[4, 2, 5],
[5, 2, 6],
[6, 0, 7],
[7, 1, 8],
[8, 2, 9],
[0, 1, 5],
], dtype=torch.long)
kg = KnowledgeGraph(triples, num_entities=10, num_relations=3)
print(f"Entities: {kg.num_entities}")
print(f"Relations: {kg.num_relations}")
print(f"Triples: {kg.triples.shape}") # [10, 3]
Part 2: Training TransE
TransE (Bordes et al., 2013) models each triple as a translation in embedding space:
score(h, r, t) = -||e_h + r_r - e_t||_2
# TransE model
model = TransEModel(
num_entities=kg.num_entities,
num_relations=kg.num_relations,
embedding_dim=64,
margin=1.0, # margin for margin-ranking loss
norm=2, # L2 norm
)
config = KGTrainingConfig(
num_epochs=100,
lr=1e-3,
batch_size=32,
negative_samples=5, # number of corrupted triples per positive
seed=42,
)
trainer = KGTrainer(model, config, kg.triples)
trainer.train()
# After training: score any triple
h_idx = torch.tensor([0])
r_idx = torch.tensor([0])
t_idx = torch.tensor([1])
score = model.score(h_idx, r_idx, t_idx)
print(f"Score for (0, 0, 1): {score.item():.4f}")
Part 3: Alternative Scoring Functions
TGraphX includes four KGE scoring functions:
from tgraphx.kg import TransEModel, DistMultModel, ComplExModel, RotatEModel
# DistMult: score(h, r, t) = <e_h, r_r, e_t> (Hadamard product)
distmult = DistMultModel(num_entities=10, num_relations=3, embedding_dim=64)
# ComplEx: complex-valued embeddings
complex_model = ComplExModel(num_entities=10, num_relations=3, embedding_dim=64)
# RotatE: relations as rotations in complex space
rotate = RotatEModel(num_entities=10, num_relations=3, embedding_dim=64)
| Model | Score function | Best for |
|---|---|---|
| TransE | Translation | Simple hierarchical relations |
| DistMult | Hadamard product | Symmetric relations |
| ComplEx | Complex dot product | Anti-symmetric + symmetric |
| RotatE | Complex rotation | Patterns: symmetry, antisymmetry, inversion, composition |
Part 4: Adding Entity Features
TGraphX supports attaching feature tensors to entities. This is useful when entities have external representations (protein sequences, molecular fingerprints, image patches):
from tgraphx.kg import KnowledgeGraph
# Entity features: [num_entities, feature_dim]
# Different entities can have different feature types (handled via masks)
entity_features = torch.randn(10, 128) # 10 entities, 128-dim features
kg_with_features = KnowledgeGraph(
triples=triples,
num_entities=10,
num_relations=3,
entity_features=entity_features,
)
print(kg_with_features.entity_features.shape) # [10, 128]
Part 5: Multimodal Knowledge Graph with Tensor Features
For entities with image-like features:
from tgraphx.kg.multimodal import MultimodalKGModel, ModalityConfig
# Mixed entity types:
# - Entities 0-4: image entities [C, H, W]
# - Entities 5-9: vector entities [D]
num_entities = 10
# Image entity features: [5, 3, 32, 32]
image_features = torch.randn(5, 3, 32, 32)
# Text/vector entity features: [5, 256] (e.g., BERT embeddings)
text_features = torch.randn(5, 256)
# Modality mask: which entities have which modality
image_mask = torch.zeros(num_entities, dtype=torch.bool)
image_mask[:5] = True # entities 0-4 have image features
text_mask = torch.zeros(num_entities, dtype=torch.bool)
text_mask[5:] = True # entities 5-9 have text features
# Multimodal KG model projects each modality to a shared embedding space
modality_config = ModalityConfig(
embedding_dim=64,
image_in_channels=3,
image_height=32,
image_width=32,
text_in_dim=256,
)
mm_model = MultimodalKGModel(
num_entities=num_entities,
num_relations=3,
modality_config=modality_config,
base_model="transe",
)
The multimodal projectors are differentiable — gradients flow through image/text encoders. Entity embeddings are the sum of the learned entity embedding and the projected modality feature.
Part 6: Link Prediction Evaluation
After training, evaluate on held-out triples using filtered ranking:
from tgraphx.kg.evaluation import filtered_ranking_metrics
# Split triples into train/val/test
n = len(triples)
train_triples = triples[:7]
test_triples = triples[7:]
# Filtered ranking: rank the true tail among all entities,
# filtering out known true triples to avoid unfair penalization
metrics = filtered_ranking_metrics(
model=model,
test_triples=test_triples,
all_triples=triples, # used for filtering
num_entities=10,
)
print(f"MRR: {metrics['mrr']:.4f}")
print(f"Hits@1: {metrics['hits@1']:.4f}")
print(f"Hits@10: {metrics['hits@10']:.4f}")
Part 7: KG + RGCN for Relational Graph Convolution
For entity classification tasks on the knowledge graph (not just link prediction), combine KG embeddings with RGCN:
from tgraphx.kg.gnn import KGRGCNModel
# RGCN on the KG: uses entity features + relational edges
model_rgcn = KGRGCNModel(
num_entities=10,
num_relations=3,
entity_feature_dim=128,
hidden_dim=64,
out_dim=4, # 4 entity classes
)
# entity_features used as node features; triples used to build edge_index
logits = model_rgcn(entity_features, triples)
print(logits.shape) # [10, 4]
Part 8: PyKEEN-Style API Aliases
TGraphX provides PyKEEN-compatible syntax aliases:
# PyKEEN-style access
print(kg.triples) # same as kg.triples
print(kg.num_entities) # same
print(kg.num_relations) # same
# Construct from HRT format (like PyKEEN)
kg2 = KnowledgeGraph.from_hrt(
heads=triples[:, 0],
relations=triples[:, 1],
tails=triples[:, 2],
num_entities=10,
num_relations=3,
)
Limitations
No temporal KG training loop in this tutorial. TGraphX includes temporal KG primitives (tgraphx.kg.temporal) but temporal link prediction training is more involved.
Multimodal KG is Experimental. The MultimodalKGModel API may change in future releases. Pin your TGraphX version if you build on it.
No hyperparameter search built in. TGraphX has a tgraphx.kg.hpo module for HPO integration, but a systematic HPO study requires external tooling (Optuna, Ray Tune).
Filtered ranking is exact but slow for large KGs. For KGs with millions of entities, approximate or GPU-batched ranking is required. TGraphX's filtered_ranking_metrics is designed for research-scale KGs.
Performance numbers not provided. No claims are made about TGraphX's KGE performance on Freebase, Wikidata, or other standard benchmarks. See TGraphX benchmark disclaimers.
Related Articles
- Knowledge graph embedding with tensor features — the published detailed KG tutorial
- TGraphX vs PyKEEN — when to use PyKEEN vs TGraphX for KGE
- What is a TGX graph — TGraphX's data model
- Multimodal graph nodes in TGraphX — broader multimodal graph learning
- GNN research reproducibility — reproducibility for KGE experiments