Qu

track

Builtin index · Statistics & ML

result = param(v) / track(v)

Input: v · Output: result

What it is

Wraps a plain number, vector, or matrix v as a fresh, differentiable Tensor — a new leaf node on the autodiff tape with no inputs of its own, so grad treats it as something to differentiate *with respect to* rather than something computed. param and track do exactly the same thing; the two names exist so a program can say which values are trainable weights (param) versus intermediate values you also want a gradient through (track) — a note to the reader, not a mechanical difference.

Overloads

One call shape — this function is not overloaded.

CodeInputOutputDescription
result = param(v) / track(v)
v number, vector, or matrixnot documented yet
v vector or matrixa bare vector is promoted to a column matrix, matching to_matrix's convention
Returns a Tensor of the same shape as v (a bare vector is promoted to a column matrix, matching to_matrix's convention).

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

x = track(3.0)
y = x * x + 2 * x
dy_dx = grad(y, wrt=x)      # 2*x + 2 = 8

print("dy/dx = {dy_dx}")

from repl-diagnostics

x = track(3.0)
y = track(2.0)
loss = x * x + y * y
dloss_dx = grad(loss, wrt=x)          # 2*x = 6

grads = grad(loss, x, y)              # [2*x, 2*y] = (6, 4)

print("wrt=x form: {dloss_dx}")
print("positional form: {grads}")
output
wrt=x form: 6
positional form: (6, 4)

from repl-diagnostics

target = stop_grad(track(5.0))
x = track(2.0)
loss = (x - target) * (x - target)
dloss_dx = grad(loss, wrt=x)
print("dloss/dx = {dloss_dx}")

from repl-diagnostics

How it works

param(v)/track(v) (§38 autodiff): wraps a plain Num/ Mat (or promotes a Vec, matching to_matrix's own Vec-as-column convention, so a param's shape is always matmul-ready) as a fresh, untracked-yet root Value::Tensor — a new tape node with no inputs, so grad treats it as a leaf. param and track are the same operation; two names because the spec uses param for trainable weights and track for "differentiate through this too" on an ordinary intermediate value — the distinction is documentation, not mechanism, until optimizers exist to actually read it.

From the note above this builtin in the interpreter, where the reasoning was written down as it was built.

See also

param — documented in the same entry.