Diffusion and flow matching · INTEGRATION
Gaussian forward corruption and score targets
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
For each movable valid point, form noisy = alpha·x0 + sigma·epsilon and return the conditional Gaussian score −epsilon/sigma at that sample. Obtain alpha and sigma either from the continuous linear VP schedule or from supplied batch coefficients. Valid fixed points retain x0; invalid points return zero.
Function signature
gaussian_forward(
x0: torch.Tensor,
epsilon: torch.Tensor,
masks: dict,
t: torch.Tensor | None = None,
beta_min: torch.Tensor | None = None,
beta_max: torch.Tensor | None = None,
alpha: torch.Tensor | None = None,
sigma: torch.Tensor | None = None,
schedule: str = 'linear_vp',
) -> dict[str, torch.Tensor]Worked example
Explicit three four five
The explicit schedule supplies alpha=[0.6] and sigma=[0.8]. With x0=[5,10,0] and epsilon=[1,0,-1], noisy=0.6×[5,10,0]+0.8×[1,0,-1]=[3.8,6,-0.8], and score=−[1,0,-1]/0.8=[−1.25,0,1.25]. The coefficient vectors are returned unchanged.
import torch
x0 = torch.tensor([[[5.0, 10.0, 0.0]]], dtype=torch.float64, requires_grad=True)
epsilon = torch.tensor([[[1.0, 0.0, -1.0]]], dtype=torch.float64, requires_grad=True)
t = None
beta_min = None
beta_max = None
alpha = torch.tensor([0.6], dtype=torch.float64, requires_grad=True)
sigma = torch.tensor([0.8], dtype=torch.float64, requires_grad=True)
masks = {
'valid_mask': torch.tensor([[True]], dtype=torch.bool),
'diffuse_mask': torch.tensor([[True]], dtype=torch.bool),
}
schedule = 'explicit'
result = gaussian_forward(x0=x0, epsilon=epsilon, t=t, beta_min=beta_min, beta_max=beta_max, alpha=alpha, sigma=sigma, masks=masks, schedule=schedule)Expected return
{
'alpha': torch.tensor([0.6], dtype=torch.float64),
'sigma': torch.tensor([0.8], dtype=torch.float64),
'noisy': torch.tensor([[[3.8, 6.0, -0.8]]], dtype=torch.float64),
'score': torch.tensor([[[-1.25, -0.0, 1.25]]], dtype=torch.float64),
}Parameters
| Parameter | Shape and meaning |
|---|---|
x0torch.Tensor | [B, N, 3][B,N,3] clean positions |
epsilontorch.Tensor | [B, N, 3]Supplied IID standard-normal variates |
ttorch.Tensor | NoneDefault None | [B]Continuous positive time, linear_vp only |
beta_mintorch.Tensor | NoneDefault None | Scalar tensor, shape [].Positive start rate, linear_vp only |
beta_maxtorch.Tensor | NoneDefault None | Scalar tensor, shape [].End \mathrm{rate} \ge \beta_{\mathrm{min}}, linear_vp only |
alphatorch.Tensor | NoneDefault None | [B]Mean coefficient, explicit only |
sigmatorch.Tensor | NoneDefault None | [B]Positive standard deviation, explicit only |
masksdict | Supplied masks. Each field below defines what True includes or permits. |
schedulestrDefault 'linear_vp' | Choose "linear_vp" to derive alpha/sigma from supplied time and beta endpoints or "explicit" to use supplied coefficients directly. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Given
x0and suppliedepsilon[B,N,3], compute the conditional IID Gaussian corruptionx_{t}=\alpha\cdot \mathrm{x0}+\sigma\cdot \epsilonand\mathrm{score}=-(x_{t}-\alpha\cdot \mathrm{x0})/\sigma^{2}=-\epsilon/\sigmaat the sampledx_t. schedule='linear_vp'(default) takest [B],beta_min[]andbeta_max[]; require0<t\le 1and0<\beta_{\mathrm{min}}\le \beta_{\mathrm{max}}.- With
\beta(u)=\beta_{\min}+(\beta_{\max}-\beta_{\min})u,I(t)=\beta_{\mathrm{min}}\cdot t+(\beta_{\mathrm{max}}-\beta_{\mathrm{min}})\cdot t^{2}/2,\alpha=\operatorname{exp}(-I/2),\sigma=\sqrt{1-\operatorname{exp}(-I)}; evaluate the variance as -expm1(-I) to preserve tiny positive times. - The alternate
schedule='explicit'takesalpha[B]andsigma[B]directly, with0\le \alpha\le 1and\sigma>0;t/\betainputs are then absent. Coefficients broadcast overNand xyz and are returned as[B]. - Update only
valid_mask&diffuse_mask: fixed valid residues retainx0and have zeroscore; invalid residues have zeronoisycoordinates andscore. Noepsilonregularization, coordinate rescaling, centering or COM projection is applied. t=0/\mathrm{zero}sigmais excluded because the conditionalscorehas no finite zero-variance limit;t=1is valid for this forward marginal. schedule is the onlykey. All masks are bool:valid_mask=Truedenotes a real residue/atom;diffuse_mask=Truedenotes a movable one. Their conjunction selects updates.B,N(or A) are positive; an all-false mask, not a zero-length tensor, represents an empty example. All supplied numbers, including padding, are finite and share dtype/device; floating tensors arefloat32orfloat64.
Why this matters
The score points toward the conditional Gaussian mean, with a magnitude determined by the noise variance.
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 gaussian_forward(
x0: torch.Tensor, # (B, N, 3)
epsilon: torch.Tensor, # (B, N, 3)
masks: dict,
t: torch.Tensor | None = None, # (B,)
beta_min: torch.Tensor | None = None, # Scalar tensor, shape ().
beta_max: torch.Tensor | None = None, # Scalar tensor, shape ().
alpha: torch.Tensor | None = None, # (B,)
sigma: torch.Tensor | None = None, # (B,)
schedule: str = 'linear_vp',
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
alpha: (B,).
sigma: (B,).
noisy: (B, N, 3).
score: (B, N, 3)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement gaussian_forward")
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.
Related exercises
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.