Skip to content

Tools for quantum machine learning

Qadence offers a wide range of utilities for helping building and researching quantum machine learning algorithms, including:

  • a set of constructors for circuits commonly used in quantum machine learning
  • a set of tools for optimizing quantum neural networks and loading classical data into a QML algorithm

Quantum machine learning constructors

Besides the arbitrary Hamiltonian constructors, Qadence also provides a complete set of program constructors useful for digital-analog quantum machine learning programs.

Feature maps

A few feature maps are directly available for loading classical data into quantum circuits by encoding them into gate rotation angles.

from qadence import feature_map

n_qubits = 3

fm = feature_map(n_qubits, fm_type="fourier")

fm = feature_map(n_qubits, fm_type="chebyshev")

fm = feature_map(n_qubits, fm_type="tower")
Fourier = KronBlock(0,1,2) [tag: FM]
├── RX(0) [params: ['phi']]
├── RX(1) [params: ['phi']]
└── RX(2) [params: ['phi']]
Chebyshev KronBlock(0,1,2) [tag: FM]
├── RX(0) [params: ['2*acos(phi)']]
├── RX(1) [params: ['2*acos(phi)']]
└── RX(2) [params: ['2*acos(phi)']]
Tower KronBlock(0,1,2) [tag: FM]
├── RX(0) [params: ['2*acos(phi)']]
├── RX(1) [params: ['4*acos(phi)']]
└── RX(2) [params: ['6*acos(phi)']]

Hardware-efficient ansatz

Ansatze blocks for quantum machine-learning are typically built following the Hardware-Efficient Ansatz formalism (HEA). Both fully digital and digital-analog HEAs can easily be built with the hea function. By default, the digital version is returned:

from qadence import hea
from qadence.draw import display

n_qubits = 3
depth = 2

ansatz = hea(n_qubits, depth)
622feef30d8a4d6493d44f2fde8a18a3 0 1f4404494a6d443d9be0da753f2ae8e6 RX(theta₀) 622feef30d8a4d6493d44f2fde8a18a3--1f4404494a6d443d9be0da753f2ae8e6 6395ae7f353b40daac3a4a7da57e6a50 1 8c80f7a4da534ed1ba6da41f8077868d RY(theta₃) 1f4404494a6d443d9be0da753f2ae8e6--8c80f7a4da534ed1ba6da41f8077868d 71560ab892e648bba018ac71cb53a2d4 RX(theta₆) 8c80f7a4da534ed1ba6da41f8077868d--71560ab892e648bba018ac71cb53a2d4 ab0c7c7a2d3a441c9b4b40e00d79c7cf 71560ab892e648bba018ac71cb53a2d4--ab0c7c7a2d3a441c9b4b40e00d79c7cf 0dc1cc0bf99643839c22ce435d672e99 ab0c7c7a2d3a441c9b4b40e00d79c7cf--0dc1cc0bf99643839c22ce435d672e99 f4abff9ab83645c6b2ce6a3d26d7c7da RX(theta₉) 0dc1cc0bf99643839c22ce435d672e99--f4abff9ab83645c6b2ce6a3d26d7c7da 6dbc1518b6654507bc47627beaff9424 RY(theta₁₂) f4abff9ab83645c6b2ce6a3d26d7c7da--6dbc1518b6654507bc47627beaff9424 cfd16eeb9cbe4084927ce121fda2fa00 RX(theta₁₅) 6dbc1518b6654507bc47627beaff9424--cfd16eeb9cbe4084927ce121fda2fa00 8221018ecd13405c909cde2726d613e6 cfd16eeb9cbe4084927ce121fda2fa00--8221018ecd13405c909cde2726d613e6 368162926fa7422fba2952fdf1984ddf 8221018ecd13405c909cde2726d613e6--368162926fa7422fba2952fdf1984ddf 31cee3e31eb04a77a305c17068efee5d 368162926fa7422fba2952fdf1984ddf--31cee3e31eb04a77a305c17068efee5d 9d7f7b6fc22d4b049cf2db86b464afdf fe051f1789ee4fadbed4c14633cc2562 RX(theta₁) 6395ae7f353b40daac3a4a7da57e6a50--fe051f1789ee4fadbed4c14633cc2562 6b33b6a9d0eb4c3192275a0b7c7222e9 2 c984bf60885d480e8e29cf8fb4362eb4 RY(theta₄) fe051f1789ee4fadbed4c14633cc2562--c984bf60885d480e8e29cf8fb4362eb4 22b591bb0d29473e8431399072a8436f RX(theta₇) c984bf60885d480e8e29cf8fb4362eb4--22b591bb0d29473e8431399072a8436f 75709bba5d944105901d8ae59c395b68 X 22b591bb0d29473e8431399072a8436f--75709bba5d944105901d8ae59c395b68 75709bba5d944105901d8ae59c395b68--ab0c7c7a2d3a441c9b4b40e00d79c7cf 85fd1cf003a3485284d066385012e7a4 75709bba5d944105901d8ae59c395b68--85fd1cf003a3485284d066385012e7a4 03d0effada764cd0915bd641e3e75a73 RX(theta₁₀) 85fd1cf003a3485284d066385012e7a4--03d0effada764cd0915bd641e3e75a73 f5d50f487a7a4b44b9bdf8a6d66885ad RY(theta₁₃) 03d0effada764cd0915bd641e3e75a73--f5d50f487a7a4b44b9bdf8a6d66885ad 2131c176a8534709a72c295da2f0cb8e RX(theta₁₆) f5d50f487a7a4b44b9bdf8a6d66885ad--2131c176a8534709a72c295da2f0cb8e 3361fcbafdad4e45a8f56d19e9031bcb X 2131c176a8534709a72c295da2f0cb8e--3361fcbafdad4e45a8f56d19e9031bcb 3361fcbafdad4e45a8f56d19e9031bcb--8221018ecd13405c909cde2726d613e6 6e84e91f4e434e31b107a1e028f1bd5f 3361fcbafdad4e45a8f56d19e9031bcb--6e84e91f4e434e31b107a1e028f1bd5f 6e84e91f4e434e31b107a1e028f1bd5f--9d7f7b6fc22d4b049cf2db86b464afdf b5025f61d32245a7965ecc7e73e323f4 0a0ab8f820e74a2189814439e55b7d18 RX(theta₂) 6b33b6a9d0eb4c3192275a0b7c7222e9--0a0ab8f820e74a2189814439e55b7d18 09ada421ca994316a6eedc4658fb9590 RY(theta₅) 0a0ab8f820e74a2189814439e55b7d18--09ada421ca994316a6eedc4658fb9590 e3b69610d1cb442d9119d5c306a6b11c RX(theta₈) 09ada421ca994316a6eedc4658fb9590--e3b69610d1cb442d9119d5c306a6b11c 54b2d65b32e94ca6afd0c5c205271924 e3b69610d1cb442d9119d5c306a6b11c--54b2d65b32e94ca6afd0c5c205271924 493ba1513c4b404f81d5e2cf3bcecc71 X 54b2d65b32e94ca6afd0c5c205271924--493ba1513c4b404f81d5e2cf3bcecc71 493ba1513c4b404f81d5e2cf3bcecc71--85fd1cf003a3485284d066385012e7a4 6ad009dcab7b4e25b36167be391ac269 RX(theta₁₁) 493ba1513c4b404f81d5e2cf3bcecc71--6ad009dcab7b4e25b36167be391ac269 b0e58b85c7cd44b89176e49e158d9214 RY(theta₁₄) 6ad009dcab7b4e25b36167be391ac269--b0e58b85c7cd44b89176e49e158d9214 d81a52257e1741d59a3cdee68ed99924 RX(theta₁₇) b0e58b85c7cd44b89176e49e158d9214--d81a52257e1741d59a3cdee68ed99924 1c4c7d000c3f4b7e8c2ef8b5b1073e3c d81a52257e1741d59a3cdee68ed99924--1c4c7d000c3f4b7e8c2ef8b5b1073e3c 3ccac1afdfef4cf5a6e08bad5f9ec79a X 1c4c7d000c3f4b7e8c2ef8b5b1073e3c--3ccac1afdfef4cf5a6e08bad5f9ec79a 3ccac1afdfef4cf5a6e08bad5f9ec79a--6e84e91f4e434e31b107a1e028f1bd5f 3ccac1afdfef4cf5a6e08bad5f9ec79a--b5025f61d32245a7965ecc7e73e323f4

As seen above, the rotation layers are automatically parameterized, and the prefix "theta" can be changed with the param_prefix argument.

Furthermore, both the single-qubit rotations and the two-qubit entangler can be customized with the operations and entangler argument. The operations can be passed as a list of single-qubit rotations, while the entangler should be either CNOT, CZ, CRX, CRY, CRZ or CPHASE.

from qadence import RX, RY, CPHASE

ansatz = hea(
    n_qubits=n_qubits,
    depth=depth,
    param_prefix="phi",
    operations=[RX, RY, RX],
    entangler=CPHASE
)
a4b52d2a399944ec9be663302f52d6a5 0 8d3a44e34dc04dea93fb1e82ff37a871 RX(phi₀) a4b52d2a399944ec9be663302f52d6a5--8d3a44e34dc04dea93fb1e82ff37a871 5e2d630eb28947349819e7bcba5be87c 1 556fe39e8e1845d2a8083a9c9e21014d RY(phi₃) 8d3a44e34dc04dea93fb1e82ff37a871--556fe39e8e1845d2a8083a9c9e21014d 62898afa815548b8ae10e5a75fb45139 RX(phi₆) 556fe39e8e1845d2a8083a9c9e21014d--62898afa815548b8ae10e5a75fb45139 2de9d1676da842219faf73a78b9cb2e8 62898afa815548b8ae10e5a75fb45139--2de9d1676da842219faf73a78b9cb2e8 9a2ca2c6db7b4ef58276cc526960cda9 2de9d1676da842219faf73a78b9cb2e8--9a2ca2c6db7b4ef58276cc526960cda9 5c78ff51d96446f9b02538931af4d408 RX(phi₉) 9a2ca2c6db7b4ef58276cc526960cda9--5c78ff51d96446f9b02538931af4d408 4acc53f420b14e48b1f73428201202c5 RY(phi₁₂) 5c78ff51d96446f9b02538931af4d408--4acc53f420b14e48b1f73428201202c5 18390dd62b2a438b955e0cef275cdcb1 RX(phi₁₅) 4acc53f420b14e48b1f73428201202c5--18390dd62b2a438b955e0cef275cdcb1 97fd51b966b0439d99a4a3ff9b847ba8 18390dd62b2a438b955e0cef275cdcb1--97fd51b966b0439d99a4a3ff9b847ba8 64cdb8eb4abf487295aa518329f1ba44 97fd51b966b0439d99a4a3ff9b847ba8--64cdb8eb4abf487295aa518329f1ba44 494e1834f23c46d9964d69eadddea4f7 64cdb8eb4abf487295aa518329f1ba44--494e1834f23c46d9964d69eadddea4f7 a6326bc18ec446afba0754995aefabd0 210e943f65d24eec9af45f68095623b7 RX(phi₁) 5e2d630eb28947349819e7bcba5be87c--210e943f65d24eec9af45f68095623b7 7fd5be94eb8d4ef3b308e8c6d6a0c562 2 00aad3e8f9e64105938ece704fa0380d RY(phi₄) 210e943f65d24eec9af45f68095623b7--00aad3e8f9e64105938ece704fa0380d 8adaf31cfe46461c9d387b553da16c3a RX(phi₇) 00aad3e8f9e64105938ece704fa0380d--8adaf31cfe46461c9d387b553da16c3a 6b8315cd2d0b4222833f680e08264bb1 PHASE(phi_ent₀) 8adaf31cfe46461c9d387b553da16c3a--6b8315cd2d0b4222833f680e08264bb1 6b8315cd2d0b4222833f680e08264bb1--2de9d1676da842219faf73a78b9cb2e8 32aba4695b0b4800ac873e166bd2188a 6b8315cd2d0b4222833f680e08264bb1--32aba4695b0b4800ac873e166bd2188a ccb95a36325c4544a57924ee900ef73e RX(phi₁₀) 32aba4695b0b4800ac873e166bd2188a--ccb95a36325c4544a57924ee900ef73e c179ba746333447d9c1385045de3fb05 RY(phi₁₃) ccb95a36325c4544a57924ee900ef73e--c179ba746333447d9c1385045de3fb05 a87d432c4c454f0da91ad9333b3b4d48 RX(phi₁₆) c179ba746333447d9c1385045de3fb05--a87d432c4c454f0da91ad9333b3b4d48 85a4a9358cf84cc1850cc4e3c7da5521 PHASE(phi_ent₂) a87d432c4c454f0da91ad9333b3b4d48--85a4a9358cf84cc1850cc4e3c7da5521 85a4a9358cf84cc1850cc4e3c7da5521--97fd51b966b0439d99a4a3ff9b847ba8 96c22d53307a4d3a8295b1f9ff8008c5 85a4a9358cf84cc1850cc4e3c7da5521--96c22d53307a4d3a8295b1f9ff8008c5 96c22d53307a4d3a8295b1f9ff8008c5--a6326bc18ec446afba0754995aefabd0 11b54cdc11814ffabb191c4e21250e0d f7cd6d058e6741699269fa9b755ae2b4 RX(phi₂) 7fd5be94eb8d4ef3b308e8c6d6a0c562--f7cd6d058e6741699269fa9b755ae2b4 49acead36d884fd784e7fe5da44850fd RY(phi₅) f7cd6d058e6741699269fa9b755ae2b4--49acead36d884fd784e7fe5da44850fd c1d36f57b35c407ca09e01d4c1143aac RX(phi₈) 49acead36d884fd784e7fe5da44850fd--c1d36f57b35c407ca09e01d4c1143aac dcfd6269d55441e1a97946ebc9c899ce c1d36f57b35c407ca09e01d4c1143aac--dcfd6269d55441e1a97946ebc9c899ce e272d93529c94130904f55cafc7ad910 PHASE(phi_ent₁) dcfd6269d55441e1a97946ebc9c899ce--e272d93529c94130904f55cafc7ad910 e272d93529c94130904f55cafc7ad910--32aba4695b0b4800ac873e166bd2188a bd4fa5e9122647d8b6614e138219e683 RX(phi₁₁) e272d93529c94130904f55cafc7ad910--bd4fa5e9122647d8b6614e138219e683 bc49d19745524af98f7e66c58d5526e8 RY(phi₁₄) bd4fa5e9122647d8b6614e138219e683--bc49d19745524af98f7e66c58d5526e8 3e26612cc4b64d3292bb06dc9fbc5f42 RX(phi₁₇) bc49d19745524af98f7e66c58d5526e8--3e26612cc4b64d3292bb06dc9fbc5f42 e9424182ce234450a5eef50d6536fd4e 3e26612cc4b64d3292bb06dc9fbc5f42--e9424182ce234450a5eef50d6536fd4e 446da6fcb38e45d38b41d9b6fd7106e9 PHASE(phi_ent₃) e9424182ce234450a5eef50d6536fd4e--446da6fcb38e45d38b41d9b6fd7106e9 446da6fcb38e45d38b41d9b6fd7106e9--96c22d53307a4d3a8295b1f9ff8008c5 446da6fcb38e45d38b41d9b6fd7106e9--11b54cdc11814ffabb191c4e21250e0d

Having a truly hardware-efficient ansatz means that the entangling operation can be chosen according to each device's native interactions. Besides digital operations, in Qadence it is also possible to build digital-analog HEAs with the entanglement produced by the natural evolution of a set of interacting qubits, as natively implemented in neutral atom devices. As with other digital-analog functions, this can be controlled with the strategy argument which can be chosen from the Strategy enum type. Currently, only Strategy.DIGITAL and Strategy.SDAQC are available. By default, calling strategy = Strategy.SDAQC will use a global entangling Hamiltonian with Ising-like NN interactions and constant interaction strength,

from qadence import Strategy

ansatz = hea(
    n_qubits,
    depth=depth,
    strategy=Strategy.SDAQC
)
cluster_6d2fbec0eabf42799547d7ee8694056f cluster_ee8b081b7982489ebed16f9eabd95861 32a85a04ec924a51a6fea1549f2a2bc8 0 cc21087dbb0d4309ae814bb5a88390f8 RX(theta₀) 32a85a04ec924a51a6fea1549f2a2bc8--cc21087dbb0d4309ae814bb5a88390f8 3e15859bff2f434aaa4c2a4ff9cd0835 1 e55630d2d8a24e88a9e914a9d8831f10 RY(theta₃) cc21087dbb0d4309ae814bb5a88390f8--e55630d2d8a24e88a9e914a9d8831f10 41bcf2d64e9e4c1791272dfee753ebc4 RX(theta₆) e55630d2d8a24e88a9e914a9d8831f10--41bcf2d64e9e4c1791272dfee753ebc4 3582d00f029d4d1a91c88c5f8ad43d9b HamEvo 41bcf2d64e9e4c1791272dfee753ebc4--3582d00f029d4d1a91c88c5f8ad43d9b 095ab6a8f3e944bd8ee724cfe7561b56 RX(theta₉) 3582d00f029d4d1a91c88c5f8ad43d9b--095ab6a8f3e944bd8ee724cfe7561b56 ca3360a5b4ed4f34bad17a48b35690bb RY(theta₁₂) 095ab6a8f3e944bd8ee724cfe7561b56--ca3360a5b4ed4f34bad17a48b35690bb 6c27a29b72404c7f9ccf15d81476bf5c RX(theta₁₅) ca3360a5b4ed4f34bad17a48b35690bb--6c27a29b72404c7f9ccf15d81476bf5c 910fdfc44c164a0ba51808cc98c9a8cc HamEvo 6c27a29b72404c7f9ccf15d81476bf5c--910fdfc44c164a0ba51808cc98c9a8cc c461db1efa1c4dd1a5c9d1179c1c144e 910fdfc44c164a0ba51808cc98c9a8cc--c461db1efa1c4dd1a5c9d1179c1c144e 73a92b717a194d4ba96bb56f0f9fd54d cc91be9b3d264692b8a975534ee14f1a RX(theta₁) 3e15859bff2f434aaa4c2a4ff9cd0835--cc91be9b3d264692b8a975534ee14f1a 118f70fe0e1f43ebb59f5fe0e4514ec5 2 95cee1590ea84a4585bd8f510a5991a8 RY(theta₄) cc91be9b3d264692b8a975534ee14f1a--95cee1590ea84a4585bd8f510a5991a8 5a91cfdcc94f4e7685ddfea373ce2bce RX(theta₇) 95cee1590ea84a4585bd8f510a5991a8--5a91cfdcc94f4e7685ddfea373ce2bce f5bd8ca92be14aff87d84f0feb095839 t = theta_t₀ 5a91cfdcc94f4e7685ddfea373ce2bce--f5bd8ca92be14aff87d84f0feb095839 b4dedeef14b34bd5990fd6ab24bd7a9e RX(theta₁₀) f5bd8ca92be14aff87d84f0feb095839--b4dedeef14b34bd5990fd6ab24bd7a9e 2a6231d6454e4986b8098fff4dd54619 RY(theta₁₃) b4dedeef14b34bd5990fd6ab24bd7a9e--2a6231d6454e4986b8098fff4dd54619 8737af406e7c4c6895f4328ec6e38cae RX(theta₁₆) 2a6231d6454e4986b8098fff4dd54619--8737af406e7c4c6895f4328ec6e38cae 1239482b356f49088cba408bba14711d t = theta_t₁ 8737af406e7c4c6895f4328ec6e38cae--1239482b356f49088cba408bba14711d 1239482b356f49088cba408bba14711d--73a92b717a194d4ba96bb56f0f9fd54d 77eec7ec98444e6684d9f701d840ec9f 2e118e21492e4143b51803923745859f RX(theta₂) 118f70fe0e1f43ebb59f5fe0e4514ec5--2e118e21492e4143b51803923745859f b8b62fdf4cce4c1d9a73a2e46bbe18b9 RY(theta₅) 2e118e21492e4143b51803923745859f--b8b62fdf4cce4c1d9a73a2e46bbe18b9 b0da23f6095d4b11b0a0b9d3b8eadb72 RX(theta₈) b8b62fdf4cce4c1d9a73a2e46bbe18b9--b0da23f6095d4b11b0a0b9d3b8eadb72 0383dcd9df934cfc993ea02b38f56cb2 b0da23f6095d4b11b0a0b9d3b8eadb72--0383dcd9df934cfc993ea02b38f56cb2 4b8ba3483b104c02be8a8ecf43542444 RX(theta₁₁) 0383dcd9df934cfc993ea02b38f56cb2--4b8ba3483b104c02be8a8ecf43542444 c5d324764c3343118c87e0c5f2df9923 RY(theta₁₄) 4b8ba3483b104c02be8a8ecf43542444--c5d324764c3343118c87e0c5f2df9923 db9921ced6294e4dafa960e257a7ea5c RX(theta₁₇) c5d324764c3343118c87e0c5f2df9923--db9921ced6294e4dafa960e257a7ea5c b68ef10ac7e843ed81296735c08ea5ba db9921ced6294e4dafa960e257a7ea5c--b68ef10ac7e843ed81296735c08ea5ba b68ef10ac7e843ed81296735c08ea5ba--77eec7ec98444e6684d9f701d840ec9f

Note that, by default, only the time-parameter is automatically parameterized when building a digital-analog HEA. However, as described in the Hamiltonians tutorial, arbitrary interaction Hamiltonians can be easily built with the hamiltonian_factory function, with both customized or fully parameterized interactions, and these can be directly passed as the entangler for a customizable digital-analog HEA.

from qadence import hamiltonian_factory, Interaction, N, Register, hea

# Build a parameterized neutral-atom Hamiltonian following a honeycomb_lattice:
register = Register.honeycomb_lattice(1, 1)

entangler = hamiltonian_factory(
    register,
    interaction=Interaction.NN,
    detuning=N,
    interaction_strength="e",
    detuning_strength="n"
)

# Build a fully parameterized Digital-Analog HEA:
n_qubits = register.n_qubits
depth = 2

ansatz = hea(
    n_qubits=register.n_qubits,
    depth=depth,
    operations=[RX, RY, RX],
    entangler=entangler,
    strategy=Strategy.SDAQC
)
cluster_47eb5ea2199b4cc48e188c2ffac378ed cluster_11ce38057e354fcf896ec026b638a361 f4a6e73ef5a54ba29caf189444c84dc9 0 8a4ad4ef56f041a49d6f23105c9fc10a RX(theta₀) f4a6e73ef5a54ba29caf189444c84dc9--8a4ad4ef56f041a49d6f23105c9fc10a 5b3b42769c9647f3b5e8bb45f116e0f7 1 3f6c42976fda41bdaed1184b006b32bf RY(theta₆) 8a4ad4ef56f041a49d6f23105c9fc10a--3f6c42976fda41bdaed1184b006b32bf c15c114d94ab45fabf3abf4a4bdec85b RX(theta₁₂) 3f6c42976fda41bdaed1184b006b32bf--c15c114d94ab45fabf3abf4a4bdec85b 64ad0a69b77840589461bba86541f690 c15c114d94ab45fabf3abf4a4bdec85b--64ad0a69b77840589461bba86541f690 513444216735485fae228ddd60ca0494 RX(theta₁₈) 64ad0a69b77840589461bba86541f690--513444216735485fae228ddd60ca0494 87363798254d4b87b98acb06dac52d43 RY(theta₂₄) 513444216735485fae228ddd60ca0494--87363798254d4b87b98acb06dac52d43 4407df39ebef4739a014d113166e1466 RX(theta₃₀) 87363798254d4b87b98acb06dac52d43--4407df39ebef4739a014d113166e1466 828bfb664f3c4eb5b61a0be16a2ac2d8 4407df39ebef4739a014d113166e1466--828bfb664f3c4eb5b61a0be16a2ac2d8 b5ebbd4c5d7248768cdf0a5f05bc77cd 828bfb664f3c4eb5b61a0be16a2ac2d8--b5ebbd4c5d7248768cdf0a5f05bc77cd 4532cf59a59a46fcaff494d86e7a5e40 4d2fdc850eea4741a390c2b9f1ba568b RX(theta₁) 5b3b42769c9647f3b5e8bb45f116e0f7--4d2fdc850eea4741a390c2b9f1ba568b ccd5e8c0065a413f9b67bb589c410040 2 80aa8685696a47e0832c4d9da75c4ad3 RY(theta₇) 4d2fdc850eea4741a390c2b9f1ba568b--80aa8685696a47e0832c4d9da75c4ad3 9a5521aeecb240e791e3c494a5b47932 RX(theta₁₃) 80aa8685696a47e0832c4d9da75c4ad3--9a5521aeecb240e791e3c494a5b47932 a3f3d9da819b4855bd50bedf91d432c4 9a5521aeecb240e791e3c494a5b47932--a3f3d9da819b4855bd50bedf91d432c4 644499d08cd1497fbd58b777a10a9aca RX(theta₁₉) a3f3d9da819b4855bd50bedf91d432c4--644499d08cd1497fbd58b777a10a9aca 60e60ca0e46f4519b4e01c2f1e28aad0 RY(theta₂₅) 644499d08cd1497fbd58b777a10a9aca--60e60ca0e46f4519b4e01c2f1e28aad0 9b7490f33d4f469fa04cbaf5368ac990 RX(theta₃₁) 60e60ca0e46f4519b4e01c2f1e28aad0--9b7490f33d4f469fa04cbaf5368ac990 6b815cc3bc064606be5c7fe3e9aba551 9b7490f33d4f469fa04cbaf5368ac990--6b815cc3bc064606be5c7fe3e9aba551 6b815cc3bc064606be5c7fe3e9aba551--4532cf59a59a46fcaff494d86e7a5e40 00ee1b3417b7420abdf51db55cefafdf ccd4f7694b4e49b8a98f7b845478d275 RX(theta₂) ccd5e8c0065a413f9b67bb589c410040--ccd4f7694b4e49b8a98f7b845478d275 f70cfabd6b544c67a17f4807bc193413 3 73e2fc0999574697a6a8716d1905d1a7 RY(theta₈) ccd4f7694b4e49b8a98f7b845478d275--73e2fc0999574697a6a8716d1905d1a7 460d9b59e1ab4ce4a7c41f8413e580f0 RX(theta₁₄) 73e2fc0999574697a6a8716d1905d1a7--460d9b59e1ab4ce4a7c41f8413e580f0 b806d5b68ff64fce9f5890bc43419dcd HamEvo 460d9b59e1ab4ce4a7c41f8413e580f0--b806d5b68ff64fce9f5890bc43419dcd 329f94c7c50648748b36ab2011ff6772 RX(theta₂₀) b806d5b68ff64fce9f5890bc43419dcd--329f94c7c50648748b36ab2011ff6772 475b9dab845b472dbc84a3e1594e017e RY(theta₂₆) 329f94c7c50648748b36ab2011ff6772--475b9dab845b472dbc84a3e1594e017e 527d8819822144fba0f9f3b0faa634f4 RX(theta₃₂) 475b9dab845b472dbc84a3e1594e017e--527d8819822144fba0f9f3b0faa634f4 581993336f5e4840916a0dae53223277 HamEvo 527d8819822144fba0f9f3b0faa634f4--581993336f5e4840916a0dae53223277 581993336f5e4840916a0dae53223277--00ee1b3417b7420abdf51db55cefafdf 5eccc8f8cd114b369c31c97d848019ce 87baf968c28f41a0a87438f70ceb11cb RX(theta₃) f70cfabd6b544c67a17f4807bc193413--87baf968c28f41a0a87438f70ceb11cb e1baf87a71de4c1f8ee6f5893cd5e9b6 4 7f23d93630ad412eb0ce72d1a4929938 RY(theta₉) 87baf968c28f41a0a87438f70ceb11cb--7f23d93630ad412eb0ce72d1a4929938 c817d06d391947248f31a6d49f6cc76f RX(theta₁₅) 7f23d93630ad412eb0ce72d1a4929938--c817d06d391947248f31a6d49f6cc76f eee168a8611d4363a686435e391cbb8c t = theta_t₀ c817d06d391947248f31a6d49f6cc76f--eee168a8611d4363a686435e391cbb8c 85a26e7ef49e435e9e003ea885efc6a0 RX(theta₂₁) eee168a8611d4363a686435e391cbb8c--85a26e7ef49e435e9e003ea885efc6a0 c542dbbe9ce44a98a2b2b1d1638a0e82 RY(theta₂₇) 85a26e7ef49e435e9e003ea885efc6a0--c542dbbe9ce44a98a2b2b1d1638a0e82 8a9be436f8074a399d197198d70c597d RX(theta₃₃) c542dbbe9ce44a98a2b2b1d1638a0e82--8a9be436f8074a399d197198d70c597d f4a4df664dde4755adc934948f705664 t = theta_t₁ 8a9be436f8074a399d197198d70c597d--f4a4df664dde4755adc934948f705664 f4a4df664dde4755adc934948f705664--5eccc8f8cd114b369c31c97d848019ce df8f98f89dbd464dac3f3bbea670feb2 78718e87bb934b8e9ec5a118203ebafd RX(theta₄) e1baf87a71de4c1f8ee6f5893cd5e9b6--78718e87bb934b8e9ec5a118203ebafd 3e71c486e196422a9d7b915f442762a1 5 5819e7ff8cdf48f58995dc5f0e2f164a RY(theta₁₀) 78718e87bb934b8e9ec5a118203ebafd--5819e7ff8cdf48f58995dc5f0e2f164a e6fc99822f824e3c8431eaffbee2accf RX(theta₁₆) 5819e7ff8cdf48f58995dc5f0e2f164a--e6fc99822f824e3c8431eaffbee2accf d48e42f78bbb4015a4b2865aaa892175 e6fc99822f824e3c8431eaffbee2accf--d48e42f78bbb4015a4b2865aaa892175 dd8dd93c4d4846a1acb35e323ea0f74a RX(theta₂₂) d48e42f78bbb4015a4b2865aaa892175--dd8dd93c4d4846a1acb35e323ea0f74a e5ba47ba9012455a9fd661c4ce9239c2 RY(theta₂₈) dd8dd93c4d4846a1acb35e323ea0f74a--e5ba47ba9012455a9fd661c4ce9239c2 adb853ecf28742fda282747ca373674d RX(theta₃₄) e5ba47ba9012455a9fd661c4ce9239c2--adb853ecf28742fda282747ca373674d 5900b28fecd540679c8eb4f44d089f54 adb853ecf28742fda282747ca373674d--5900b28fecd540679c8eb4f44d089f54 5900b28fecd540679c8eb4f44d089f54--df8f98f89dbd464dac3f3bbea670feb2 43a7133820c24027ac6f3bfb0bf46f54 aa8ada6f0e154f7c8cc6248a94889299 RX(theta₅) 3e71c486e196422a9d7b915f442762a1--aa8ada6f0e154f7c8cc6248a94889299 f3d9324351304a5eaaf4de28ded958f2 RY(theta₁₁) aa8ada6f0e154f7c8cc6248a94889299--f3d9324351304a5eaaf4de28ded958f2 5ec3fdeaec604bea98c2e3ebad2ee59f RX(theta₁₇) f3d9324351304a5eaaf4de28ded958f2--5ec3fdeaec604bea98c2e3ebad2ee59f 8f2d43ac819f4e9b899486d829722d94 5ec3fdeaec604bea98c2e3ebad2ee59f--8f2d43ac819f4e9b899486d829722d94 176cedea53c24d4ebbc72f001a968baa RX(theta₂₃) 8f2d43ac819f4e9b899486d829722d94--176cedea53c24d4ebbc72f001a968baa 098a34ede78b4ad6873428783ffcd143 RY(theta₂₉) 176cedea53c24d4ebbc72f001a968baa--098a34ede78b4ad6873428783ffcd143 5adb73174c3745dabdcd3a9679f42e80 RX(theta₃₅) 098a34ede78b4ad6873428783ffcd143--5adb73174c3745dabdcd3a9679f42e80 ef1275088bf34b089311576515950d23 5adb73174c3745dabdcd3a9679f42e80--ef1275088bf34b089311576515950d23 ef1275088bf34b089311576515950d23--43a7133820c24027ac6f3bfb0bf46f54

Machine Learning Tools

Dataloaders

When using qadence, you can supply classical data to a quantum machine learning algorithm by using a standard PyTorch DataLoader instance. Qadence also provides the DictDataLoader convenience class which allows to build dictionaries of DataLoaders instances and easily iterate over them.

import torch
from torch.utils.data import DataLoader, TensorDataset
from qadence.ml_tools import DictDataLoader

def dataloader() -> DataLoader:
    batch_size = 5
    x = torch.linspace(0, 1, batch_size).reshape(-1, 1)
    y = torch.sin(x)

    dataset = TensorDataset(x, y)
    return DataLoader(dataset, batch_size=batch_size)


def dictdataloader() -> DictDataLoader:
    batch_size = 5

    keys = ["y1", "y2"]
    dls = {}
    for k in keys:
        x = torch.rand(batch_size, 1)
        y = torch.sin(x)
        dataset = TensorDataset(x, y)
        dataloader = DataLoader(dataset, batch_size=batch_size)
        dls[k] = dataloader

    return DictDataLoader(dls)

n_epochs = 2

# iterate standard DataLoader
dl = dataloader()
for i in range(n_epochs):
    data = next(iter(dl))

# iterate DictDataLoader
ddl = dictdataloader()
for i in range(n_epochs):
    data = next(iter(ddl))

Optimization routines

For training QML models, qadence also offers a few out-of-the-box routines for optimizing differentiable models like QNNs and QuantumModels containing either trainable and/or non-trainable parameters (you can refer to this for a refresh about different parameter types):

These routines performs training, logging/printing loss metrics and storing intermediate checkpoints of models. In the following, we use train_with_grad as example but the code can be used directly with the gradient-free routine.

As every other training routine commonly used in Machine Learning, it requires model, data and an optimizer as input arguments. However, in addition, it requires a loss_fn and a TrainConfig. A loss_fn is required to be a function which expects both a model and data and returns a tuple of (loss, metrics: <dict>), where metrics is a dict of scalars which can be customized too.

import torch
from itertools import count
cnt = count()
criterion = torch.nn.MSELoss()

def loss_fn(model: torch.nn.Module, data: torch.Tensor) -> tuple[torch.Tensor, dict]:
    next(cnt)
    x, y = data[0], data[1]
    out = model(x)
    loss = criterion(out, y)
    return loss, {}

The TrainConfig tells train_with_grad what batch_size should be used, how many epochs to train, in which intervals to print/log metrics and how often to store intermediate checkpoints.

from qadence.ml_tools import TrainConfig

batch_size = 5
n_epochs = 100

config = TrainConfig(
    folder="some_path/",
    max_iter=n_epochs,
    checkpoint_every=100,
    write_every=100,
    batch_size=batch_size,
)

Let's see it in action with a simple example.

Fitting a funtion with a QNN using ml_tools

Let's look at a complete example of how to use train_with_grad now.

from pathlib import Path
import torch
from itertools import count
from qadence.constructors import hamiltonian_factory, hea, feature_map
from qadence import chain, Parameter, QuantumCircuit, Z
from qadence.models import QNN
from qadence.ml_tools import train_with_grad, TrainConfig
import matplotlib.pyplot as plt

n_qubits = 2
fm = feature_map(n_qubits)
ansatz = hea(n_qubits=n_qubits, depth=3)
observable = hamiltonian_factory(n_qubits, detuning=Z)
circuit = QuantumCircuit(n_qubits, fm, ansatz)

model = QNN(circuit, observable, backend="pyqtorch", diff_mode="ad")
batch_size = 1
input_values = {"phi": torch.rand(batch_size, requires_grad=True)}
pred = model(input_values)

cnt = count()
criterion = torch.nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)

def loss_fn(model: torch.nn.Module, data: torch.Tensor) -> tuple[torch.Tensor, dict]:
    next(cnt)
    x, y = data[0], data[1]
    out = model(x)
    loss = criterion(out, y)
    return loss, {}

tmp_path = Path("/tmp")

n_epochs = 5

config = TrainConfig(
    folder=tmp_path,
    max_iter=n_epochs,
    checkpoint_every=100,
    write_every=100,
    batch_size=batch_size,
)

batch_size = 25

x = torch.linspace(0, 1, batch_size).reshape(-1, 1)
y = torch.sin(x)

train_with_grad(model, (x, y), optimizer, config, loss_fn=loss_fn)

plt.plot(y.numpy())
plt.plot(model(input_values).detach().numpy())

For users who want to use the low-level API of qadence, here is the example from above written without train_with_grad.

Fitting a function - Low-level API

from pathlib import Path
import torch
from itertools import count
from qadence.constructors import hamiltonian_factory, hea, feature_map
from qadence import chain, Parameter, QuantumCircuit, Z
from qadence.models import QNN
from qadence.ml_tools import train_with_grad, TrainConfig

n_qubits = 2
fm = feature_map(n_qubits)
ansatz = hea(n_qubits=n_qubits, depth=3)
observable = hamiltonian_factory(n_qubits, detuning=Z)
circuit = QuantumCircuit(n_qubits, fm, ansatz)

model = QNN(circuit, observable, backend="pyqtorch", diff_mode="ad")
batch_size = 1
input_values = {"phi": torch.rand(batch_size, requires_grad=True)}
pred = model(input_values)

criterion = torch.nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
n_epochs=50
cnt = count()

tmp_path = Path("/tmp")

config = TrainConfig(
    folder=tmp_path,
    max_iter=n_epochs,
    checkpoint_every=100,
    write_every=100,
    batch_size=batch_size,
)

x = torch.linspace(0, 1, batch_size).reshape(-1, 1)
y = torch.sin(x)

for i in range(n_epochs):
    out = model(x)
    loss = criterion(out, y)
    loss.backward()
    optimizer.step()