Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 5 additions & 49 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,51 +1,7 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
// For format details, see https://aka.ms/devcontainer.json.
{
"name": "Ocean Development Environment",

// python 3.11 on debian, with latest Ocean and optional packages
// source repo: https://github.com/dwavesystems/ocean-dev-docker
"image": "docker.io/dwavesys/ocean-dev:latest",

// install repo pip requirements (only if present) on content update
"updateContentCommand": "[ ! -r requirements.txt ] || pip install -r requirements.txt",

// forward/expose container services (relevant only when run locally)
"forwardPorts": [
// dwave-inspector web app
18000, 18001, 18002, 18003, 18004,
// OAuth connect redirect URIs
36000, 36001, 36002, 36003, 36004
],

"portsAttributes": {
"18000-18004": {
"label": "D-Wave Problem Inspector",
"requireLocalPort": true
},
"36000-36004": {
"label": "OAuth 2.0 authorization code redirect URI",
"requireLocalPort": true
}
},

// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"workbench": {
"editorAssociations": {
"*.md": "vscode.markdown.preview.editor"
},
"startupEditor": "readme"
}
},
"extensions": [
"ms-python.python",
"ms-toolsai.jupyter"
]
}
}
// Debian stable with the second-latest Python, latest Ocean, and optional dev packages.
// Docker image source: https://github.com/dwavesystems/ocean-dev-docker.
// Devcontainer config: https://github.com/dwavesystems/ocean-devcontainer.
"image": "docker.io/dwavesys/ocean-dev:latest"
}
24 changes: 24 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
Thanks for contributing a pull request! Please ensure that
your PR conforms to our contributor guide.
https://github.com/dwave-examples/template-dash/blob/main/CONTRIBUTING.md
-->

### Associated GitHub Issue
<!--If applicable. Example: Closes https://github.com/dwave-examples/template-dash/issues/X-->

### Feature Implemented/Bugs Fixed
<!--Please explain your changes.-->

### Additional Information
<!--Any additional information you think is important.-->

### Accessibility Score
<!--If the UI was significantly changed, what is the updated accessibility score?-->

### AI Generation Disclosure
<!-- If AI was used in the preparation of this pull request, please disclose
the tool(s) used, how they were used, and specify what code or text is AI generated.
If no AI tools were used, please write "No AI tools used" in this section. Read our
policy on AI generated code at
https://docs.dwavequantum.com/en/latest/ocean/ai_policy.html -->
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.DS_Store
__pycache__
cache
assets/__generated_theme.css
data/MNIST/
generated_json/*
static/model_diagram/*
!static/model_diagram/step_5_output_default.png
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ of spin strings arising from encoding the input data into the binary latent spac
generated by sampling spin strings from the trained QPU, and passing these to the decoder.


![Demo Example](static/demo.png)
![Demo Example](static/demo.png "Image of demo interface")

## Installation
You can run this example without installation in cloud-based IDEs that support the
[Development Containers specification](https://containers.dev/supporting) (aka "devcontainers")
[Development Containers Specification](https://containers.dev/supporting) (aka "devcontainers")
such as GitHub Codespaces.

For development environments that do not support `devcontainers`, install requirements:
Expand All @@ -33,9 +33,9 @@ If you are cloning the repo to your local system, working in a

## Usage
Your development environment should be configured to access the
[Leap&trade; quantum cloud service](https://docs.ocean.dwavesys.com/en/stable/overview/sapi.html).
[Leap&trade; quantum cloud service](https://docs.dwavequantum.com/en/latest/ocean/sapi_access_basic.html).
You can see information about supported IDEs and authorizing access to your Leap account
[here](https://docs.dwavesys.com/docs/latest/doc_leap_dev_env.html).
[here](https://docs.dwavequantum.com/en/latest/ocean/leap_authorization.html).

Run the following terminal command to start the Dash application:

Expand All @@ -52,7 +52,7 @@ Configuration options can be found in the [demo_configs.py](demo_configs.py) fil

> [!NOTE]\
> If you plan on editing any files while the application is running, please run the application
with the `--debug` command-line argument for easier debugging:
with the `--debug` command-line argument for live reloads and easier debugging:
`python app.py --debug`


Expand All @@ -62,7 +62,7 @@ Variational autoencoders are machine learning models that learn latent represent
through an `encoder` and then reconstruct data from these latent representations using a `decoder`.
Put simply,

![eq0](static/eq0.png)
![Autoencoder reconstruction equation](static/eq0.png "Equation: x_hat equals decoder(encoder(x))")

where _x_hat_ is the reconstruction of _x_.

Expand Down Expand Up @@ -93,7 +93,7 @@ whose structure is defined in `dwave.plugins.torch.autoencoder` with a

We minimize the following loss function:

![eq1](static/eq1.png)
![Total loss function](static/eq1.png "Equation: the loss L(theta) equals MSE(x, x_hat) plus MMD(z, s) plus NLL(z, theta_QPU)")

whose terms correspond to a reconstruction loss (MSE), a distribution distance loss (MMD)
and a likelihood loss (NLL). Note the NLL term is only optimized with respect to the QPU parameters.
Expand All @@ -103,7 +103,7 @@ and a likelihood loss (NLL). Note the NLL term is only optimized with respect to
The reconstruction loss considered in this problem is the mean squared error over the pixels that
form the original image _x_ and the reconstructed image _x_hat_, that is:

![eq2](static/eq2.png)
![Mean squared error equation](static/eq2.png "Equation: MSE(x, y) equals the squared L2 norm of x minus y")

Other losses, including perceptual losses, could be used, but from the simplicity of this dataset,
we also keep a simple loss. It is worth noting that MSE could make the autoencoder produce blurry
Expand All @@ -116,13 +116,13 @@ we use the maximum mean discrepancy distance, which uses samples to estimate the
two distributions. To measure the (squared) maximum mean discrepancy (&eta;\_k) between two
distributions _p_ and _q_, a kernel, _k_, is used:

![eq3](static/eq3.png)
![Squared maximum mean discrepancy equation](static/eq3.png "Equation: eta_k(p, q) written as expectation values of the kernel k over samples z from p and s from q")

where &varphi; is the feature map associated to the kernel _k_.

In this demo, a mixture of radial basis kernels are used:

![eq4](static/eq4.png)
![Radial basis kernel mixture equation](static/eq4.png "Equation: the kernel k(x, x') equals the average of d radial basis kernels with bandwidths gamma_u")

where &gamma;\_u is _2^w_ for _w ∈ \{-d/2, -d/2+1, ..., d/2\}_. Thus _MMD(z,s)_ is evaluated
by sampling _z_ from the encoded data, and _s_ from the QPU to estimate the expectation values of
Expand All @@ -135,19 +135,19 @@ encoded data in the latent space. For this, we train the couplings _(\{J\_ij\})_
_(\{h\_i\})_ of the QPU and train the QPU so that the encoded data in the latent space is distributed
according to an approximate Boltzmann distribution defined by the QPU parameters, that is we aim for:

![eq5](static/eq5.png)
![Boltzmann distribution equation](static/eq5.png "Equation: p(z = encoder(x)) equals exp(-beta E(z)) divided by the partition function Z")

where _E(z)_ is the energy of _z_ with respect to the QPU parameters, i.e.,

![eq6](static/eq6.png)
![Energy equation](static/eq6.png "Equation: E(z) equals the sum of J_ij z_i z_j over GRBM edges plus the sum of h_i z_i over GRBM nodes")

and _Z_ is the partition function.

To ensure that the encoded data is distributed according to a Boltzmann distribution defined by the
QPU parameters, we minimize the negative log-likelihood of encoded data under the QPU Boltzmann
distribution:

![eq7](static/eq7.png)
![Negative log-likelihood equation](static/eq7.png "Equation: NLL(z, theta_QPU) equals negative log p(z)")

## Model Overview

Expand Down
44 changes: 27 additions & 17 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import diskcache
from dash import DiskcacheManager

from demo_configs import APP_TITLE, THEME_COLOR, THEME_COLOR_SECONDARY
from demo_configs import APP_TITLE
from demo_interface import create_interface
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc

# Essential for initializing callbacks. Do not remove.
import demo_callbacks
Expand All @@ -47,12 +47,32 @@
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
prevent_initial_callbacks="initial_duplicate",
background_callback_manager=background_callback_manager,
external_stylesheets=[dbc.themes.BOOTSTRAP]
)
app.title = APP_TITLE

app.config.suppress_callback_exceptions = True

app.index_string = """
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
{%metas%}
<title>{%title%}</title>
{%favicon%}
<link rel="stylesheet" href="https://use.typekit.net/fyq0cum.css">
{%css%}
</head>
<body>
{%app_entry%}
<footer>
{%config%}
{%scripts%}
{%renderer%}
</footer>
</body>
</html>
"""

# Parse debug argument
parser = argparse.ArgumentParser(description="Dash debug setting.")
parser.add_argument(
Expand All @@ -67,26 +87,16 @@
print(f"\nDebug has been set to: {DEBUG}")
if not DEBUG:
print(
"The app will not show live code updates and the Dash debug menu will be hidden.",
"If editting code while the app is running, run the app with `python app.py --debug`.\n",
"Code changes will not be reflected in the app interface and the Dash debug menu will be hidden.",
"If editing code while the app is running, run the app with `python app.py --debug`.\n",
sep="\n",
)

# Generates css file and variable using THEME_COLOR and THEME_COLOR_SECONDARY settings
css = f"""/* Automatically generated theme settings css file, see app.py */
:root {{
--theme: {THEME_COLOR};
--theme-secondary: {THEME_COLOR_SECONDARY};
}}
"""
with open("assets/__generated_theme.css", "w") as f:
f.write(css)


if __name__ == "__main__":
# Imports the Dash HTML code and sets it in the app.
# Creates the visual layout and app (see `demo_interface.py`)
app.layout = create_interface()
app.layout = dmc.MantineProvider(create_interface())

# Run the server
app.run(debug=DEBUG, dev_tools_hot_reload=False)
app.run(debug=DEBUG)
Loading