Hands-on lab · 1 step
Train a QCNN to tell horizontal from vertical bars
Train the 4-qubit quantum convolutional neural network of the lesson, with shared weights, on images of horizontal and vertical bars. Your TypeScript function receives training images and returns the weights p0 to p11. You write the loss, the gradient and the optimiser. For the gradient, the engine's parameterShiftGradient applies the two-term rule to the weights and the four-term rule to the / pooling weights. The grader binds your weights into the fixed QCNN circuit and classifies held-out images by ; at least must be correct.
Step 1: Implement trainQCNN
Complete the TypeScript function
trainQCNN(Xtrain: number[][], ytrain: number[]): Record<string, number>
The model. qcnnTemplate() from 'quantumcore/qml' is the circuit the grader uses. It has four data parameters x0 to x3 and twelve weights p0 to p11; qubit is the most significant bit and . In time order:
- Encoding: on qubit , so a pixel value sets .
- Convolution layer 1: the block (time order) on the pairs , , , , all with the same weights .
- Pooling layer 1: , which rotates qubit by if qubit is and by if it is , on and with the shared weights . Qubits and are not used again.
- Convolution layer 2: .
- Pooling layer 2: .
- Readout: (Pauli word
IIIZ), prediction ; counts as wrong.
The data. Xtrain holds images, each an array [x0, x1, x2, x3] of pixel values in in the order (top row), (bottom row). ytrain[m] is for a horizontal bar (pattern 1100 or 0011) and for a vertical bar (1010 or 0101). A pixel that is on has a value in and a pixel that is off a value in . The training set has images of each class.
What to write. A training loop that lowers a loss over the training set, for example the mean squared error with . Compute with the parameter-shift rule: either the engine's parameterShiftGradient(template, observable, { bindings, params }) from 'quantumcore', which applies the four-term rule to the controlled pooling rotations and sums over every gate that shares a weight, or your own function from the parameter-shift lab. The lesson proves that for these pooling gates the plain two-term rule is exact as well, because each pooled qubit is used only as a control afterwards; with your own function you must still sum the contributions of every gate that shares a weight. Any optimiser is allowed: gradient descent, Adam, or several random restarts. The starter code initialises the weights at random and returns them untrained.
What to return. An object with exactly the keys p0 to p11, each a finite number.
Grading. The function runs once, with the training set as its arguments, in a time limit of 60 seconds. The reference solution (Adam, full-batch steps, circuit evaluations per step) needs about seconds. The check shape verifies the returned keys. The check model binds your weights into qcnnTemplate() on the server and computes the accuracy on held-out images from the same distribution. These images are never sent to your browser, so the score cannot be tuned against them. The required accuracy is at least ; the reference reaches test accuracy 1.00 on the 100 held-out images.
About the shortcut. The module 'quantumcore/qml' also exports a reference trainQCNN (with qcnnPredict and barsDataset), which the lesson uses. Calling it would pass this lab without doing the exercise. The grader only sees the returned weights, so it cannot tell who trained them: this rule is not enforced, and the exercise only works if you write the loop yourself.