Hi everyone! We’re very happy to announce the release of PennyLane version 0.9.0.
This release contains a lot of new exciting features; including new machine learning integrations with Keras, faster simulation evaluations, new templates, and new quantum-aware optimizers to minimize your quantum function of choice.
New machine learning integrations
Easily construct a hybrid machine learning model using the new KerasLayer
class!
Code example
from pennylane.qnn import KerasLayer
@qml.qnode(dev)
def circuit(inputs, weights_0, weight_1):
# define the circuit
# ...
weight_shapes = {"weights_0": 3, "weight_1": 1}
qlayer = qml.qnn.KerasLayer(circuit, weight_shapes, output_dim=2)
model = tf.keras.models.Sequential([qlayer, tf.keras.layers.Dense(2)])
Use the new “backprop”
differentiation method with the qnode
decorator to utilize end-to-end differentiability when creating a circuit with a compatible simulator (supported by PennyLane’s default.tensor.tf
device backend).
Code example
dev = qml.device("default.tensor.tf", wires=1)
@qml.qnode(dev, interface="tf", diff_method="backprop")
def circuit(x):
qml.RX(x[1], wires=0)
qml.Rot(x[0], x[1], x[2], wires=0)
return qml.expval(qml.PauliZ(0))
vars = tf.Variable([0.2, 0.5, 0.1])
with tf.GradientTape() as tape:
res = circuit(vars)
tape.gradient(res, vars)
New gradient-free optimizers
Try out the new gradient-free qml.RotosolveOptimizer
that optimizes circuits by updating each parameter one-at-a-time. Alternatively, using the qml.RotoselectOptimizer
, it’s also possible to optimize both the applied rotation operations and their parameters.
Rotosolve code example
Initialize the optimizer, set the initial values of x
to be used and set the number of steps to optimize over.
>>> opt = qml.optimize.RotosolveOptimizer()
>>> x = [0.3, 0.7]
>>> n_steps = 1000
>>> dev = qml.device("default.qubit", analytic=True, wires=2)
... @qml.qnode(dev)
... def circuit(params):
... qml.RX(params[0], wires=0)
... qml.RY(params[1], wires=1)
... qml.CNOT(wires=[0, 1])
... return qml.expval(qml.PauliY(0)), qml.expval(qml.PauliZ(1))
Define a cost function (that takes a list of values as input and return a single value) based on the above circuit.
>>> def cost(x):
... Y_1, Z_2 = circuit(x)
... return 0.2 * Y_1 + 0.5 * Z_2
>>> cost_rotosel = []
>>> for _ in range(n_steps):
... cost_rotosel.append(cost(x))
... x = opt.step(cost, x)
The optimized values for x should now be stored in x
and steps-vs-cost can be seen by plotting cost_rotosel
.
For more information, and an example using the Rotoselect optimizer, see the documentation pages for qml.Rotosolve
and qml.Rotoselect
.
Faster simulator evaluations with new operations
The new DiagonalQubitUnitary
— encountered in, for example, IQP circuits— allows faster execution on simulator devices. Further operations such as the PauliRot
and MultiRZ
operations have been added.
New templates using broadcasting
The new qml.broadcast()
function allows templates to be constructed easily. New templates such as ArbitraryUnitary
, ArbitraryStatePreparation
and IQPEmbedding
have been added using broadcasting.
Other new features include improved speed and performance of the default.qubit
device and an improved circuit drawer.
We have also carried out a redesign of our plugin documentation! Check out the fresh new look of the Qiskit, Cirq and Strawberry Fields plugin docs.
The full release notes are available at Release notes — PennyLane 0.27.0 documentation.
As always, this release would not have been possible without all the help from our contributors:
Ville Bergholm, Lana Bozanic, @Tom_Bromley, @theodor, @josh, @nathan, Maggie Li, @johannesjmeyer, @Maria_Schuld, Sukin Sim @antalszava