Understanding the --add-eweights Flag in doc2graph: Enabling Geometric Edge Features and Weights

The --add-eweights flag enables geometric edge features and distance-based edge weights in doc2graph, computing polar coordinates between document entities and discretizing them into binned vectors that capture spatial relationships for graph neural networks.

The --add-eweights flag controls whether doc2graph includes geometric relationship features when converting documents into graph representations. When enabled, the preprocessing pipeline calculates spatial distances and angles between entity bounding boxes, creating edge feature tensors and learnable weights stored in g.edata["feat"] and g.edata["weights"] that provide crucial relational cues for downstream graph convolutional networks.

How the --add-eweights Flag Works

When passed via CLI, --add-eweights (short form -addE) stores a boolean value in FEATURES.add_eweights within the preprocessing configuration. In doc2graph/utils.py, this setting persists to the configuration file, allowing the FeatureBuilder class to conditionally execute geometric feature computation during graph construction.

Edge Feature Computation Pipeline

When enabled, the FeatureBuilder in doc2graph/data/feature_builder.py executes a spatial analysis pipeline for each graph:

Polar Coordinate Extraction

For every edge (src, dst) connecting two document entities, the system invokes the polar() method to compute Euclidean distance and angular displacement between the source and destination bounding boxes. This geometric calculation captures the spatial orientation of entities within the document layout.

Feature Discretization

Continuous polar values undergo quantization via the to_bin() function, which bins measurements into num_polar_bins (default 8) discrete categories. This discretization produces fixed-size vectors for each edge, ensuring consistent tensor dimensions regardless of document complexity.

Edge Tensor and Weight Generation

The binned vectors populate g.edata["feat"], creating the edge feature matrix utilized by GNN models. Simultaneously, distances undergo normalization (1 - d/m) and thresholding (> 0.9 → 0.1, else 0) to generate scalar weights stored in g.edata["weights"]. These weights subsequently enable computation of per-node normalization factors in g.ndata["norm"] for message-passing operations.

Default Behavior Without Edge Features

If --add-eweights is omitted, FeatureBuilder bypasses geometric calculations entirely. The system initializes dummy distances of 0.0 and assigns a default normaliser value of m = 1, constructing graphs containing exclusively node-level features (geometric, visual, and textual attributes) without edata tensors.

Implementation Examples

Command Line Usage

Activate edge features during dataset preprocessing:

python -m doc2graph.main \
    --src-data FUNSD \
    --edge-type fully \
    --add-eweights

Omitting the flag generates graphs lacking spatial edge attributes.

Python API Configuration

Programmatically enable the flag before building graphs:

from doc2graph.data.graph_builder import GraphBuilder
from doc2graph.utils import get_config

cfg = get_config("preprocessing")
cfg.FEATURES.add_eweights = True  # Equivalent to --add-eweights

graphs, feats = GraphBuilder().build()
g = graphs[0]

print("Edge features:", g.edata["feat"].shape)  # [E, 8]

print("Edge weights:", g.edata["weights"])

GNN Model Integration

Utilize edge features within message-passing layers:

import torch.nn as nn
import dgl.function as fn

class EdgeAwareGNN(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super().__init__()
        self.conv = dgl.nn.GraphConv(in_dim + 8, hidden_dim)
        self.lin = nn.Linear(hidden_dim, out_dim)

    def forward(self, g, node_feats):
        e_feat = g.edata["feat"]  # [E, 8]

        g.ndata["h"] = node_feats
        g.update_all(fn.u_mul_e('h', 'feat', 'm'), fn.sum('m', 'h'))
        h = self.conv(g, g.ndata["h"])
        return self.lin(h)

Source Code References

The implementation spans three critical modules:

Summary

  • The --add-eweights flag activates geometric edge feature computation in doc2graph's preprocessing pipeline
  • Edge features capture spatial relationships through binned polar coordinates (distance and angle) stored in g.edata["feat"] as 8-dimensional vectors
  • Edge weights provide normalized distance scalars in g.edata["weights"] for message-passing normalization
  • Without the flag, graphs contain only node-level features with dummy zero distances and default normalization
  • The FeatureBuilder class in doc2graph/data/feature_builder.py conditionally executes this logic based on the FEATURES.add_eweights configuration value

Frequently Asked Questions

What happens if I omit the --add-eweights flag during preprocessing?

Doc2graph constructs graphs without geometric edge features. The FeatureBuilder skips polar coordinate calculations, assigns dummy distance values of 0.0, and sets the normalization factor m = 1. Resulting graphs lack both g.edata["feat"] and g.edata["weights"] tensors, containing only node-level geometric, visual, and textual features.

How are the edge features mathematically computed?

For each edge connecting two document entities, the system calculates Euclidean distance and angular displacement between their bounding box centers using the polar() function in doc2graph/data/feature_builder.py. These continuous values are then discretized into num_polar_bins (default 8) bins via the to_bin() method, creating a fixed-size feature vector that quantifies the spatial relationship between connected nodes.

Can I adjust the number of bins for edge features?

Yes. The num_polar_bins parameter controls the dimensionality of the edge feature vectors, defaulting to 8. You can modify this value in the preprocessing configuration before calling GraphBuilder().build(), which directly affects the shape of g.edata["feat"] (specifically [E, num_polar_bins] where E represents the number of edges).

Why are edge weights thresholded at 0.9 during normalization?

The thresholding operation (> 0.9 → 0.1, else 0) in doc2graph/data/feature_builder.py implements a proximity-based filtering mechanism. Normalized distances exceeding 0.9 indicate entities that are relatively far apart spatially; assigning them a minimal weight of 0.1 reduces their influence during message passing, while closer entities retain full connectivity strength, prioritizing local spatial relationships in the document layout.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →