QML Templates¶
Module name: pennylane.template
This module provides a growing library of templates of common quantum machine learning circuit architectures that can be used to easily build, evaluate, and train more complex quantum machine learning models.
Note
The templates below are constructed out of structured combinations
of the quantum operations
provided by PennyLane.
As a result, you should follow all the rules of quantum operations
when you use templates. For example template functions can only be
used within a valid pennylane.qnode
.
Examples
For example, you can construct a circuitcentric quantum
classifier with the architecture from [R2] on an arbitrary
number of wires and with an arbitrary number of blocks by using the
template StronglyEntanglingCircuit
in the following way:
import pennylane as qml
from pennylane.template import StronglyEntanglingCircuit
from pennylane import numpy as np
num_wires = 4
num_blocks = 3
dev = qml.device('default.qubit', wires=num_wires)
@qml.qnode(dev)
def circuit(weights, x=None):
qml.BasisState(x, wires=range(num_wires))
StronglyEntanglingCircuit(weights, periodic=True, wires=range(num_wires))
return qml.expval.PauliZ(0)
weights = np.random.randn(num_blocks, num_wires, 3)
print(circuit(weights, x=np.array(np.random.randint(0, 1, num_wires))))
The handy Interferometer()
function can be used to construct arbitrary
interferometers in terms of elementary Beamsplitter
operations,
by providing lists of transmittivity and phase angles. PennyLane can
then be used to easily differentiate and optimize these
parameters:
import pennylane as qml
from pennylane.template import Interferometer
from pennylane import numpy as np
num_wires = 4
dev = qml.device('default.gaussian', wires=num_wires)
num_params = int(num_wires*(num_wires1)/2)
# initial parameters
r = np.random.rand(num_wires, 2)
theta = np.random.uniform(0, 2*np.pi, num_params)
phi = np.random.uniform(0, 2*np.pi, num_params)
@qml.qnode(dev)
def circuit(theta, phi):
for w in range(num_wires):
qml.Squeezing(r[w][0], r[w][1], wires=w)
Interferometer(theta=theta, phi=phi, wires=range(num_wires))
return [qml.expval.MeanPhoton(wires=w) for w in range(num_wires)]
print(qml.jacobian(circuit, 0)(theta, phi))
The function CVNeuralNet()
implements the continuousvariable neural network architecture
from [R3]. Provided with a suitable array of weights, such neural
networks can be easily constructed and trained with PennyLane.
Provided templates¶
StronglyEntanglingCircuit (weights[, …]) 
A strongly entangling circuit. 
StronglyEntanglingCircuitBlock (weights[, …]) 
An individual block of a strongly entangling circuit. 
CVNeuralNet (weights, wires) 
A CV Quantum Neural Network 
CVNeuralNetLayer (theta_1, phi_1, varphi_1, …) 
A single layer of a CV Quantum Neural Network 
Interferometer (theta, phi, varphi, wires) 
General linear interferometer. 
Code details¶

StronglyEntanglingCircuit
(weights, periodic=True, ranges=None, imprimitive=qml.CNOT, wires)[source]¶ A strongly entangling circuit.
Constructs the strongly entangling circuit used in the circuitcentric quantum classifier [R2] with
len(weights)
blocks on the \(N\) wires with the provided weights. Each element of weights must be a an array of size \(3N\).Parameters:  weights (array[float]) – shape
(len(weights), len(wires), 3)
array of weights  periodic (bool) – whether to use periodic boundary conditions when applying imprimitive gates
 ranges (Sequence[int]) – ranges of the imprimitive gates in the respective blocks
 imprimitive (pennylane.ops.Operation) – imprimitive gate to use,
defaults to
CNOT
Keyword Arguments: wires (Sequence[int]) – wires the strongly entangling circuit should act on
 weights (array[float]) – shape

StronglyEntanglingCircuitBlock
(weights, periodic=True, r=1, imprimitive=qml.CNOT, wires)[source]¶ An individual block of a strongly entangling circuit.
Parameters:  weights (array[float]) – shape
(len(wires), 3)
array of weights  periodic (bool) – whether to use periodic boundary conditions when applying imprimitive gates
 r (Sequence[int]) – range of the imprimitive gates of this block
 imprimitive (pennylane.ops.Operation) – Imprimitive gate to use,
defaults to
CNOT
Keyword Arguments: wires (Sequence[int]) – Wires the block should act on
 weights (array[float]) – shape

CVNeuralNet
(weights, wires)[source]¶ A CV Quantum Neural Network
Implements the CV Quantum Neural Network (CVQNN) architecture from [R3] for an arbitrary number of wires and layers.
The weights parameter is a nested list. Its first dimension is equal to the number of layers. Each entry is again a list that contains the parameters feeding into
CVNeuralNetLayer()
.Parameters: weights (array[array]) – array of arrays of weights for each layer of the CV neural network Keyword Arguments: wires (Sequence[int]) – wires the CVQNN should act on

CVNeuralNetLayer
(theta_1, phi_1, varphi_1, r, phi_r, theta_2, phi_2, varphi_2, a, phi_a, k, wires)[source]¶ A single layer of a CV Quantum Neural Network
Implements a single layer from the the CV Quantum Neural Network (CVQNN) architecture of [R3] over \(N\) wires.
Note
The CV neural network architecture includes
Kerr
operations. Make sure to use a suitable device, such as thestrawberryfields.fock
device of the PennyLaneSF plugin.Parameters:  theta_1 (array[float]) – length \(N(N1)/2\) array of transmittivity angles for first interferometer
 phi_1 (array[float]) – length \(N(N1)/2\) array of phase angles for first interferometer
 varphi_1 (array[float]) – length \(N\) array of final rotation angles for first interferometer
 r (array[float]) – length \(N\) arrays of squeezing amounts for
Squeezing
operations  phi_r (array[float]) – length \(N\) arrays of squeezing angles for
Squeezing
operations  theta_2 (array[float]) – length \(N(N1)/2\) array of transmittivity angles for second interferometer
 phi_2 (array[float]) – length \(N(N1)/2\) array of phase angles for second interferometer
 varphi_2 (array[float]) – length \(N\) array of final rotation angles for second interferometer
 a (array[float]) – length \(N\) arrays of displacement magnitudes for
Displacement
operations  phi_a (array[float]) – length \(N\) arrays of displacement angles for
Displacement
operations  k (array[float]) – length \(N\) arrays of kerr parameters for
Kerr
operations
Keyword Arguments: wires (Sequence[int]) – wires the layer should act on

Interferometer
(theta, phi, varphi, wires)[source]¶ General linear interferometer.
For \(N\) wires, the general interferometer is specified by providing \(N(N1)\) transmittivity angles \(\theta\) and the same number of phase angles \(\phi\), as well as either \(N1\) or \(N\) additional rotation parameters \(\varphi\).
For the parametrization of a universal interferometer \(N1\) such rotation parameters are sufficient. If \(N\) rotation parameters are given, the interferometer is over parametrized, but the resulting circuit is more symmetric, which can be advantageous.
By specifying the keyword argument
mesh
, the scheme used to implement the interferometer may be adjusted:mesh='rectangular'
(default): uses the scheme described in [R4], resulting in a rectangular array of \(N(N1)/2\) beamsplitters arranged in \(N\) layers and numbered from left to right and top to bottom in each layer. The first beamsplitters acts on wires \(0\) and \(1\).mesh='triangular'
: uses the scheme described in [R5], resulting in a triangular array of \(N(N1)/2\) beamsplitters arranged in \(2N3\) layers and numbered from left to right and top to bottom. The first and forth beamsplitters act on wires \(N1\) and \(N\), the second on \(N2\) and \(N1\), and the third on \(N3\) and \(N2\), and so on.
In both schemes, the network of
Beamsplitter
operations is followed by \(N\) (or \(N1\)) localRotation
Operations. In the latter case, the rotation on the last wire is left out.The rectangular decomposition is generally advantageous, as it has a lower circuit depth (\(N\) vs \(2N3\)) and optical depth than the triangular decomposition, resulting in reduced optical loss.
Note
The decomposition as formulated in [R4] uses a different convention for a beamsplitter \(T(\theta, \phi)\) than PennyLane, namely:
\[T(\theta, \phi) = BS(\theta, 0) R(\phi)\]For the universality of the decomposition, the used convention is irrelevant, but for a given set of angles the resulting interferometers will be different.
If an interferometer consistent with the convention from [R4] is needed, the optional keyword argument
beamsplitter='clements'
can be specified. This will result in eachBeamsplitter
being preceded by aRotation
and thus increase the number of elementary operations in the circuit.Parameters:  theta (array) – length \(N(N1)/2\) array of transmittivity angles \(\theta\)
 phi (array) – length \(N(N1)/2\) array of phase angles \(\phi\)
 varphi (array) – length \(N\) or \(N1\) array of rotation angles \(\varphi\)
Keyword Arguments:  mesh (string) – the type of mesh to use
 beamsplitter (str) – if
clements
, the beamsplitter convention from Clements et al. 2016 (https://dx.doi.org/10.1364/OPTICA.3.001460) is used  wires (Sequence[int]) – wires the interferometer should act on