TGraphX Insights Tensor-Valued Edges in TGraphX: Relations as Structured Feature Maps
← Back to Insights

Tensor-Valued Edges in TGraphX: Relations as Structured Feature Maps

Target keyword: tensor-valued edges

Tensor-Valued Edges in TGraphX: Relations as Structured Feature Maps

Most graph learning treats an edge as a scalar: a 1.0 to say "connected," maybe a weight to say "strongly connected." That is enough for a social link or a citation, but it throws away a lot of structure in problems where the relation itself carries content — a relative pose between two image regions, a learned transformation between two scene objects, a typed predicate between two entities. TGraphX lets an edge carry a feature of the same kinds of shapes a node can: a vector, a [C, H, W] map, or a [C, D, H, W] volume. This note explains what that buys you mathematically and exactly how each layer family consumes it, based on docs/edge_features.md and the layer source.

The companion piece Inside Tensor Message Passing covers the message/aggregate/update skeleton; here we zoom into the E_{i→j} term.

Where edges enter the math

Recall the message step M_{i→j} = φ(X_i, X_j, E_{i→j}). A scalar-weight model degenerates this to M_{i→j} = w_{i→j} · φ(X_i, X_j) — the edge can only rescale a message. A tensor-valued edge restores E_{i→j} as a first-class argument, so the relation can reshape the message, not just dim it up or down. In TGraphX a Graph stores this as edge_features (PyG alias edge_attr), validated against the edge count at construction, and a parallel edge_labels field exists for edge-level supervision such as link classification.

Three supported shapes

The documentation enumerates exactly what is accepted, and which layers handle each:

Format Shape Consumed by
Vector [E, D_e] GAT (attention bias), SAGE (vector bias), GIN (broadcast bias)
2-D spatial [E, C_e, H, W] ConvMessagePassing, SAGE (concat), GIN (1×1 conv)
3-D volumetric [E, C_e, D, H, W] ConvMessagePassing, SAGE (concat), GIN

The shape you choose is not cosmetic — it determines which layer can use the edge and how. That is the honest trade-off: richer edge tensors are more expressive but impose compatibility rules.

How each layer family consumes an edge

ConvMessagePassing treats the edge as another feature map to fuse. The source concatenates source, destination, and edge tensors along the channel axis before the 1×1 convolution, which is why docs/edge_features.md states the rule plainly: edge_features.shape[1] must equal in_shape[0] — the edge must have the same channel count as the nodes. A minimal, verified example:

python
from tgraphx.layers.conv_message import ConvMessagePassing
        
        layer = ConvMessagePassing(in_shape=(16, 8, 8), out_shape=(32, 8, 8),
                                   use_edge_features=True)
        out = layer(x, edge_index, edge_features=edge_feats)   # edge_feats: [E, 16, 8, 8]
        

TensorGATLayer uses the edge differently: a vector edge feature becomes an additive bias on the attention logit, per (edge, head). Spatial edge tensors [E, D_e, H_e, W_e] are mean-pooled to vectors before that projection, so the edge's spatial dimensions do not have to match the node's. This is a deliberate design choice — attention wants a scalar-per-head nudge, so a spatial edge is summarised rather than convolved.

TensorGraphSAGELayer is the most flexible on edge_dim: it accepts an edge_features_kind of "vector" (added as a per-edge channel bias) or "spatial" (concatenated to the source before the neighbour transform). If your edge dimensionality does not match the node channels, SAGE or GIN is the path the docs point you to, since ConvMessagePassing requires the channel-match above.

A worked intuition

Think of a graph of detected objects in a scene, each node a [C, H, W] region embedding. An edge could encode the relative geometry between two objects as its own small feature map — orientation, overlap, relative scale rendered spatially. With ConvMessagePassing, that edge map is convolved together with the two object maps, so the message "object A as seen through its relation to B" is computed in feature space rather than reduced to a single number. The same problem with a scalar edge weight could only say "A and B are 0.7-related," which cannot represent how they relate.

Honest boundaries

Three caveats keep this accurate. First, the channel-match constraint on ConvMessagePassing is real; you will hit a shape error if an edge tensor's channel count differs from the node channels, and the fix is to pick SAGE/GIN or reshape. Second, attention layers summarise spatial edges by mean-pooling, so they are not using the full spatial edge structure — if per-location edge reasoning matters, a convolutional layer is the right choice. Third, expressive edge tensors increase memory; whether the extra structure improves a model is task-specific and should be measured, not assumed. None of this is a defect — it is the normal shape bookkeeping that comes with taking edges seriously.

How to describe this accurately

A safe summary for a paper or report: In TGraphX, edges may carry vector, 2-D, or 3-D tensor features (edge_features / edge_attr); convolutional message passing fuses spatial edge maps by channel concatenation, while attention and SAGE layers consume vector or pooled edge features as biases. That statement is backed directly by docs/edge_features.md.

Related guides

Conclusion

Edges in TGraphX are not limited to scalar weights: they can be vectors or full feature-map tensors, and the layer you choose decides how that structure is used — channel concatenation for convolutional messages, pooled biases for attention. Treating relations as structured objects is the natural counterpart to treating nodes as structured objects, and the per-layer rules in docs/edge_features.md tell you precisely what shapes fit where.