Protein sequence and inverse folding

Attention-derived protein contact prediction

MediumRaw PyTorchAbout 20 min2 public examples plus private tests

ESM-2ESM-1b

Write and run your solution Sign in

Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.

Your task

Convert attention between residue tokens into a symmetric contact-probability matrix. Each output pair first combines both attention directions, subtracts the background expected from its row and column totals, then uses the supplied logistic readout across layer/head planes. Keep the original token positions and zero pairs touching padding or excluded special tokens.

Function signature

attention_contact_prediction(
    attention: torch.Tensor,
    tokens: torch.Tensor,
    token_mask: torch.Tensor,
    weight: torch.Tensor,
    bias: torch.Tensor,
    special_ids: list = [0, 1, 2],
) -> dict[str, torch.Tensor]

Worked example

Symmetrize and remove row/column background

For one batch, one layer, one head, and two valid ordinary tokens, take attention [[0.8,0.2],[0.3,0.7]], readout weight 1, and bias 0. Symmetrizing by addition gives S=[[1.6,0.5],[0.5,1.4]]. Row and column totals are [2.1,1.9], and the total is 4. The corrected (0,1) feature is 0.5 − 2.1*1.9/4 = −0.4975; the full feature/logit matrix is [[0.4975,-0.4975],[-0.4975,0.4975]]. Applying sigmoid gives probabilities approximately [[0.621872,0.378128],[0.378128,0.621872]].

Parameters

ParameterShape and meaning
attentiontorch.Tensor[B, A, H, T, T]Attention maps for each model layer and head; final axes are query and key token positions.
tokenstorch.Tensor[B, T]Token identities used to identify excluded special positions.
token_masktorch.Tensor[B, T]Bool [B,T], True means present.
weighttorch.Tensor[A\cdot H]One logistic-readout coefficient per layer/head plane, flattened layer first then head.
biastorch.TensorScalar tensor, shape [].Floating scalar [].
special_idslistDefault [0, 1, 2]Token IDs excluded from contact prediction. Their positions remain in both output axes and are masked to zero; the sequence is not compacted.

Return

dict[str, torch.Tensor]

Return exactly the named fields applicable to this operation.

Required behavior

  • Inputs attention [B,A,H,T,T] is finite nonnegative floating attention (B,A,H,T\ge 1); token_mask [B,T] is bool with True means present; tokens [B,T] is integer. weight [A\cdot H] and scalar bias [] share attention dtype/device. Config special_ids is a list of integer IDs, default [0,1,2]; no other keys.
  • A residue is valid exactly when token_mask is True and its token ID is not in special_ids. Mask BOTH attention endpoints before any reduction. Keep the original T axes; do not remove diagonal/self contacts.
  • For each layer/head plane, let M_{\mathrm{ij}}=\mathrm{attention\_ij} on valid pairs, zero elsewhere; S=M+M^{\top} (a SUM, not a mean). Set r_{i}=\sum_{j} S_{\mathrm{ij}}, c_{j}=\sum_{i} S_{\mathrm{ij}}, Z=\sum_{\mathrm{ij}} S_{\mathrm{ij}}.
  • If Z>0, C_{\mathrm{ij}}=S_{\mathrm{ij}}-r_{i}\cdot c_{j}/Z; if Z=0 define C=0 with zero attention derivative for that whole plane. No \epsilon is added to a positive APC denominator. Flatten A,H in layer-major, head-minor order to features [B,T,T,A\cdot H].
  • Let z_{\mathrm{ij}}=\sum_{c} \mathrm{features\_ijc}\cdot \mathrm{weight\_c}+\mathrm{bias}; probabilities are \operatorname{sigmoid}(z). Return features, logits and probabilities with invalid pairs exactly zero, plus pair_mask [B,T,T]. Empty valid-residue sets yield finite zeros even with nonzero bias.
  • The positive-mass branch is differentiable; the zero-mass extension is explicitly defined, not source 0/0 behavior. Preserve \mathrm{float32}/64 and noncontiguous inputs; do not mutate inputs.

Why this matters

Average product correction removes a broad row/column background before a learned readout scores contact-specific attention.

Starter code

You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.

import torch


def attention_contact_prediction(
    attention: torch.Tensor,  # (B, A, H, T, T)
    tokens: torch.Tensor,  # (B, T)
    token_mask: torch.Tensor,  # (B, T)
    weight: torch.Tensor,  # (A* H)
    bias: torch.Tensor,  # Scalar tensor, shape ().
    special_ids: list = [0, 1, 2],
) -> dict[str, torch.Tensor]:
    """Return dict[str, torch.Tensor]:
    
    features: (B, T, T, A* H).
    logits: (B, T, T).
    probabilities: (B, T, T).
    pair_mask: (B, T, T)."""
    # Implement the operation. Inputs and test setup are supplied by BioTorch.
    raise NotImplementedError("Implement attention_contact_prediction")

Ready to implement it?

3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.

Write and run your solution Sign in

Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.

Sources and further reading

A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.