This repository has been archived by the owner on Aug 18, 2023. It is now read-only.
Overall, this release is a rewrite of most of the library. These changes realize significant increases in code simplicity, modularity, and generality.
Stages in QHBM Library development
The changes can be understood by reviewing the history of the structure of the library:
Version 0.1.0
- This initial version of the library had all EBM and QNN functionality embedded in one large QHBM class. This kithcen-sink class had separate management for each of the components of a QHBM: the EBM and its parameters
thetas
, and the QNN and its parametersphis
. Only a single 1Dtf.Variable
could be used for each ofthetas
andphis
. This class was a direct lifting of the mathematical definition of a QHBM into code. - There was no ability to use
tf.GradientTape()
to take derivatives of the VQT and QMHL loss; instead, there were separate functions for the forward pass and it's derivative, that the user had to call manually to implement gradient descent.
Versions 0.2.0 and 0.2.1
- Unbundled EBMs and QNNs from the QHBM class to be viable on their own. This simplified the construction of QHBMs, since EBMs and QNNs could now be built individually, then composed to form a QHBM. However, building new EBMs was still a heavy process; a whole new class had to be implemented for each energy function the user might wish to define.
- Here we upgraded the VQT and QMHL losses into functions which could be differentiated using standard
tf.GradientTape()
methods. However, their implementations were not very general; for example, VQT could only accept Hamiltonians specified ascirq.PauliSum
. There are many cases where it is desirable to instead express observables directly in terms of a quantum circuit plus a function defining the spectrum of the observable.
Version 0.3.0
- This release takes inspiration from the distinction between model and inference to further modularize and simplify the structure of the code. Given some problem to solve in machine learning, here is how we think about the distinction:
- model: a representation of some structure assumed to be present in the problem. For example, when trying to learn a probability distribution, an energy function is a model: the structure it represents is the relative probabilities of samples from the probability distribution you are trying to learn. Models are typically parameterized so that they can be updated to better represent the actual structure present in the problem.
- inference: a process for obtaining results from a model. For example, MCMC is a process which obtains samples from the probability distribution corresponding to an energy function.
- To support this distinction, we now provide a
models
subpackage for defining energy functions and quantum circuits. Separately, we now provide aninference
subpackage for defining EBMs (classes for sampling according to an energy function) and QNNs (classes for measuring observables at the output of a given quantum circuit). - Further theoretical analysis revealed to us that the derivatives of VQT and QMHL losses could be composed from more general derivatives of the underlying computations. This means the VQT and QMHL functions do not need to define their own custom gradients anymore. Instead, the more general derivatives of log partition functions and EBM expectation values are implemented.
New features
Below we list in finer granularity some of the improvements made in this release.
models
subpackage- Classical models
BitstringEnergy
class, for defining an energy function as a stack oftf.keras.layers.Layer
instances.- Two hardcoded subclasses,
BernoulliEnergy
for representing a tensor product of Bernoullis andKOBE
for representing Kth order binary energy functions.
- Quantum models
QuantumCircuit
class, for defining unitary transformations. This is an abstraction layer on top of TensorFlow Quantum. As a benefit of this abstraction, users are able to add and invert circuits, while the underlying class manages tracking all associated variables, symbols, and circuit tensors. Sort of like a generalization of the PQC layer in TFQ.DirectQuantumCircuit
class, for automatically upgrading a parameterizedcirq.Circuit
into aQuantumCircuit
.
- Hybrid models
Hamiltonian
class for representing general observables. This class accepts aBitstringEnergy
to represent eigenvalues, and aQuantumCircuit
to represent eigenvectors.
- Classical models
inference
subpackage- Classical inference
EnergyInference
is a base class for working with probability distributions corresponding toBitstringEnergy
models. In other words, this class is an EBM. A critical feature is its ability to take derivatives: given a functionf
acting on samplesx
from the EBM, this class can take the derivative off(x)
with respect to both the variables off
and the variables of theBitstringEnergy
defining this EBM.AnalyticEnergyInference
class for exact sampling from anyBitstringEnergy
(subject to memory constraints on the number of bits). Works by calculating the probability of every bitstring, then sampling them as a categorical distribution.BernoulliEnergyInference
class for exact sampling fromBernoulliEnergy
models.probabilities
function for calculating the vector of probabilities corresponding to a givenBitstringEnergy
model.
- Quantum inference
QuantumInference
class for encapsulating the circuit, symbol name, symbol value, and observable management required for expectation calculation with TFQ. Enables measuring some kinds ofHamiltonian
s beyond simplecirq.PauliSum
s.unitary
function for calculating the unitary matrix represented by a givenQuantumCircuit
.
- Hybrid inference
QHBM
class. Here is where all the pieces come together. It is initialized with anEnergyInference
andQuantumCircuit
instance. It enables measuring the expectation values of observables against QHBMs. The modular Hamiltonian corresponding to the QHBM is an property ofQHBM
returned as aHamiltonian
class.density_matrix
function for calculating the matrix corresponding to a givenQHBM
, useful for numerics when the number of qubits is small enough.fidelity
function for calculating the fidelity between aQHBM
and a density matrix. Again, useful for numerics when the number of qubits is small enough.
- Losses
vqt
function for calculating the VQT loss given aQHBM
, a hamiltonian, and an inverse temperature. Fully differentiable intf.GradientTape()
contexts.qmhl
function for calculating the QMHL loss between aQuantumData
and aQHBM
. Fully differentiable intf.GradientTape()
contexts.
- Classical inference
data
subpackageQuantumData
class for encapsulating any sources of data to which we have quantum processing access.QHBMData
class for defining a source of quantum data as the output from a QHBM.
- Other improvements
- Enabled
yapf
lint checks for pull requests. - Added a nightly build publisher, triggered on merges into the
main
branch. - updated TFQ dependency to latest version, 0.6.1
- Enabled
Breaking changes
Note that almost all APIs have been changed and simplified. See the test cases for examples of usage. As well, keep an eye out for our upcoming baselines
release (issue #197), where we will showcase some of our research code.
Further details
Full commit list
- Enable differentiation through hypernetworks by @sahilpatelsp in #96
- Utilities for modular Hamiltonian expectation by @zaqqwerty in #97
- Fix the internal test error. by @jaeyoo in #98
- Updated links in documentation + instructions on how to add reviewers by @thubregtsen in #103
- Added two examples: qmhl and vqt by @thubregtsen in #102
- Reverts erroneous changes by @farice in #107
- Add automatic dev version publisher by @zaqqwerty in #108
- Separate EBM by @zaqqwerty in #111
- Add yapf linter step and make CI explicit by @jaeyoo in #116
- Fix lint error for loss function argument by @jaeyoo in #118
- Remove lint from energy files by @zaqqwerty in #121
- Separate QNN by @zaqqwerty in #113
- QuantumCircuit addition and inversion by @zaqqwerty in #122
- Make models arguments to inference engines by @zaqqwerty in #124
- Hamiltonian tracing by @zaqqwerty in #156
- EnergyInference expectation method derivative by @zaqqwerty in #151
- Upgrade TFQ version to 0.6.1 by @zaqqwerty in #160
- Generalize EnergyInfer expectation by @zaqqwerty in #169
- VQT by @zaqqwerty in #163
- Add inverse to unique_bitstrings_with_counts by @zaqqwerty in #177
- Energy inference cleanup by @zaqqwerty in #174
- Remove counts argument from inference calls by @zaqqwerty in #175
- Log partition estimator and derivative by @zaqqwerty in #180
- Move operator expectations to QuantumInference by @zaqqwerty in #179
- Automate inference and make models arguments to inference engines by @zaqqwerty in #181
- Fidelity for new style QHBMs by @zaqqwerty in #187
- Add derivative tests to circuit by @zaqqwerty in #188
- QMHL by @zaqqwerty in #189
- Architecture refresh by @zaqqwerty in #191
- Remove old code, bump working version by @zaqqwerty in #192
- Update docs by @zaqqwerty in #193
- Organize into submodules by @zaqqwerty in #196
New Contributors
- @thubregtsen made their first contribution in #103