QAutoencoder_EN.ipynb 17.2 KB
Newer Older
Q
Quleaf 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quantum Autoencoder\n",
    "\n",
    "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview\n",
    "\n",
    "This tutorial will show how to train a quantum autoencoder to compress and reconstruct a given quantum state (mixed state) [1].\n",
    "\n",
    "### Theory\n",
    "\n",
    "The form of the quantum autoencoder is very similar to the classical autoencoder, which is composed of an encoder $E$ and a decoder $D$. For the input quantum state $\\rho_{in}$ of the $N$ qubit system (here we use the density operator representation of quantum mechanics to describe the mixed state), first use the encoder $E = U(\\theta)$ to encode information into some of the qubits in the system. This part of qubits is denoted by **system $A$**. After measuring and discarding the remaining qubits (this part is denoted by **system $B$**), we get the compressed quantum state $\\rho_{encode}$! The dimension of the compressed quantum state is the same as the dimension of the quantum system $A$. Suppose we need $N_A$ qubits to describe the system $A$, then the dimension of the encoded quantum state $\\rho_{encode}$ is $2^{N_A}\\times 2^{N_A}$. Note that the mathematical operation corresponding to the measure-and-discard operation in this step is partial trace. The reader can intuitively treat it as the inverse operation of the tensor product $\\otimes$.\n",
    "\n",
    "Let us look at a specific example. Given a quantum state $\\rho_A$ of $N_A$ qubits and another quantum state $\\rho_B$ of $N_B$ qubits, the quantum state of the entire quantum system composed of subsystems $A$ and $B$ is $\\rho_{AB} = \\rho_A \\otimes \\rho_B$, which is a state of $N = N_A + N_B$ qubits. Now we let the entire quantum system evolve under the action of the unitary matrix $U$ for some time to get a new quantum state $\\tilde{\\rho_{AB}} = U\\rho_{AB}U^\\dagger$. So if we only want to get the new quantum state $\\tilde{\\rho_A}$ of quantum subsystem A at this time, what should we do? We simply measure the quantum subsystem $B$ and then discard it. This step of the operation is completed by partial trace $\\tilde{\\rho_A} = \\text{Tr}_B (\\tilde{\\rho_{AB}})$. With Paddle Quantum, we can call the built-in function `partial_trace(rho_AB, 2**N_A, 2**N_B, 2)` to complete this operation. **Note:** The last parameter is 2, which means that we want to discard quantum system $B$.\n",
    "\n",
    "![QA-fig-encoder_pipeline](./figures/QA-fig-encoder_pipeline.png)\n",
    "\n",
    "After discussing the encoding process, let us take a look at how decoding is done. To decode the quantum state $\\rho_{encode}$, we need to introduce an ancillary system $C$ with the same dimension as the system $B$ and take its initial state as the $|0\\dots0\\rangle$ state. Then use the decoder $D = U^\\dagger(\\theta)$ to act on the entire quantum system $A+C$ to decode the compressed information in system A. We hope that the final quantum state $\\rho_{out}$ and $\\rho_{in}$ are as similar as possible and use Uhlmann-Josza fidelity $F$ to measure the similarity between them.\n",
    "\n",
    "$$\n",
    "F(\\rho_{in}, \\rho_{out}) = \\left(\\operatorname{tr} \\sqrt{\\sqrt{\\rho_{in}} \\rho_{out} \\sqrt{\\rho_{in}}} \\right)^{2}.\n",
    "\\tag{1}\n",
    "$$\n",
    "\n",
    "Finally, by optimizing the encoder's parameters, we can improve the fidelity of $\\rho_{in}$ and $\\rho_{out}$ as much as possible."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Paddle Quantum Implementation\n",
    "\n",
    "Next, we will use a simple example to show the workflow of the quantum autoencoder. Here we first import the necessary packages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
Q
Quleaf 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
     "end_time": "2021-04-30T08:57:25.375761Z",
     "start_time": "2021-04-30T08:57:25.355799Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>pre { white-space: pre !important; }</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.core.display import HTML\n",
    "display(HTML(\"<style>pre { white-space: pre !important; }</style>\"))"
   ]
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
77
   "execution_count": 2,
Q
Quleaf 已提交
78 79 80 81
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-04-30T08:57:29.266507Z",
     "start_time": "2021-04-30T08:57:25.894969Z"
Q
Quleaf 已提交
82 83 84 85 86 87
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import paddle\n",
Q
Quleaf 已提交
88 89 90 91
    "import paddle_quantum as pq\n",
    "from paddle_quantum.ansatz.circuit import Circuit\n",
    "from paddle_quantum.qinfo import state_fidelity, partial_trace\n",
    "from paddle_quantum.linalg import dagger, haar_unitary\n",
Q
Quleaf 已提交
92
    "from paddle_quantum.state import State"
Q
Quleaf 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generating the initial state\n",
    "\n",
    "Let us consider the quantum state $\\rho_{in}$ of $N = 3$ qubits. We first encode the information into the two qubits below (system $A$) through the encoder then measure and discard the first qubit (system $B$). Secondly, we introduce another qubit (the new reference system $C$) in state $|0\\rangle$ to replace the discarded qubit $B$. Finally, through the decoder, the compressed information in A is restored to $\\rho_{out}$. Here, we assume that the initial state is a mixed state and the spectrum of $\\rho_{in}$ is $\\lambda_i \\in \\{0.4, 0.2, 0.2, 0.1, 0.1, 0, 0, 0\\}$, and then generate the initial state $\\rho_{in}$ by applying a random unitary transformation.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
107
   "execution_count": 3,
Q
Quleaf 已提交
108 109
   "metadata": {
    "ExecuteTime": {
Q
Quleaf 已提交
110 111
     "end_time": "2021-04-30T08:57:29.283394Z",
     "start_time": "2021-04-30T08:57:29.270542Z"
Q
Quleaf 已提交
112 113 114 115
    }
   },
   "outputs": [],
   "source": [
Q
Quleaf 已提交
116 117 118 119
    "N_A = 2                          # Number of qubits in system A\n",
    "N_B = 1                          # Number of qubits in system B\n",
    "N = N_A + N_B                    # Total number of qubits\n",
    "SEED = 15                        # Set random seed\n",
Q
Quleaf 已提交
120
    "complex_dtype = 'complex128'\n",
Q
Quleaf 已提交
121
    "paddle.seed(SEED)\n",
Q
Quleaf 已提交
122 123
    "pq.set_dtype(complex_dtype)        # set data type\n",
    "pq.set_backend('density_matrix')\n",
Q
Quleaf 已提交
124
    "\n",
Q
Quleaf 已提交
125 126
    "V = haar_unitary(N).numpy()                              # Generate a random unitary matrix\n",
    "D = np.diag([0.4, 0.2, 0.2, 0.1, 0.1, 0, 0, 0])          # Set the spectrum of the target state rho\n",
Q
Quleaf 已提交
127 128
    "rho_in = State(V @ D @ dagger(V))     # Generate input state rho_in\n",
    "rho_C = State(np.diag([1, 0]))     # Generate ancilla state rho_C"
Q
Quleaf 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Building a quantum neural network\n",
    "\n",
    "Here, we use quantum neural networks (QNN) as encoders and decoders. Suppose system A has $N_A$ qubits, both system $B$ and $C$ have $N_B$ qubits, and the depth of the QNN is $D$. Encoder $E$ acts on the total system composed of systems A and B, and decoder $D$ acts on the total system composed of $A$ and $C$. In this example, $N_{A} = 2$ and $N_{B} = 1$."
   ]
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
142
   "execution_count": 4,
Q
Quleaf 已提交
143 144
   "metadata": {
    "ExecuteTime": {
Q
Quleaf 已提交
145 146
     "end_time": "2021-04-30T08:57:29.301622Z",
     "start_time": "2021-04-30T08:57:29.288113Z"
Q
Quleaf 已提交
147 148
    }
   },
Q
Quleaf 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The initialized circuit:\n",
      "--Ry(2.974)----Rz(3.296)----*---------x----Ry(4.201)----Rz(4.559)----*---------x----Ry(5.254)----Rz(4.834)----*---------x----Ry(3.263)----Rz(1.664)----*---------x----Ry(5.240)----Rz(1.166)----*---------x----Ry(5.038)----Rz(0.564)----*---------x--\n",
      "                            |         |                              |         |                              |         |                              |         |                              |         |                              |         |  \n",
      "--Ry(2.407)----Rz(3.514)----x----*----|----Ry(6.279)----Rz(4.675)----x----*----|----Ry(4.986)----Rz(5.080)----x----*----|----Ry(2.845)----Rz(2.662)----x----*----|----Ry(0.015)----Rz(0.052)----x----*----|----Ry(4.341)----Rz(5.329)----x----*----|--\n",
      "                                 |    |                                   |    |                                   |    |                                   |    |                                   |    |                                   |    |  \n",
      "--Ry(3.866)----Rz(3.272)---------x----*----Ry(2.219)----Rz(2.298)---------x----*----Ry(6.060)----Rz(0.431)---------x----*----Ry(3.197)----Rz(1.673)---------x----*----Ry(2.324)----Rz(0.037)---------x----*----Ry(4.892)----Rz(1.856)---------x----*--\n",
      "                                                                                                                                                                                                                                                      \n"
     ]
    }
   ],
Q
Quleaf 已提交
164
   "source": [
Q
Quleaf 已提交
165 166 167 168 169 170 171 172 173 174 175
    "# Set circuit depth\n",
    "cir_depth = 6\n",
    "\n",
    "# Use Circuit class to build the encoder E\n",
    "cir_Encoder = Circuit(N)\n",
    "for _ in range(cir_depth):\n",
    "    cir_Encoder.ry('full')\n",
    "    cir_Encoder.rz('full')\n",
    "    cir_Encoder.cnot('cycle')\n",
    "print(\"The initialized circuit:\") \n",
    "print(cir_Encoder)"
Q
Quleaf 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configuring the training model: loss function\n",
    "\n",
    "Here, we define the loss function to be\n",
    "\n",
    "$$\n",
    "Loss = 1-\\langle 0...0|\\rho_{trash}|0...0\\rangle,\n",
    "\\tag{2}\n",
    "$$\n",
    "\n",
    "where $\\rho_{trash}$ is the quantum state of the system $B$ discarded after encoding. Then we train the QNN through PaddlePaddle to minimize the loss function. If the loss function reaches 0, the input state and output state will be exactly the same state. This means that we have achieved compression and decompression perfectly, in which case the fidelity of the initial and final states is $F(\\rho_{in}, \\rho_{out}) = 1$."
   ]
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
196
   "execution_count": 6,
Q
Quleaf 已提交
197 198
   "metadata": {
    "ExecuteTime": {
Q
Quleaf 已提交
199 200
     "end_time": "2021-04-30T08:57:52.962725Z",
     "start_time": "2021-04-30T08:57:42.476996Z"
Q
Quleaf 已提交
201 202 203 204 205 206 207
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
Q
Quleaf 已提交
208 209 210 211 212 213 214 215 216 217
      "iter: 10 loss: 0.1285 fid: 0.8609\n",
      "iter: 20 loss: 0.1090 fid: 0.8800\n",
      "iter: 30 loss: 0.1040 fid: 0.8877\n",
      "iter: 40 loss: 0.1017 fid: 0.8899\n",
      "iter: 50 loss: 0.1007 fid: 0.8913\n",
      "iter: 60 loss: 0.1002 fid: 0.8923\n",
      "iter: 70 loss: 0.1001 fid: 0.8925\n",
      "iter: 80 loss: 0.1000 fid: 0.8925\n",
      "iter: 90 loss: 0.1000 fid: 0.8925\n",
      "iter: 100 loss: 0.1000 fid: 0.8926\n",
Q
Quleaf 已提交
218 219
      "\n",
      "The trained circuit:\n",
Q
Quleaf 已提交
220
      "--Ry(2.426)----Rz(3.029)----*---------x----Ry(4.490)----Rz(4.618)----*---------x----Ry(5.908)----Rz(4.413)----*---------x----Ry(1.273)----Rz(0.885)----*---------x----Ry(6.689)----Rz(1.169)----*---------x----Ry(5.038)----Rz(0.564)----*---------x--\n",
Q
Quleaf 已提交
221
      "                            |         |                              |         |                              |         |                              |         |                              |         |                              |         |  \n",
Q
Quleaf 已提交
222
      "--Ry(1.004)----Rz(3.807)----x----*----|----Ry(7.110)----Rz(5.279)----x----*----|----Ry(5.825)----Rz(6.107)----x----*----|----Ry(2.676)----Rz(2.543)----x----*----|----Ry(-1.62)----Rz(-1.07)----x----*----|----Ry(5.135)----Rz(5.329)----x----*----|--\n",
Q
Quleaf 已提交
223
      "                                 |    |                                   |    |                                   |    |                                   |    |                                   |    |                                   |    |  \n",
Q
Quleaf 已提交
224
      "--Ry(4.519)----Rz(1.909)---------x----*----Ry(3.341)----Rz(2.543)---------x----*----Ry(7.258)----Rz(-0.10)---------x----*----Ry(3.402)----Rz(2.748)---------x----*----Ry(3.975)----Rz(0.944)---------x----*----Ry(4.903)----Rz(1.856)---------x----*--\n",
Q
Quleaf 已提交
225
      "                                                                                                                                                                                                                                                      \n"
Q
Quleaf 已提交
226 227 228 229 230 231 232 233
     ]
    }
   ],
   "source": [
    "# Set hyper-parameters\n",
    "LR = 0.2       # Set the learning rate\n",
    "ITR = 100      # Set the number of iterations\n",
    "\n",
Q
Quleaf 已提交
234
    "class NET(paddle.nn.Layer):\n",
Q
Quleaf 已提交
235
    "    def __init__(self, cir, rho_in, rho_C, dtype='float32'):\n",
Q
Quleaf 已提交
236
    "        super(NET, self).__init__()\n",
Q
Quleaf 已提交
237 238 239
    "        # load the circuit of the encoder E\n",
    "        self.cir = cir\n",
    "        # load the input state rho_in and the ancilla state rho_C\n",
Q
Quleaf 已提交
240 241
    "        self.rho_in = rho_in.data\n",
    "        self.rho_C = rho_C.data\n",
Q
Quleaf 已提交
242 243
    "        # set trainable parameters\n",
    "        self.theta = cir.parameters()\n",
Q
Quleaf 已提交
244 245 246
    "    \n",
    "    # Define loss function and forward propagation mechanism\n",
    "    def forward(self):\n",
Q
Quleaf 已提交
247 248 249
    "    \n",
    "        # Generate the matrices of the encoder E and decoder D\n",
    "        E = self.cir.unitary_matrix()\n",
Q
Quleaf 已提交
250 251 252 253 254
    "        E_dagger = dagger(E)\n",
    "        D = E_dagger\n",
    "        D_dagger = E\n",
    "\n",
    "        # Encode the quantum state rho_in\n",
Q
Quleaf 已提交
255
    "        rho_BA = E @ self.rho_in @ E_dagger\n",
Q
Quleaf 已提交
256 257
    "        \n",
    "        # Take partial_trace() to get rho_encode and rho_trash\n",
Q
Quleaf 已提交
258 259
    "        rho_encode = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 1)\n",
    "        rho_trash = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 2)\n",
Q
Quleaf 已提交
260
    "\n",
Q
Quleaf 已提交
261
    "        # Decode and get the quantum state rho_out\n",
Q
Quleaf 已提交
262 263
    "        rho_CA = paddle.kron(self.rho_C, rho_encode)\n",
    "        rho_out = D @ rho_CA @ D_dagger\n",
Q
Quleaf 已提交
264 265
    "        \n",
    "        # Calculate the loss function with rho_trash\n",
Q
Quleaf 已提交
266 267
    "        zero_Hamiltonian = paddle.to_tensor(np.diag([1, 0]).astype(complex_dtype))\n",
    "        loss = 1 - paddle.real(paddle.trace(zero_Hamiltonian @ rho_trash))\n",
Q
Quleaf 已提交
268
    "\n",
Q
Quleaf 已提交
269
    "        return loss, rho_out\n",
Q
Quleaf 已提交
270
    "\n",
Q
Quleaf 已提交
271
    "# Generate network\n",
Q
Quleaf 已提交
272
    "net = NET(cir_Encoder, rho_in, rho_C)\n",
Q
Quleaf 已提交
273
    "# Generally speaking, we use Adam optimizer to get relatively good convergence\n",
Q
Quleaf 已提交
274
    "# Of course, it can be changed to SGD or RMS prop\n",
Q
Quleaf 已提交
275 276 277 278 279
    "opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n",
    "\n",
    "# Optimization loops\n",
    "for itr in range(1, ITR + 1):\n",
    "    # Forward propagation for calculating loss function\n",
Q
Quleaf 已提交
280
    "    loss, rho_out = net()\n",
Q
Quleaf 已提交
281 282 283 284 285
    "    # Use back propagation to minimize the loss function\n",
    "    loss.backward()\n",
    "    opt.minimize(loss)\n",
    "    opt.clear_grad()\n",
    "    # Calculate and print fidelity\n",
Q
Quleaf 已提交
286 287 288
    "    fid = state_fidelity(rho_in, rho_out)\n",
    "    if itr % 10 == 0:\n",
    "        print('iter:', itr, 'loss:', '%.4f' % loss, 'fid:', '%.4f' % np.square(fid.item()))\n",
Q
Quleaf 已提交
289
    "    if itr == ITR:\n",
Q
Quleaf 已提交
290 291
    "        print(\"\\nThe trained circuit:\") \n",
    "        print(cir_Encoder)"
Q
Quleaf 已提交
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the dimension of system A is denoted by $d_A$, it is easy to prove that the maximum fidelity can be achieved by quantum autoencoder is the sum of $d_A$ largest eigenvalues ​​of $\\rho_{in}$. In our case $d_A = 4$ and the maximum fidelity is\n",
    "\n",
    "$$\n",
    "F_{\\text{max}}(\\rho_{in}, \\rho_{out})  = \\sum_{j=1}^{d_A} \\lambda_j(\\rho_{in})= 0.4 + 0.2 + 0.2 + 0.1 = 0.9.\n",
    "\\tag{3}\n",
    "$$\n",
    "\n",
    "After 100 iterations, the fidelity achieved by the quantum autoencoder we trained reaches above 0.89, which is very close to the optimal value."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "_______\n",
    "\n",
    "## References\n",
    "\n",
    "[1] Romero, J., Olson, J. P. & Aspuru-Guzik, A. Quantum autoencoders for efficient compression of quantum data. [Quantum Sci. Technol. 2, 045001 (2017).](https://iopscience.iop.org/article/10.1088/2058-9565/aa8072)\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
Q
Quleaf 已提交
323
   "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')",
Q
Quleaf 已提交
324 325 326 327 328 329 330 331 332 333 334 335 336
   "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",
Q
Quleaf 已提交
337
   "version": "3.7.13"
Q
Quleaf 已提交
338 339 340 341 342 343 344 345 346 347 348 349 350
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
Q
Quleaf 已提交
351 352 353 354 355
  },
  "vscode": {
   "interpreter": {
    "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd"
   }
Q
Quleaf 已提交
356 357 358 359 360
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}