Protein sequence and inverse folding
Attention-derived protein contact prediction
ESM-2ESM-1b
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
| Parameter | Shape 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.Tensor | Scalar 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 floatingattention(B,A,H,T\ge 1);token_mask[B,T]is bool withTruemeans present;tokens[B,T]is integer.weight[A\cdot H]and scalarbias[]shareattentiondtype/device. Configspecial_idsis a list of integer IDs, default[0,1,2]; no other keys. - A residue is valid exactly when
token_maskisTrueand its token ID is not inspecial_ids. Mask BOTHattentionendpoints before any reduction. Keep the originalTaxes; 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). Setr_{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; ifZ=0defineC=0with zeroattentionderivative for that whole plane. No\epsilonis added to a positive APC denominator. Flatten A,Hin layer-major, head-minor order tofeatures[B,T,T,A\cdot H]. - Let
z_{\mathrm{ij}}=\sum_{c} \mathrm{features\_ijc}\cdot \mathrm{weight\_c}+\mathrm{bias};probabilitiesare\operatorname{sigmoid}(z). Returnfeatures,logitsandprobabilitieswith invalid pairs exactly zero, pluspair_mask[B,T,T]. Empty valid-residue sets yield finite zeros even with nonzerobias. - The positive-mass branch is differentiable; the zero-mass extension is explicitly defined, not source
0/0behavior. Preserve\mathrm{float32}/64and 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.
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.