diff --git a/docs/source/tutorials/nnvqe.ipynb b/docs/source/tutorials/nnvqe.ipynb new file mode 100644 index 00000000..3669b34d --- /dev/null +++ b/docs/source/tutorials/nnvqe.ipynb @@ -0,0 +1,4001 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "64ba95d6", + "metadata": {}, + "source": [ + "#
NN-VQE" + ] + }, + { + "cell_type": "markdown", + "id": "b65f64bf", + "metadata": {}, + "source": [ + "## Overview\n", + "\n", + "In this tutorial, we'll show you a general framework called neural network encoded variational quantum algorithms (NN-VQAs) with TensorCircuit. NN-VQA feeds input (such as parameters of a Hamiltonian) from a given problem to a neural network and uses its outputs to parameterize an ansatz circuit for the standard VQA. Here, we take NN-variational quantum eigensolver (VQE) to illustrate concretely." + ] + }, + { + "cell_type": "markdown", + "id": "831930ae", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4e1651b9", + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorflow as tf\n", + "import tensorcircuit as tc\n", + "import cotengra\n", + "import quimb\n", + "from tqdm.notebook import tqdm\n", + "from functools import partial\n", + "\n", + "optc = cotengra.ReusableHyperOptimizer(\n", + " methods=[\"greedy\"],\n", + " parallel=\"ray\",\n", + " minimize=\"combo\",\n", + " max_time=30,\n", + " max_repeats=1024,\n", + " progbar=True,\n", + ")\n", + "tc.set_contractor(\"custom\", optimizer=optc, preprocessing=True)\n", + "\n", + "K = tc.set_backend(\"tensorflow\")\n", + "tc.set_dtype(\"complex128\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d78b480b", + "metadata": {}, + "source": [ + "## Energy\n", + "\n", + "The Hamiltonian used in this tutorial is a 1D XXZ model with periodic boundary conditions, with the transverse field strength $\\lambda$ and the anisotropy parameter $\\Delta$. The Hamiltonian energy expectation function is chosen as loss.\n", + "\n", + "$$ \\hat{H}_{XXZ}=\\sum_{i}{ \\left( X_{i}X_{i+1}+Y_{i}Y_{i+1}+\\Delta Z_{i}Z_{i+1} \\right) } + \\lambda \\sum_{i}{Z_{i}} $$" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "fff67346", + "metadata": {}, + "outputs": [], + "source": [ + "def energy(c: tc.Circuit, lamb: float = 1.0, delta: float = 1.0):\n", + " e = 0.0\n", + " n = c._nqubits\n", + " for i in range(n):\n", + " e += lamb * c.expectation((tc.gates.z(), [i])) # \n", + " for i in range(n): \n", + " e += c.expectation(\n", + " (tc.gates.x(), [i]), (tc.gates.x(), [(i + 1) % n])\n", + " ) # \n", + " e += c.expectation(\n", + " (tc.gates.y(), [i]), (tc.gates.y(), [(i + 1) % n])\n", + " ) # \n", + " e += delta * c.expectation(\n", + " (tc.gates.z(), [i]), (tc.gates.z(), [(i + 1) % n])\n", + " ) # \n", + " return K.real(e)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "0ad6a7a6", + "metadata": {}, + "source": [ + "## Ansatz circuit\n", + "\n", + "Now we design the circuit. We choose multi-scale entangled renormalization ansatz (MERA) as the ansatz here, $d$ is the circuit depth. (see tutorial of MERA [here](https://tensorcircuit.readthedocs.io/en/latest/tutorials/mera.html))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "445b7c86", + "metadata": {}, + "outputs": [], + "source": [ + "def MERA(inp, n, d=1, lamb=1., energy_flag=False): # for single-parameter 1D XXZ model, we fix lamb\n", + " params = K.cast(inp[\"params\"], \"complex128\")\n", + " delta = K.cast(inp[\"delta\"], \"complex128\") \n", + " c = tc.Circuit(n)\n", + " \n", + " idx = 0\n", + "\n", + " for i in range(n):\n", + " c.rx(i, theta=params[3 * i])\n", + " c.rz(i, theta=params[3 * i + 1])\n", + " c.rx(i, theta=params[3 * i + 2])\n", + " idx += 3 * n\n", + " \n", + "\n", + " for n_layer in range(1, int(np.log2(n)) + 1):\n", + " n_qubit = 2**n_layer # number of qubits involving\n", + " step = int(n / n_qubit)\n", + "\n", + " for _ in range(d): # circuit depth\n", + " # even \n", + " for i in range(step, n - step, 2 * step):\n", + " c.rxx(i, i + step, theta=params[idx])\n", + " c.rzz(i, i + step, theta=params[idx + 1])\n", + " idx += 2\n", + " \n", + " # odd \n", + " for i in range(0, n, 2 * step):\n", + " c.rxx(i, i + step, theta=params[idx])\n", + " c.rzz(i, i + step, theta=params[idx + 1])\n", + " idx += 2\n", + "\n", + " # single qubit\n", + " for i in range(0, n, step):\n", + " c.rx(i, theta=params[idx])\n", + " c.rz(i, theta=params[idx + 1])\n", + " idx += 2\n", + " \n", + " if energy_flag:\n", + " return energy(c, lamb, delta) # return Hamiltonian energy expectation\n", + " else:\n", + " return c, idx # return the circuit & number of circuit parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "6daa2f64", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The number of parameters is 74\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2023-08-06T16:31:47.918946\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.5.3, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# circuit visulization\n", + "n = 8\n", + "d = 1\n", + "cirq, idx = MERA({\"params\": np.zeros(3000), \"delta\": 0.}, n, d, 1.)\n", + "print(\"The number of parameters is\", idx)\n", + "cirq.draw()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "bfe2fbee", + "metadata": {}, + "source": [ + "## NN-VQE\n", + "\n", + "Design the NN-VQE. We use a neural network to transform the Hamiltonian parameters to the optimized parameters in the PQC for VQE." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1ac050a8", + "metadata": {}, + "outputs": [], + "source": [ + "def NN_MERA(n, d, lamb, NN_shape, stddev):\n", + " input = tf.keras.layers.Input(shape=[1]) # input layer\n", + "\n", + " x = tf.keras.layers.Dense(\n", + " units=NN_shape, \n", + " kernel_initializer=tf.keras.initializers.RandomNormal(stddev=stddev),\n", + " activation=\"ReLU\"\n", + " )(input) # hidden layer\n", + "\n", + " x = tf.keras.layers.Dropout(0.05)(x) # dropout layer\n", + "\n", + " _, idx = MERA({\"params\": np.zeros(3000), \"delta\": 0.}, n, d, 1., energy_flag=False)\n", + " params = tf.keras.layers.Dense(\n", + " units=idx, \n", + " kernel_initializer=tf.keras.initializers.RandomNormal(stddev=stddev),\n", + " activation=\"sigmoid\"\n", + " )(x) # output layer\n", + " \n", + " qlayer = tc.KerasLayer(partial(MERA, n=n, d=d, lamb=lamb, energy_flag=True)) # PQC\n", + "\n", + " output = qlayer({\"params\": 6.3 * params, \"delta\": input}) # NN-VQE output\n", + "\n", + " m = tf.keras.Model(inputs=input, outputs=output)\n", + "\n", + " return m" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e9afb1a5", + "metadata": {}, + "source": [ + "## Train\n", + "\n", + "Now we can train the NN-VQE with TensorFlow." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "873ebd5e", + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "def train(n, d, lamb, delta, NN_shape, maxiter=10000, lr=0.005, stddev=1.):\n", + " exp_lr = tf.keras.optimizers.schedules.ExponentialDecay(\n", + " initial_learning_rate=lr, decay_steps=1000, decay_rate=0.7\n", + " )\n", + " opt = tf.keras.optimizers.Adam(exp_lr) # optimizer\n", + "\n", + " m = NN_MERA(n, d, lamb, NN_shape, stddev)\n", + " for i in range(maxiter):\n", + " with tf.GradientTape() as tape:\n", + " e = tf.zeros([1], dtype=tf.float64)\n", + " for de in delta:\n", + " e += m(K.reshape(de, [1])) # sum up energies of all training points\n", + " grads = tape.gradient(e, m.variables)\n", + " opt.apply_gradients(zip(grads, m.variables))\n", + " if i % 500 == 0:\n", + " print(\"epoch\", i, \":\", e)\n", + " \n", + " m.save_weights('NN-VQE.weights.h5') # save the trained model" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "e8df3d67", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch 0 : tf.Tensor([[117.53523392]], shape=(1, 1), dtype=float64)\n", + "epoch 500 : tf.Tensor([[-361.85937039]], shape=(1, 1), dtype=float64)\n", + "epoch 1000 : tf.Tensor([[-365.35288984]], shape=(1, 1), dtype=float64)\n", + "epoch 1500 : tf.Tensor([[-366.65891358]], shape=(1, 1), dtype=float64)\n", + "epoch 2000 : tf.Tensor([[-366.94258369]], shape=(1, 1), dtype=float64)\n" + ] + } + ], + "source": [ + "n = 8 # number of qubits\n", + "d = 2 # circuit depth\n", + "lamb = 0.75 # fixed\n", + "delta = np.linspace(-3.0, 3.0, 20, dtype=\"complex128\") # training set\n", + "NN_shape = 20 # node number of the hidden layer\n", + "maxiter = 2500 # maximum iteration for the optimization\n", + "lr = 0.009 # learning rate\n", + "stddev = 0.1 # the initial standard deviation of the NN\n", + "\n", + "with tf.device('/cpu:0'):\n", + " train(n, d, lamb, delta, NN_shape=NN_shape, maxiter=maxiter, lr=lr, stddev=stddev)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "c5a7cdb0", + "metadata": {}, + "source": [ + "## Test\n", + "\n", + "We use a test set beyond the training set to test the accuracy and generalization capability of NN-VQE." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "f15f4f68", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4a3ceb8bdf90463f88050b771fde6925", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "test_delta = np.linspace(-4.0, 4.0, 201) # test set\n", + "test_energies = tf.zeros_like(test_delta).numpy()\n", + "m = NN_MERA(n, d, lamb, NN_shape, stddev)\n", + "m.load_weights('DNN-MERA_2[20](-3.0,3.0,20)_drop05.weights.h5')\n", + "for i, de in tqdm(enumerate(test_delta)):\n", + " test_energies[i] = m(K.reshape(de, [1]))" + ] + }, + { + "cell_type": "markdown", + "id": "924027f8", + "metadata": {}, + "source": [ + "## Compare\n", + "\n", + "We compare the results of NN-VQE with the analytical ones to calculate the ground-state relative error. From the figure, we can see that NN-VQE is able to estimate the ground-state energies of parameterized Hamiltonians with high precision without fine-tuning and has a favorable generalization capability." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "c8668a13", + "metadata": {}, + "outputs": [], + "source": [ + "analytical_energies = [] # analytical result\n", + "for i in test_delta:\n", + " h = quimb.tensor.tensor_builder.MPO_ham_XXZ(n, i*4, jxy=4., bz=2.*0.75, S=0.5, cyclic=True) \n", + " h = h.to_dense()\n", + " analytical_energies.append(np.min(quimb.eigvalsh(h)))" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "42799e3e", + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " 2023-08-06T23:44:26.082098\n", + " image/svg+xml\n", + " \n", + " \n", + " Matplotlib v3.5.3, https://matplotlib.org/\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ], + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# relative error\n", + "plt.plot(test_delta, (test_energies - analytical_energies) / np.abs(analytical_energies), '-', color='b')\n", + "plt.xlabel(\"Delta\", fontsize=14)\n", + "plt.ylabel(\"GS Relative Error\", fontsize=14)\n", + "plt.axvspan(-3.0, 3.0, color='darkgrey', alpha=0.5) # training set span\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "5f9bda8a", + "metadata": {}, + "source": [ + "To get more detailed information or further study, please refer to [our paper](https://arxiv.org/abs/2308.01068) and [GitHub](https://github.com/JachyMeow/NN-VQA)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "vscode": { + "interpreter": { + "hash": "18d2a9923f839b0d86cf68fd09770e726264cf9d62311eaf57b1fff0ca4bed8e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}