polycirc.learner
Circuits for gradient-based machine learning.
Suppose you have the following:
A dataset of input/output examples
(a, b)
, which are pairs ofA
- andB
-dimensional vectors.An initial
P
-dimensional parameterθ ∈ P
A circuit
model : P + A → B
which maps parameters and inputs to outputs
Using the make_learner()
and rdiff()
functions in this module,
you can obtain a circuit step : P + A + B → P
mapping a parameter θ
and
example datum (a, b)
to an updated parameter. Iterating the step
function amounts to learning with gradient descent.
For a step-by-step explanation, see the User Guide. For a complete end-to-end example, see the included example.
For mathematical background, see Cruttwell et al. [CGG+21].
Warning
Note that the example update/displacement maps given in this file don’t work well for integer-valued learning.
See the examples directory for a full example of integer-valued training using fixed-point operations.
- polycirc.learner.gd(lr: int)
Gradient descent update map with learning rate
lr
.>>> from yarrow import Diagram >>> u = gd(0.01) >>> type(u(p = 10)) is Diagram # 10-dimensional parameter vector True
- polycirc.learner.mse(b: int)
Mean-squared error displacement map for
b
-dimensional predictions. Computes model error as the pointwise differenceŷ - y
between predictionŷ
and true labely
.
- polycirc.learner.rdiff(c: Diagram)
Transform a circuit into an optic computing the forward and reverse passes
- polycirc.learner.make_learner(model_optic, update, displacement, P: int, A: int)
Construct a circuit
step : P + A + B → B + P + A
which computes both model output (dimensionB
) and new parameter vector (dimensionP
). Iterate thisstep
function to train your model.>>> import polycirc.ir as ir >>> from polycirc.ast import diagram_to_function >>> A = 4 # input dimension >>> B = 3 # output dimension >>> P = 3*4 # parameter dimension >>> model = ir.mat_mul(B, A) >>> f = rdiff(model) # compute derivative of model >>> u = gd(lr=1)(P) # update circuit >>> d = mse(B) # displacement circuit >>> step = diagram_to_function(make_learner(f, u, d, P, A)) >>> params = [0]*P # initial params >>> x = [1, 2, 3, 4] # example input >>> y = [0, 1, 0] # example output >>> new_params = step(*params, *x, *y)[B:B+P] # compute parameter change: a 3×4 matrix. >>> new_params [0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0]