1520 lines (1519 with data), 275.7 kB
{
"cells": [
{
"cell_type": "markdown",
"id": "secondary-copying",
"metadata": {},
"source": [
"# Torch Connector and Hybrid QNNs\n",
"\n",
"This tutorial introduces Qiskit's `TorchConnector` class, and demonstrates how the `TorchConnector` allows for a natural integration of any `NeuralNetwork` from Qiskit Machine Learning into a PyTorch workflow. `TorchConnector` takes a Qiskit `NeuralNetwork` and makes it available as a PyTorch `Module`. The resulting module can be seamlessly incorporated into PyTorch classical architectures and trained jointly without additional considerations, enabling the development and testing of novel **hybrid quantum-classical** machine learning architectures.\n",
"\n",
"## Content:\n",
"\n",
"[Part 1: Simple Classification & Regression](#Part-1:-Simple-Classification-&-Regression)\n",
"\n",
"The first part of this tutorial shows how quantum neural networks can be trained using PyTorch's automatic differentiation engine (`torch.autograd`, [link](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html)) for simple classification and regression tasks. \n",
"\n",
"1. [Classification](#1.-Classification)\n",
" 1. Classification with PyTorch and `EstimatorQNN`\n",
" 2. Classification with PyTorch and `SamplerQNN`\n",
"2. [Regression](#2.-Regression)\n",
" 1. Regression with PyTorch and `SamplerQNN`\n",
"\n",
"[Part 2: MNIST Classification, Hybrid QNNs](#Part-2:-MNIST-Classification,-Hybrid-QNNs)\n",
"\n",
"The second part of this tutorial illustrates how to embed a (Quantum) `NeuralNetwork` into a target PyTorch workflow (in this case, a typical CNN architecture) to classify MNIST data in a hybrid quantum-classical manner.\n",
"\n",
"***"
]
},
{
"cell_type": "code",
"execution_count": 76,
"id": "banned-helicopter",
"metadata": {},
"outputs": [],
"source": [
"# Necessary imports\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from torch import Tensor\n",
"from torch.nn import Linear, CrossEntropyLoss, MSELoss\n",
"from torch.optim import LBFGS\n",
"\n",
"from qiskit import QuantumCircuit\n",
"from qiskit.utils import algorithm_globals\n",
"from qiskit.circuit import Parameter\n",
"from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap\n",
"from qiskit_machine_learning.neural_networks import SamplerQNN, EstimatorQNN\n",
"from qiskit_machine_learning.connectors import TorchConnector\n",
"\n",
"# Set seed for random generators\n",
"algorithm_globals.random_seed = 42"
]
},
{
"cell_type": "markdown",
"id": "unique-snapshot",
"metadata": {},
"source": [
"## Part 1: Simple Classification & Regression"
]
},
{
"cell_type": "markdown",
"id": "surgical-penetration",
"metadata": {},
"source": [
"### 1. Classification\n",
"\n",
"First, we show how `TorchConnector` allows to train a Quantum `NeuralNetwork` to solve a classification tasks using PyTorch's automatic differentiation engine. In order to illustrate this, we will perform **binary classification** on a randomly generated dataset."
]
},
{
"cell_type": "code",
"execution_count": 77,
"id": "secure-tragedy",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAABbvUlEQVR4nO3deVxU5f4H8M8wyKYMqCCLoIjmVuagCGLiSoJ6XS6au6i5lKWimAve1NJKU69LZu577oRmZaSpKCqCIuSGpl4MUMAtGUAFmTm/P/gxOQI6wAxnGD7v1+u8xnnmOWe+D4dxvpzzLBJBEAQQERERGRETsQMgIiIi0jUmOERERGR0mOAQERGR0WGCQ0REREaHCQ4REREZHSY4REREZHSY4BAREZHRYYJDRERERsdU7ADEoFKpcPfuXVhbW0MikYgdDhEREWlBEARkZWXB2dkZJiavvkZTJROcu3fvwtXVVewwiIiIqAxSUlLg4uLyyjpVMsGxtrYGUPADkslkIkdDRERE2lAoFHB1dVV/j79KlUxwCm9LyWQyJjhERESVjDbdS9jJmIiIiIwOExwiIiIyOkxwiIiIyOgwwSEiIiKjwwSHiIiIjA4THCIiIjI6THCIiIjI6DDBISIiIqPDBIeIiIiMjl4TnJMnT6JXr15wdnaGRCLBgQMHXrtPZGQkWrVqBXNzczRq1AhbtmwpUmfVqlVwc3ODhYUFvL29ERsbq/vgiYiIqNLSa4KTk5ODli1bYtWqVVrVT0pKQs+ePdG5c2ckJCRg8uTJGDNmDH777Td1nT179iAkJARz587FhQsX0LJlS/j7++PevXv6agYRERFVMhJBEIQKeSOJBPv370ffvn1LrDNjxgz88ssvuHz5srps0KBBePz4MSIiIgAA3t7eaNOmDb799lsAgEqlgqurKyZOnIiZM2dqFYtCoYCNjQ0yMzO5FhUREVElUZrvb4PqgxMdHQ0/Pz+NMn9/f0RHRwMA8vLyEBcXp1HHxMQEfn5+6jrFyc3NhUKh0Nj0RRAE3Lp1S2/HJyIiotczqAQnPT0dDg4OGmUODg5QKBR4+vQpHjx4AKVSWWyd9PT0Eo+7YMEC2NjYqDdXV1e9xA8AW7ZsQbNmzbBs2TJU0MUxIiIieolBJTj6EhoaiszMTPWWkpKit/eKjIzE8+fPERISgr59++LRo0d6ey8iIiIqnkElOI6OjsjIyNAoy8jIgEwmg6WlJezs7CCVSout4+joWOJxzc3NIZPJNDZ92bJlC1atWgUzMzMcPHgQHh4er7x9RkRERLpnUAmOj48Pjh49qlF25MgR+Pj4AADMzMzQunVrjToqlQpHjx5V1xGbRCLBRx99hLNnz6JRo0ZITk5Ghw4dsHjxYqhUKrHDIyIiqhL0muBkZ2cjISEBCQkJAAqGgSckJCA5ORlAwa2joKAgdf0PP/wQ//vf/zB9+nRcu3YN3333Hfbu3YspU6ao64SEhGD9+vXYunUrEhMTMX78eOTk5GDUqFH6bEqpeXh4IC4uDoMGDUJ+fj5mzJiBCxcuiB0WAECpBCIjgV27Ch6VSrEjIiIi0i1TfR78/Pnz6Ny5s/p5SEgIAGDEiBHYsmUL0tLS1MkOADRo0AC//PILpkyZghUrVsDFxQUbNmyAv7+/us7AgQNx//59zJkzB+np6ZDL5YiIiCjS8dgQyGQy7Ny5E126dEF6ejo8PT3FDgnh4UBwMJCa+k+ZiwuwYgUQGCheXERERLpUYfPgGBKx58G5desWwsLCMG3aNJiYVNxdwvBwoH9/4OUzLpEUPIaFMckhooqnVAJRUUBaGuDkBPj6AlKp2FGRIaq08+BUBc+fP8fAgQMxc+ZMBAQEFOkwrS9KZcGVm+LS2cKyyZN5u4qIKlZ4OODmBnTuDAwZUvDo5lZQTlQeTHAqmKmpKT7++GNYWlriyJEjkMvlOH78uN7fNypK87bUywQBSEkpqEdEVBEKryq//H/TnTsF5UxyqDyY4FQwiUSCUaNG4fz582jevDnS09Ph5+eHzz//HEo9Xj5JS9NtPSKi8uBVZdI3Jjgiad68Oc6dO4f3338fKpUKn332Gd599108fPhQL+/n5KTbekRE5cGryqRvTHBEZGVlhY0bN2L79u2oXr06srOzYW1trZf38vUtGC1V2KH4ZRIJ4OpaUI+ISN94VZn0Ta/DxEk7w4YNQ5s2bWBmZgYzMzMAQH5+PoCCPju6IJUWDAXv378gmXnxsnBh0rN8OUcuEFHF4FVl0jdewTEQTZo0QYMGDdTPZ8+ejS5duiD1VddwSykwsGAoeN26muUuLhwiTkQVi1eVSd84D44I8+C8zv379/HGG28gMzMTtWvXxvbt29G9e3edHZ9zThCRISgcRQUUf1WZf3jRyzgPTiVnb2+P8+fPw8PDAw8fPkSPHj0wY8YMPH/+XCfHl0qBTp2AwYMLHpncEJEYeFWZ9IlXcAzwCk6hZ8+eYdq0afj2228BAO3atcOuXbtQr149kSMjItIdXlUmbZXm+5sJjgEnOIV++OEHjB49GpmZmXB1dcWNGzdgbm4udlhEREQVireojEy/fv0QHx+PNm3a4IsvvmByQ0RE9BocJl5JNGjQAGfOnNEYNh4bGws7Ozu4u7uLGBkREZHh4RWcSuTF5Ob+/fv497//jVatWuGHH34QMSqqDJRKIDIS2LWr4JHT3xORsWOCU0nl5eWhfv36yMzMRP/+/TFhwgQ8e/ZM7LDIAHG1ZiKqipjgVFJ169bFiRMnMH36dADAqlWr0K5dO9y8eVPkyMiQcLVmIqqqmOBUYtWqVcPXX3+NX375BbVr10Z8fDxatWqF3bt3ix0aGQCu1kxEVRkTHCPQo0cPJCQkoH379sjKykJ4eDiq4Oh/eglXayaiqoyjqIyEi4sLjh8/jmXLlmHcuHGQlLTAC1UZXK2ZiKoyXsExIqamppg2bRpsbGwAAIIgYOTIkfj+++9FjozEwNWaiagqY4JjxMLDw7F161YMHz4co0ePxpMnT8QOiSoQV2smoqqMCY4R69u3Lz777DNIJBJs2rQJbdq0wZUrV8QOiyqIVAqsWFHw75eTnMLny5dzzR8iMk5McIyYVCrF3LlzcfToUTg6OuLq1ato06YNNm/ezE7IVQRXayaiqoqLbVaCxTZ1ISMjA8OHD8eRI0cAAJ988gkWL14sclRUUbhaMxEZg9J8f3MUVRXh4OCAiIgILFy4EPPmzUOfPn3EDokqkFQKdOokdhREVJlU9j+MeAWnilzBedHdu3fh7Oysfn7jxg00atSIQ8uJiAhAwSznwcGac2m5uBT06xPz1nZpvr/ZB6cKejG5uXr1KuRyOYYMGQKFQiFiVEREZAiMZYkXJjhV3Llz55Cbm4vdu3ejdevWiI+PFzskIiISiTEt8cIEp4obMWIEoqKi4Orqips3b6Jt27ZYtWoVR1kREVVBxrTECxMcgo+PDxISEtC7d2/k5eVhwoQJGDBgAB4/fix2aEREVIGMaYkXJjgEAKhVqxYOHDiApUuXolq1aggLC8O6devEDouIiCqQMS3xUiEJzqpVq+Dm5gYLCwt4e3sjNja2xLqdOnWCRCIpsvXs2VNdZ+TIkUVeDwgIqIimGDWJRIIpU6bg1KlTGDZsGEJCQsQOiYiIKpAxLfGi9wRnz549CAkJwdy5c3HhwgW0bNkS/v7+uHfvXrH1w8PDkZaWpt4uX74MqVSK9957T6NeQECARr1du3bpuylVhpeXF7Zv3w5T04JpknJzczFjxgw8evRI5MiIiEifjGmJF70nOEuXLsXYsWMxatQoNG/eHGvWrIGVlRU2bdpUbP1atWrB0dFRvR05cgRWVlZFEhxzc3ONejVr1tR3U6qsWbNmYdGiRfDw8MDZs2fFDoeIiPTIWJZ40WuCk5eXh7i4OPj5+f3zhiYm8PPzQ3R0tFbH2LhxIwYNGoTq1atrlEdGRqJOnTpo0qQJxo8fj4cPH5Z4jNzcXCgUCo2NtDd06FA0bNgQycnJ8PX1xeLFi6FSqcQOi4iI9CQwELh9Gzh+HNi5s+AxKanyJDeAnhOcBw8eQKlUwsHBQaPcwcEB6enpr90/NjYWly9fxpgxYzTKAwICsG3bNhw9ehRff/01Tpw4ge7du0NZwsD8BQsWwMbGRr25urqWvVFVUKtWrXDhwgUMHDgQ+fn5mD59Onr16oUHDx6IHRoREelJ4RIvgwcXPFaG21IvMuhRVBs3bkSLFi3g5eWlUT5o0CD07t0bLVq0QN++ffHzzz/j3LlziIyMLPY4oaGhyMzMVG8pKSkVEL1xkclk2LVrF9auXQtzc3McOnQIcrkc586dEzs0IiKiIvSa4NjZ2UEqlSIjI0OjPCMjA46Ojq/cNycnB7t378bo0aNf+z7u7u6ws7PDzZs3i33d3NwcMplMY6PSk0gkGDduHGJjY9G4cWNkZWWhdu3aYodFRERUhF4THDMzM7Ru3RpHjx5Vl6lUKhw9ehQ+Pj6v3Hffvn3Izc3FsGHDXvs+qampePjwIZwqw8B8I/D2228jLi4Ov/32G9zd3dXlT58+FTEqIiKif+j9FlVISAjWr1+PrVu3IjExEePHj0dOTg5GjRoFAAgKCkJoaGiR/TZu3Ii+ffsWuUKQnZ2NadOm4ezZs7h9+zaOHj2KPn36oFGjRvD399d3c+j/1ahRA23btlU/P3z4MN54440SbxMSERFVJFN9v8HAgQNx//59zJkzB+np6ZDL5YiIiFB3PE5OToaJiWaedf36dZw6dQqHDx8ucjypVIqLFy9i69atePz4MZydndGtWzfMnz8f5ubm+m4OFUMQBCxcuBB37txB165dMWfOHHz66aeQVrYeaUREZDQkQhVcVVGhUMDGxgaZmZnsj6MjOTk5mDhxIjZv3gwA6NKlC3bs2PHavlZERETaKs33t0GPoqLKo3r16ti0aRO2bduG6tWr49ixY2jZsiV+//13sUMjIqIqiAkO6dTw4cNx/vx5tGjRAvfu3UO3bt2QkJAgdlhERFTF6L0PDlU9TZs2RUxMDKZMmYJnz55BLpeLHRIREVUxTHBILywtLbFmzRqN2aUfPHiAuLg4jnYjIiK94y0q0qvCkVQqlQojRoxAQEAAZsyYgefPn4scGRERGTMmOFQhlEolGjRoAABYtGgROnbsiOTkZJGjIiIiY8UEhypEtWrV8O2332Lfvn2QyWSIjo6GXC7HwYMHxQ6NyKgolUBkJLBrV8FjCWsQExk9JjhUofr374/4+Hh4enri77//Rp8+fRASEoK8vDyxQyOq9MLDATc3oHNnYMiQgkc3t4JyoqqGCQ5VOHd3d5w+fRqTJ08GABw4cIDrWBGVU3g40L8/kJqqWX7nTkE5kxyqajiTMWcyFtWPP/6IunXrwtPTU+xQiCotpbLgSs3LyU0hiQRwcQGSkgCuoEKVGWcypkqjT58+GsnN6tWrMXHiROTm5ooYFVHlEhVVcnIDAIIApKQU1COqKjgPDhmM9PR0hISE4NmzZzhz5gz27NmDRo0aiR0WkcFLS9NtPSJjwCs4ZDAcHR0RFhaG2rVr48KFC2jVqhX27t0rdlhEBs/JSbf1iIwBExwyKD179kRCQgLat2+PrKwsDBw4EOPHj2cnZKJX8PUt6GMjkRT/ukQCuLoW1COqKpjgkMFxcXHB8ePHMWvWLEgkEqxZswbt27fn7MdEJZBKgRUrCv79cpJT+Hz5cnYwpqqFCQ4ZJFNTU3z55ZeIiIiAvb09+vXrh2rVqokdFpHBCgwEwsKAunU1y11cCsoDA8WJi0gsHCbOYeIG7969e7Czs4OJSUE+npycDDs7O1hZWYkcGZHhUSoLRkulpRX0ufH15ZUbMh6l+f7mKCoyeHXq1FH/++nTp+jZsycEQcDevXvRvHlzESMjMjxSKdCpk9hREImPt6ioUrl16xYePHiAK1euwNPTE1u2bBE7JCLSM66vRWXBBIcqlbfeegsJCQnw8/PD06dPMWrUKIwYMQLZ2dlih0ZEesD1taismOBQpePg4ICIiAh88cUXMDExwbZt29CmTRtcunRJ7NCISIe4vhaVBzsZs5NxpXby5EkMHjwYd+/exbvvvovDhw+LHRIR6QDX16LicC0qqjI6dOiAhIQEDB48GJs2bRI7HCLSEa6vReXFBIcqPXt7e+zcuRMuLi7qssWLFyM+Pl7EqIioPLi+FpUXExwyOr/88gumT58OHx8ffPfdd6iCd2GJKj2ur0XlxQSHjE7btm3Rq1cv5Obm4uOPP8aAAQOQmZkpdlhEVApcX4vKiwkOGZ3atWvjxx9/xNKlS2FqaoqwsDB4eHjg3LlzYodGRFri+lpUXkxwyChJJBJMmTIFp0+fhpubG5KSkvDOO+9gzZo1YodGRFri+lpUHkxwyKh5eXkhPj4e//73v/H8+XPUrl1b7JCIqBQCA4Hbt4Hjx4GdOwsek5KY3NDrcR4czoNTJQiCgMjISHTu3Fld9uTJEy7YSURUiXAeHKKXSCQSjeQmLS0NjRs3xpIlS6BSqUSMjIiI9KFCEpxVq1bBzc0NFhYW8Pb2RmxsbIl1t2zZAolEorFZWFho1BEEAXPmzIGTkxMsLS3h5+eHGzdu6LsZZES2bNmCO3fuYNq0aejduzcePnwodkhERKRDek9w9uzZg5CQEMydOxcXLlxAy5Yt4e/vj3v37pW4j0wmQ1pamnr766+/NF5ftGgRvvnmG6xZswYxMTGoXr06/P398ezZM303h4zEzJkzsXr1apibm+OXX36BXC7HqVOnxA6LiIh0RO8JztKlSzF27FiMGjUKzZs3x5o1a2BlZfXKafUlEgkcHR3Vm4ODg/o1QRCwfPlyfPrpp+jTpw/efvttbNu2DXfv3sWBAwf03RwyEhKJBB9++CFiYmLQuHFjpKamolOnTliwYAFvWRERGQG9Jjh5eXmIi4uDn5/fP29oYgI/Pz9ER0eXuF92djbq168PV1dX9OnTB1euXFG/lpSUhPT0dI1j2tjYwNvbu8Rj5ubmQqFQaGxEANCyZUucP38eQ4cOhVKpxKxZs7Bs2TKxwyIionLSa4Lz4MEDKJVKjSswAODg4ID09PRi92nSpAk2bdqEH3/8Ed9//z1UKhXatWuH1P9fda1wv9Icc8GCBbCxsVFvrq6u5W0aGRFra2ts374dGzduRKtWrfDBBx+IHRIREZWTwY2i8vHxQVBQEORyOTp27Ijw8HDY29tj7dq1ZT5maGgoMjMz1VtKSooOIyZjIJFI8P777yM2NhY1atQAAKhUKuzcuRNKpVLk6IiIqLT0muDY2dlBKpUiIyNDozwjIwOOjo5aHaNatWrw8PDAzZs3AUC9X2mOaW5uDplMprERFUf6wrzvy5Ytw9ChQ+Hv71/i1UEiIjJMek1wzMzM0Lp1axw9elRdplKpcPToUfj4+Gh1DKVSiUuXLsHp/5eMbdCgARwdHTWOqVAoEBMTo/UxibTh4OAAKysrHD16FHK5HL///rvYIRERkZb0fosqJCQE69evx9atW5GYmIjx48cjJycHo0aNAgAEBQUhNDRUXX/evHk4fPgw/ve//+HChQsYNmwY/vrrL4wZMwZAwa2EyZMn44svvsDBgwdx6dIlBAUFwdnZGX379tV3c6gKGTZsGOLi4vDWW28hIyMD3bp1w+zZs5Gfny92aERE9Bqm+n6DgQMH4v79+5gzZw7S09Mhl8sRERGh7iScnJwME5N/8qy///4bY8eORXp6OmrWrInWrVvjzJkzaN68ubrO9OnTkZOTg3HjxuHx48do3749IiIiikwISFReTZs2RWxsLIKDg7F+/Xp88cUXOHnyJHbu3Im6L68ASEREBoNrUbE/Dmlp165dGDduHHJzc3Hq1Cl4eXmJHRIRUZVSmu9vvV/BITIWgwcPhqenJ86dO8fkhojIwBncMHEiQ/bGG29gyJAh6ucJCQnw8/Pj1ANERAaGCQ5RGQmCgHHjxqlHWf38889ih0RERP+PCQ5RGUkkEuzatQutW7fGo0eP0KtXL0ydOhV5eXlih0ZEVOUxwSEqh4YNG+L06dMIDg4GULC4bIcOHXD79m1xAyMiquKY4BCVk7m5OZYvX479+/fD1tYWMTEx8PDwQGJiotihERFVWRxFRaQjffv2hYeHBwYOHAhra2s0btxY7JCISARKJRAVBaSlAU5OgK8v8MIqMFRBmOAQ6VD9+vURFRWF7Oxs9bpWT58+RVpaGtzd3UWOjoj0LTwcCA4GUlP/KXNxAVasAAIDxYurKuItKiIdq1atGmrWrKl+PnnyZMjlcuzdu1fEqIhI38LDgf79NZMbALhzp6A8PFycuKoqJjhEevTs2TNcvXoVWVlZGDhwIMaPH49nz56JHRYR6ZhSWXDlpri1AQrLJk8uqEcVgwkOkR5ZWFjg+PHj6gVl16xZg7Zt2+LPP/8UOTIi0qWoqKJXbl4kCEBKSkE9qhhMcEivlColIm9HYtelXYi8HQmlqur9+WJqaoqvvvoKERERsLe3xx9//IFWrVphx44dYodGRDqSlqbbelR+THBIb8ITw+G2wg2dt3bGkPAh6Ly1M9xWuCE8sWreiPb390dCQgI6duyInJwcTJo0CY8ePRI7LCLSAScn3daj8uNq4lxNXC/CE8PRf29/CND89ZJAAgAIGxCGwGZVc0hBfn4+5s+fjzZt2uBf//qX2OEQkQ4olYCbW0GH4uK+VSWSgtFUSUkcMl4epfn+ZoLDBEfnlCol3Fa4IVVR/A1pCSRwkbkgKTgJUhN+0gHg559/xsOHDzFixAixQyGiMiocRQVoJjmSgr/rEBbGoeLlVZrvb96iIp2LSo4qMbkBAAECUhQpiEqumN52ht4PKC0tDUFBQRg5ciRGjhyJnJwcsUMiojIIDCxIYurW1Sx3cWFyIwYmOKRzaVna9aLTtl55VIZ+QHXq1EFISAhMTEywdetWeHp64tKlS2KHRURlEBgI3L4NHD8O7NxZ8JiUxORGDExwSOecrLXrRadtvbIq7Af08tWkO4o76L+3v8EkOVKpFJ9++imOHTsGZ2dnXLt2DV5eXtiwYQOq4B1kokpPKgU6dQIGDy54ZJ8bcTDBIZ3zrecLF5mLukPxyySQwFXmCt96vnqLQalSIjgiuEgnZwDqsskRkw3qdlXHjh2RkJCAgIAAPHv2DGPHjsWwYcOQn58vdmhERJUOExzSOamJFCsCVgBAkSSn8PnygOV67WBsaP2AtGVvb49ffvkFCxcuhFQqhbW1NUxNuWQcEVFpMcEhvQhsFoiwAWGoK9Psbecic6mQIeKG1A+otExMTDBjxgycOXMGy5YtU5fn5OTwlhURkZb4pyHpTWCzQPRp0gdRyVFIy0qDk7UTfOv5VsjQcEPpB1QeXl5e6n8rlUr07t0btWvXxvr162FjYyNiZEREho8JDumV1ESKTm6dKvx9C/sB3VHcKbYfTuFcPPrsB6RL586dw8mTJ5Gfn4+4uDjs2bMHnp6eYodFRGSweIuKjJIh9APSpbZt2+LUqVOoX78+/ve//6Fdu3b45ptveMuKiKgETHDIaIndD0jXvL29ER8fj759++L58+cIDg5Gv3798Pfff4sdGhGRweFSDVyqwegpVUpR+gHpiyAIWLlyJT755BM8f/4c/v7+iIiIEDssIiK941pUr8EEh4zB+fPnMXLkSOzcuRNvv/222OEQEekd16IiqgI8PT1x8eJFjeTmxx9/xMOHD0WMiojIMDDBIarETEz++QjHxsaif//+8PDwwOnTp0WMisg4KJVAZCSwa1fBo9JwJj4nLTDBITISFhYWaNCgAVJSUtCxY0csXLgQKpVK7LCIKqXwcMDNDejcGRgypODRza2gnCoHJjhERuLtt99GXFwchgwZAqVSidDQUPTs2RP3798XOzSiSiU8HOjfH0h9abWXO3cKypnkVA4VkuCsWrUKbm5usLCwgLe3N2JjY0usu379evj6+qJmzZqoWbMm/Pz8itQfOXIkJBKJxhYQEKDvZhAZPGtra3z//ffYsGEDLCwsEBERAblcjhMnTogdGlGloFQCwcFAccNvCssmT+btqspA7wnOnj17EBISgrlz5+LChQto2bIl/P39ce/evWLrR0ZGYvDgwTh+/Diio6Ph6uqKbt264c6dOxr1AgICkJaWpt527dql76YQVQoSiQSjR4/GuXPn0LRpU9y9exdxcXFih0VUKURFFb1y8yJBAFJSCuqRYdP7MHFvb2+0adMG3377LQBApVLB1dUVEydOxMyZM1+7v1KpRM2aNfHtt98iKCgIQMEVnMePH+PAgQNlionDxKmqyMnJwcaNGzFx4kRIJAUzOAuCoP43EWnataugz83r7NwJDB6s/3hIk8EME8/Ly0NcXBz8/Pz+eUMTE/j5+SE6OlqrYzx58gTPnz9HrVq1NMojIyNRp04dNGnSBOPHj3/l0Njc3FwoFAqNjagqqF69OiZNmqROaLKzs9G5c2ccPXpU5MiIDJOTluvvaluPxKPXBOfBgwdQKpVwcHDQKHdwcEB6erpWx5gxYwacnZ01kqSAgABs27YNR48exddff40TJ06ge/fuUJZwU3TBggWwsbFRb66urmVvFFEltmDBApw4cQLvvvsu5s6dW+Jnhqiq8vUFXFyAki5ySiSAq2tBPTJsBj2KauHChdi9ezf2798PCwsLdfmgQYPQu3dvtGjRAn379sXPP/+Mc+fOITIystjjhIaGIjMzU72lpKRUUAuIDMt//vMfjBkzBoIgYN68eejatSvu3r0rdlhEBkMqBVYUrNNbJMkpfL58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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Generate random dataset\n",
"\n",
"# Select dataset dimension (num_inputs) and size (num_samples)\n",
"num_inputs = 2\n",
"num_samples = 20\n",
"\n",
"# Generate random input coordinates (X) and binary labels (y)\n",
"X = 2 * algorithm_globals.random.random([num_samples, num_inputs]) - 1\n",
"y01 = 1 * (np.sum(X, axis=1) >= 0) # in { 0, 1}, y01 will be used for SamplerQNN example\n",
"y = 2 * y01 - 1 # in {-1, +1}, y will be used for EstimatorQNN example\n",
"\n",
"# Convert to torch Tensors\n",
"X_ = Tensor(X)\n",
"y01_ = Tensor(y01).reshape(len(y)).long()\n",
"y_ = Tensor(y).reshape(len(y), 1)\n",
"\n",
"# Plot dataset\n",
"for x, y_target in zip(X, y):\n",
" if y_target == 1:\n",
" plt.plot(x[0], x[1], \"bo\")\n",
" else:\n",
" plt.plot(x[0], x[1], \"go\")\n",
"plt.plot([-1, 1], [1, -1], \"--\", color=\"black\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "hazardous-rehabilitation",
"metadata": {},
"source": [
"#### A. Classification with PyTorch and `EstimatorQNN`\n",
"\n",
"Linking an `EstimatorQNN` to PyTorch is relatively straightforward. Here we illustrate this by using the `EstimatorQNN` constructed from a feature map and an ansatz."
]
},
{
"cell_type": "code",
"execution_count": 78,
"id": "fewer-desperate",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 705.35x200.667 with 1 Axes>"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Set up a circuit\n",
"feature_map = ZZFeatureMap(num_inputs)\n",
"ansatz = RealAmplitudes(num_inputs)\n",
"qc = QuantumCircuit(num_inputs)\n",
"qc.compose(feature_map, inplace=True)\n",
"qc.compose(ansatz, inplace=True)\n",
"qc.draw(\"mpl\")"
]
},
{
"cell_type": "code",
"execution_count": 79,
"id": "humanitarian-flavor",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Initial weights: [-0.01256962 0.06653564 0.04005302 -0.03752667 0.06645196 0.06095287\n",
" -0.02250432 -0.04233438]\n"
]
}
],
"source": [
"# Setup QNN\n",
"qnn1 = EstimatorQNN(\n",
" circuit=qc, input_params=feature_map.parameters, weight_params=ansatz.parameters\n",
")\n",
"\n",
"# Set up PyTorch module\n",
"# Note: If we don't explicitly declare the initial weights\n",
"# they are chosen uniformly at random from [-1, 1].\n",
"initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn1.num_weights) - 1)\n",
"model1 = TorchConnector(qnn1, initial_weights=initial_weights)\n",
"print(\"Initial weights: \", initial_weights)"
]
},
{
"cell_type": "code",
"execution_count": 80,
"id": "likely-grace",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([-0.3285], grad_fn=<_TorchNNFunctionBackward>)"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Test with a single input\n",
"model1(X_[0, :])"
]
},
{
"cell_type": "markdown",
"id": "gorgeous-segment",
"metadata": {},
"source": [
"##### Optimizer\n",
"The choice of optimizer for training any machine learning model can be crucial in determining the success of our training's outcome. When using `TorchConnector`, we get access to all of the optimizer algorithms defined in the [`torch.optim`] package ([link](https://pytorch.org/docs/stable/optim.html)). Some of the most famous algorithms used in popular machine learning architectures include *Adam*, *SGD*, or *Adagrad*. However, for this tutorial we will be using the L-BFGS algorithm (`torch.optim.LBFGS`), one of the most well know second-order optimization algorithms for numerical optimization. \n",
"\n",
"##### Loss Function\n",
"As for the loss function, we can also take advantage of PyTorch's pre-defined modules from `torch.nn`, such as the [Cross-Entropy](https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html) or [Mean Squared Error](https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html) losses.\n",
"\n",
"\n",
"**💡 Clarification :** \n",
"In classical machine learning, the general rule of thumb is to apply a Cross-Entropy loss to classification tasks, and MSE loss to regression tasks. However, this recommendation is given under the assumption that the output of the classification network is a class probability value in the $[0, 1]$ range (usually this is achieved through a Softmax layer). Because the following example for `EstimatorQNN` does not include such layer, and we don't apply any mapping to the output (the following section shows an example of application of parity mapping with `SamplerQNN`s), the QNN's output can take any value in the range $[-1, 1]$. In case you were wondering, this is the reason why this particular example uses MSELoss for classification despite it not being the norm (but we encourage you to experiment with different loss functions and see how they can impact training results). "
]
},
{
"cell_type": "code",
"execution_count": 81,
"id": "following-extension",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25.535646438598633\n",
"22.696760177612305\n",
"20.039228439331055\n",
"19.68790626525879\n",
"19.267208099365234\n",
"19.02537727355957\n",
"18.15471076965332\n",
"17.337860107421875\n",
"19.082786560058594\n",
"17.07333755493164\n",
"16.218456268310547\n",
"14.992587089538574\n",
"14.929342269897461\n",
"14.914535522460938\n",
"14.907636642456055\n",
"14.902364730834961\n",
"14.90213394165039\n",
"14.902111053466797\n",
"14.902111053466797\n"
]
},
{
"data": {
"text/plain": [
"tensor(25.5356, grad_fn=<MseLossBackward0>)"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Define optimizer and loss\n",
"optimizer = LBFGS(model1.parameters())\n",
"f_loss = MSELoss(reduction=\"sum\")\n",
"\n",
"# Start training\n",
"model1.train() # set model to training mode\n",
"\n",
"\n",
"# Note from (https://pytorch.org/docs/stable/optim.html):\n",
"# Some optimization algorithms such as LBFGS need to\n",
"# reevaluate the function multiple times, so you have to\n",
"# pass in a closure that allows them to recompute your model.\n",
"# The closure should clear the gradients, compute the loss,\n",
"# and return it.\n",
"def closure():\n",
" optimizer.zero_grad() # Initialize/clear gradients\n",
" loss = f_loss(model1(X_), y_) # Evaluate loss function\n",
" loss.backward() # Backward pass\n",
" print(loss.item()) # Print loss\n",
" return loss\n",
"\n",
"\n",
"# Run optimizer step4\n",
"optimizer.step(closure)"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "efficient-bangkok",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy: 0.8\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Evaluate model and compute accuracy\n",
"y_predict = []\n",
"for x, y_target in zip(X, y):\n",
" output = model1(Tensor(x))\n",
" y_predict += [np.sign(output.detach().numpy())[0]]\n",
"\n",
"print(\"Accuracy:\", sum(y_predict == y) / len(y))\n",
"\n",
"# Plot results\n",
"# red == wrongly classified\n",
"for x, y_target, y_p in zip(X, y, y_predict):\n",
" if y_target == 1:\n",
" plt.plot(x[0], x[1], \"bo\")\n",
" else:\n",
" plt.plot(x[0], x[1], \"go\")\n",
" if y_target != y_p:\n",
" plt.scatter(x[0], x[1], s=200, facecolors=\"none\", edgecolors=\"r\", linewidths=2)\n",
"plt.plot([-1, 1], [1, -1], \"--\", color=\"black\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "abstract-parish",
"metadata": {},
"source": [
"The red circles indicate wrongly classified data points."
]
},
{
"cell_type": "markdown",
"id": "typical-cross",
"metadata": {},
"source": [
"#### B. Classification with PyTorch and `SamplerQNN`\n",
"\n",
"Linking a `SamplerQNN` to PyTorch requires a bit more attention than `EstimatorQNN`. Without the correct setup, backpropagation is not possible. \n",
"\n",
"In particular, we must make sure that we are returning a dense array of probabilities in the network's forward pass (`sparse=False`). This parameter is set up to `False` by default, so we just have to make sure that it has not been changed.\n",
"\n",
"**⚠️ Attention:** \n",
"If we define a custom interpret function ( in the example: `parity`), we must remember to explicitly provide the desired output shape ( in the example: `2`). For more info on the initial parameter setup for `SamplerQNN`, please check out the [official qiskit documentation](https://qiskit.org/ecosystem/machine-learning/stubs/qiskit_machine_learning.neural_networks.SamplerQNN.html)."
]
},
{
"cell_type": "code",
"execution_count": 83,
"id": "present-operator",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Initial weights: [ 0.0364991 -0.0720495 -0.06001836 -0.09852755]\n"
]
}
],
"source": [
"# Define feature map and ansatz\n",
"feature_map = ZZFeatureMap(num_inputs)\n",
"ansatz = RealAmplitudes(num_inputs, entanglement=\"linear\", reps=1)\n",
"\n",
"# Define quantum circuit of num_qubits = input dim\n",
"# Append feature map and ansatz\n",
"qc = QuantumCircuit(num_inputs)\n",
"qc.compose(feature_map, inplace=True)\n",
"qc.compose(ansatz, inplace=True)\n",
"\n",
"# Define SamplerQNN and initial setup\n",
"parity = lambda x: \"{:b}\".format(x).count(\"1\") % 2 # optional interpret function\n",
"output_shape = 2 # parity = 0, 1\n",
"qnn2 = SamplerQNN(\n",
" circuit=qc,\n",
" input_params=feature_map.parameters,\n",
" weight_params=ansatz.parameters,\n",
" interpret=parity,\n",
" output_shape=output_shape,\n",
")\n",
"\n",
"# Set up PyTorch module\n",
"# Reminder: If we don't explicitly declare the initial weights\n",
"# they are chosen uniformly at random from [-1, 1].\n",
"initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn2.num_weights) - 1)\n",
"print(\"Initial weights: \", initial_weights)\n",
"model2 = TorchConnector(qnn2, initial_weights)"
]
},
{
"cell_type": "markdown",
"id": "liquid-reviewer",
"metadata": {},
"source": [
"For a reminder on optimizer and loss function choices, you can go back to [this section](#Optimizer)."
]
},
{
"cell_type": "code",
"execution_count": 84,
"id": "marked-harvest",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.6925069093704224\n",
"0.6881508231163025\n",
"0.6516684293746948\n",
"0.6485998034477234\n",
"0.6394745111465454\n",
"0.7055226564407349\n",
"0.6669210195541382\n",
"0.6787251234054565\n",
"0.6803979873657227\n",
"0.695716381072998\n",
"0.7132896184921265\n",
"0.7562533020973206\n",
"0.7432097792625427\n",
"0.6605831384658813\n",
"0.6825891137123108\n",
"0.6667172312736511\n",
"0.7186322808265686\n",
"0.748259425163269\n",
"0.6837981939315796\n",
"0.7127187252044678\n"
]
}
],
"source": [
"# Define model, optimizer, and loss\n",
"optimizer = LBFGS(model2.parameters())\n",
"f_loss = CrossEntropyLoss() # Our output will be in the [0,1] range\n",
"\n",
"# Start training\n",
"model2.train()\n",
"\n",
"# Define LBFGS closure method (explained in previous section)\n",
"def closure():\n",
" optimizer.zero_grad(set_to_none=True) # Initialize gradient\n",
" loss = f_loss(model2(X_), y01_) # Calculate loss\n",
" loss.backward() # Backward pass\n",
"\n",
" print(loss.item()) # Print loss\n",
" return loss\n",
"\n",
"\n",
"# Run optimizer (LBFGS requires closure)\n",
"optimizer.step(closure);"
]
},
{
"cell_type": "code",
"execution_count": 85,
"id": "falling-electronics",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy: 0.45\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Evaluate model and compute accuracy\n",
"y_predict = []\n",
"for x in X:\n",
" output = model2(Tensor(x))\n",
" y_predict += [np.argmax(output.detach().numpy())]\n",
"\n",
"print(\"Accuracy:\", sum(y_predict == y01) / len(y01))\n",
"\n",
"# plot results\n",
"# red == wrongly classified\n",
"for x, y_target, y_ in zip(X, y01, y_predict):\n",
" if y_target == 1:\n",
" plt.plot(x[0], x[1], \"bo\")\n",
" else:\n",
" plt.plot(x[0], x[1], \"go\")\n",
" if y_target != y_:\n",
" plt.scatter(x[0], x[1], s=200, facecolors=\"none\", edgecolors=\"r\", linewidths=2)\n",
"plt.plot([-1, 1], [1, -1], \"--\", color=\"black\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "aboriginal-white",
"metadata": {},
"source": [
"The red circles indicate wrongly classified data points."
]
},
{
"cell_type": "markdown",
"id": "scheduled-nicaragua",
"metadata": {},
"source": [
"### 2. Regression \n",
"\n",
"We use a model based on the `EstimatorQNN` to also illustrate how to perform a regression task. The chosen dataset in this case is randomly generated following a sine wave. "
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "amateur-dubai",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAGdCAYAAADaPpOnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAABCo0lEQVR4nO3dfXzN9f/H8cfZ2EQ2RIwtV31DX0VJolZkpeu06EJFuha+hhJd+QqRrlbSlyh0IZUm1feXLkRUUql14esiornYULIxMc7O749324xtzmbnvD+fc5732+3c9jmffY69LO089/6836+3x+fz+RARERFxiQjbBYiIiIiUh8KLiIiIuIrCi4iIiLiKwouIiIi4isKLiIiIuIrCi4iIiLiKwouIiIi4isKLiIiIuEoV2wVUtvz8fLZs2ULNmjXxeDy2yxERERE/+Hw+du3aRcOGDYmIKHtsJeTCy5YtW0hISLBdhoiIiFTAxo0biY+PL/OakAsvNWvWBMxfPiYmxnI1IiIi4o+cnBwSEhIK38fLEnLhpeBWUUxMjMKLiIiIy/gz5UMTdkVERMRVFF5ERETEVRReRERExFUUXkRERMRVFF5ERETEVRReRERExFUUXkRERMRVFF5ERETEVUKuSZ2IiIQurxeWLIHMTIiLg8REiIy0XZUEm8KLiIi4QloaDBoEmzYVnYuPh2eegeRke3VJ8Om2kYiIOF5aGvToUTy4AGzebM6npdmpS+xQeBEREUfzes2Ii893+OcKzqWkmOskPCi8iIiIoy1ZcviIy8F8Pti40Vwn4UHhRUREHC0zs3KvE/dTeBEREUeLi6vc68T9FF5ERMTREhPNqiKPp+TPezyQkGCuk/Cg8CIiIo4WGWmWQ8PhAabgeWqq+r2EE4UXERFxvORkmDMHGjUqfj4+3pxXn5fwoiZ1IiLiCsnJcOWV6rArCi8iIuIikZHQubPtKsQ23TYSERERV1F4EREREVdReBERERFXUXgRERERV1F4EREREVdReBERERFXUXgRERERVwloeFm8eDGXX345DRs2xOPx8M477xzxNYsWLeL0008nOjqaE088kRkzZgSyRBEREXGZgIaX3Nxc2rRpw6RJk/y6fv369Vx66aV06dKF9PR0UlJSuO222/jwww8DWaaIiIi4SEA77F588cVcfPHFfl8/efJkmjZtypNPPglA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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Generate random dataset\n",
"\n",
"num_samples = 20\n",
"eps = 0.2\n",
"lb, ub = -np.pi, np.pi\n",
"f = lambda x: np.sin(x)\n",
"\n",
"X = (ub - lb) * algorithm_globals.random.random([num_samples, 1]) + lb\n",
"y = f(X) + eps * (2 * algorithm_globals.random.random([num_samples, 1]) - 1)\n",
"plt.plot(np.linspace(lb, ub), f(np.linspace(lb, ub)), \"r--\")\n",
"plt.plot(X, y, \"bo\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "protected-genre",
"metadata": {},
"source": [
"#### A. Regression with PyTorch and `EstimatorQNN`"
]
},
{
"cell_type": "markdown",
"id": "lovely-semiconductor",
"metadata": {},
"source": [
"The network definition and training loop will be analogous to those of the classification task using `EstimatorQNN`. In this case, we define our own feature map and ansatz, but let's do it a little different."
]
},
{
"cell_type": "code",
"execution_count": 87,
"id": "brazilian-adapter",
"metadata": {},
"outputs": [],
"source": [
"# Construct simple feature map\n",
"param_x = Parameter(\"x\")\n",
"feature_map = QuantumCircuit(1, name=\"fm\")\n",
"feature_map.ry(param_x, 0)\n",
"\n",
"# Construct simple feature map\n",
"param_y = Parameter(\"y\")\n",
"ansatz = QuantumCircuit(1, name=\"vf\")\n",
"ansatz.ry(param_y, 0)\n",
"\n",
"qc = QuantumCircuit(1)\n",
"qc.compose(feature_map, inplace=True)\n",
"qc.compose(ansatz, inplace=True)\n",
"\n",
"# Construct QNN\n",
"qnn3 = EstimatorQNN(circuit=qc, input_params=[param_x], weight_params=[param_y])\n",
"\n",
"# Set up PyTorch module\n",
"# Reminder: If we don't explicitly declare the initial weights\n",
"# they are chosen uniformly at random from [-1, 1].\n",
"initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn3.num_weights) - 1)\n",
"model3 = TorchConnector(qnn3, initial_weights)"
]
},
{
"cell_type": "markdown",
"id": "waiting-competition",
"metadata": {},
"source": [
"For a reminder on optimizer and loss function choices, you can go back to [this section](#Optimizer)."
]
},
{
"cell_type": "code",
"execution_count": 88,
"id": "bibliographic-consciousness",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"14.947757720947266\n",
"2.948650360107422\n",
"8.952412605285645\n",
"0.37905153632164\n",
"0.24995625019073486\n",
"0.2483610212802887\n",
"0.24835753440856934\n"
]
},
{
"data": {
"text/plain": [
"tensor(14.9478, grad_fn=<MseLossBackward0>)"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Define optimizer and loss function\n",
"optimizer = LBFGS(model3.parameters())\n",
"f_loss = MSELoss(reduction=\"sum\")\n",
"\n",
"# Start training\n",
"model3.train() # set model to training mode\n",
"\n",
"# Define objective function\n",
"def closure():\n",
" optimizer.zero_grad(set_to_none=True) # Initialize gradient\n",
" loss = f_loss(model3(Tensor(X)), Tensor(y)) # Compute batch loss\n",
" loss.backward() # Backward pass\n",
" print(loss.item()) # Print loss\n",
" return loss\n",
"\n",
"\n",
"# Run optimizer\n",
"optimizer.step(closure)"
]
},
{
"cell_type": "code",
"execution_count": 89,
"id": "timely-happiness",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot target function\n",
"plt.plot(np.linspace(lb, ub), f(np.linspace(lb, ub)), \"r--\")\n",
"\n",
"# Plot data\n",
"plt.plot(X, y, \"bo\")\n",
"\n",
"# Plot fitted line\n",
"y_ = []\n",
"for x in np.linspace(lb, ub):\n",
" output = model3(Tensor([x]))\n",
" y_ += [output.detach().numpy()[0]]\n",
"plt.plot(np.linspace(lb, ub), y_, \"g-\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "individual-georgia",
"metadata": {},
"source": [
"***\n",
"\n",
"## Part 2: MNIST Classification, Hybrid QNNs\n",
"\n",
"In this second part, we show how to leverage a hybrid quantum-classical neural network using `TorchConnector`, to perform a more complex image classification task on the MNIST handwritten digits dataset. \n",
"\n",
"For a more detailed (pre-`TorchConnector`) explanation on hybrid quantum-classical neural networks, you can check out the corresponding section in the [Qiskit Textbook](https://qiskit.org/textbook/ch-machine-learning/machine-learning-qiskit-pytorch.html)."
]
},
{
"cell_type": "code",
"execution_count": 90,
"id": "otherwise-military",
"metadata": {},
"outputs": [],
"source": [
"# Additional torch-related imports\n",
"import torch\n",
"from torch import cat, no_grad, manual_seed\n",
"from torch.utils.data import DataLoader\n",
"from torchvision import datasets, transforms\n",
"import torch.optim as optim\n",
"from torch.nn import (\n",
" Module,\n",
" Conv2d,\n",
" Linear,\n",
" Dropout2d,\n",
" NLLLoss,\n",
" MaxPool2d,\n",
" Flatten,\n",
" Sequential,\n",
" ReLU,\n",
")\n",
"import torch.nn.functional as F"
]
},
{
"cell_type": "markdown",
"id": "bronze-encounter",
"metadata": {},
"source": [
"### Step 1: Defining Data-loaders for train and test"
]
},
{
"cell_type": "markdown",
"id": "parliamentary-middle",
"metadata": {},
"source": [
"We take advantage of the `torchvision` [API](https://pytorch.org/vision/stable/datasets.html) to directly load a subset of the [MNIST dataset](https://en.wikipedia.org/wiki/MNIST_database) and define torch `DataLoader`s ([link](https://pytorch.org/docs/stable/data.html)) for train and test."
]
},
{
"cell_type": "code",
"execution_count": 91,
"id": "worthy-charlotte",
"metadata": {},
"outputs": [],
"source": [
"# Train Dataset\n",
"# -------------\n",
"\n",
"# Set train shuffle seed (for reproducibility)\n",
"manual_seed(42)\n",
"\n",
"batch_size = 1\n",
"n_samples = 100 # We will concentrate on the first 100 samples\n",
"\n",
"# Use pre-defined torchvision function to load MNIST train data\n",
"X_train = datasets.MNIST(\n",
" root=\"./data\", train=True, download=True, transform=transforms.Compose([transforms.ToTensor()])\n",
")\n",
"\n",
"# Filter out labels (originally 0-9), leaving only labels 0 and 1\n",
"idx = np.append(\n",
" np.where(X_train.targets == 0)[0][:n_samples], np.where(X_train.targets == 1)[0][:n_samples]\n",
")\n",
"X_train.data = X_train.data[idx]\n",
"X_train.targets = X_train.targets[idx]\n",
"\n",
"# Define torch dataloader with filtered data\n",
"train_loader = DataLoader(X_train, batch_size=batch_size, shuffle=True)"
]
},
{
"cell_type": "markdown",
"id": "completed-spring",
"metadata": {},
"source": [
"If we perform a quick visualization we can see that the train dataset consists of images of handwritten 0s and 1s."
]
},
{
"cell_type": "code",
"execution_count": 92,
"id": "medieval-bibliography",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAx8AAACdCAYAAADVNMXrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAdXUlEQVR4nO3deZSMV/7H8W9rvaG7x77vhNgiQYTYZpggWsYuIbEFEU6ILXHkWGONWEYIwmFyIgbBGMkYS6QNsjASzTEilp+tbbG2trWln98ffVT393ar6uqueqqqvV/nzDn1qXqWO+rbVXXz3PvcIMuyLAEAAAAAL8vl6wYAAAAAeDLQ+QAAAABgCzofAAAAAGxB5wMAAACALeh8AAAAALAFnQ8AAAAAtqDzAQAAAMAWdD4AAAAA2ILOBwAAAABbBHTn4+TJkxIUFCQff/yxx465fft2CQoKku3bt3vsmOPHj5egoCCPHQ+PR00gLeoBJmoCJmoCJmrCu2zvfPztb3+ToKAg2bt3r92nDmg//PCDNGrUSPLkySPFihWTwYMHy82bN33dLI+gJrImp9YE9ZA1ObUeRKiJrNiyZYu8+eabUqNGDQkODpZy5cr5ukkeRU24j5pARnzx3RHQVz6eFHFxcdK8eXO5ffu2zJo1S/r27SufffaZdO7c2ddNg49QE0iLeoBpxYoVsmLFComOjpYSJUr4ujnwA9QETL767sjt1aPDI0aPHi358+eX7du3S1RUlIiIlCtXTvr16ydbtmyRl156yccthN2oCaRFPcA0ZcoUWbx4sYSEhEhMTIwcPHjQ102Cj1ETMPnqu8Mvr3zcu3dPxo4dK3Xq1JHo6GjJmzevNG7cWGJjYx+7z+zZs6Vs2bISEREhTZs2zfCP6vDhw9KpUycpUKCAhIeHS926dWXDhg2ZatPu3bulVatWEh0dLXny5JGmTZvK999/n267Xbt2Sb169SQ8PFwqVqwoixYtyvB4ly9flsOHD8vt27ednvfGjRuydetWef311x2FISLSo0cPyZcvn6xevTpT7Q901EQqaoJ6SIt6SEFNaCVKlJCQkJBMtTOnoiY0aoKaSMun3x2WzZYtW2aJiPXf//73sdtcunTJKl68uDVs2DBrwYIF1kcffWRVqVLFCgkJsfbt2+fY7sSJE5aIWDVr1rTKlStnTZ8+3ZowYYJVoEABq3DhwtaFCxcc2x48eNCKjo62qlWrZk2fPt2aN2+e1aRJEysoKMhat26dY7vY2FhLRKzY2FjHc9u2bbNCQ0OtBg0aWDNnzrRmz55t1apVywoNDbV2797t2O7AgQNWRESEVaZMGWvq1KnWhx9+aBUtWtSqVauWZf5Tjxs3Lt15MrJr1y5LRKxVq1ale61Ro0bWc88953T/QEBNpKAmUlAPKaiHVNREiszWhKlNmzZW2bJl3drH31ETKaiJVNREikD47vDLzseDBw+spKQk9dy1a9esokWLWn369HE896g4IiIirPj4eMfzu3fvtkTEGjp0qOO55s2bWzVr1rTu3r3reC45Odlq2LChVblyZcdzZnEkJydblStXtlq2bGklJyc7trt9+7ZVvnx5689//rPjuXbt2lnh4eHWqVOnHM8dOnTICg4OznJxfPXVV5aIWDt27Ej3WufOna1ixYo53T8QUBMpqIkU1EMK6iEVNZGCH5qpqIkU1EQqaiJFIHx3+OWwq+DgYAkNDRURkeTkZLl69ao8ePBA6tatK7/88ku67du1ayclS5Z05Oeff17q168vGzduFBGRq1evynfffSddunSRxMREuXz5sly+fFmuXLkiLVu2lKNHj8rZs2czbEtcXJwcPXpUunXrJleuXHHse+vWLWnevLns2LFDkpOT5eHDh7J582Zp166dlClTxrH/008/LS1btkx33PHjx4tlWdKsWTOn/xZ37twREZGwsLB0r4WHhztez+moiVTUBPWQFvWQgpqAiZqAiZpI5cvvDr+dcP7555/LzJkz5fDhw3L//n3H8+XLl0+3beXKldM999RTTznGqx07dkwsy5IxY8bImDFjMjzf77//rgrskaNHj4qISM+ePR/b1oSEBElKSpI7d+5k2JYqVao4CtVdERERIiKSlJSU7rW7d+86Xn8SUBMpqIkU1EMK6iEVNQETNQETNZHCl98dftn5WL58ufTq1UvatWsnI0eOlCJFikhwcLBMnTpVjh8/7vbxkpOTRURkxIgRGfYSRUQqVarkdN8ZM2ZI7dq1M9wmX758Gb55nlC8eHERETl//ny6186fP//E3C6PmkhFTVAPaVEPKagJmKgJmKiJVL787vDLzseaNWukQoUKsm7dOrVy47hx4zLc/lHvMa0jR444FtCpUKGCiIiEhIRIixYt3GpLxYoVRUQkKirK6b6FCxeWiIiIDNvy22+/uXXOtGrUqCG5c+eWvXv3SpcuXRzP37t3T+Li4tRzORk1kYqaoB7Soh5SUBMwURMwUROpfPnd4bdzPkRELMtyPLd792758ccfM9x+/fr1akzdnj17ZPfu3dK6dWsRESlSpIg0a9ZMFi1alGEP79KlS49tS506daRixYry8ccfZ7ji46N9g4ODpWXLlrJ+/Xo5ffq04/Vff/1VNm/enG6/zN4KLTo6Wlq0aCHLly+XxMREx/NffPGF3Lx584lZRIyaSEVNUA9pUQ8pqAmYqAmYqIlUvvzu8NmVj6VLl8qmTZvSPT9kyBCJiYmRdevWSfv27aVNmzZy4sQJWbhwoVSrVi3DN6hSpUrSqFEjefvttyUpKUnmzJkjBQsWlPfee8+xzfz586VRo0ZSs2ZN6devn1SoUEEuXrwoP/74o8THx8v+/fszbGeuXLlkyZIl0rp1a6levbr07t1bSpYsKWfPnpXY2FiJioqSr7/+WkREJkyYIJs2bZLGjRvLwIED5cGDB/LJJ59I9erV5cCBA+q48+bNkwkTJkhsbKzLSUGTJ0+Whg0bStOmTaV///4SHx8vM2fOlJdeeklatWrl6p86YFAT1ERa1AP1YKImMl8TBw4ccKwzcOzYMUlISJBJkyaJiMgzzzwjbdu2dbp/oKAmqAkTNREA3x1eu4/WYzy6Fdrj/nfmzBkrOTnZmjJlilW2bFkrLCzMevbZZ61vvvnG6tmzp7o13KNboc2YMcOaOXOmVbp0aSssLMxq3LixtX///nTnPn78uNWjRw+rWLFiVkhIiFWyZEkrJibGWrNmjWObjO7DbFmWtW/fPqtDhw5WwYIFrbCwMKts2bJWly5drG3btqnt/vOf/1h16tSxQkNDrQoVKlgLFy503PYsLXdvj7dz506rYcOGVnh4uFW4cGFr0KBB1o0bNzK1r7+jJlJQEymohxTUQypqIoU7NeHs36xnz54u9/d31EQKaiIVNZEiEL47giwrzbUnAAAAAPASv5zzAQAAACDnofMBAAAAwBZ0PgAAAADYgs4HAAAAAFvQ+QAAAABgiyyv85GcnCznzp2TyMhItUok/J9lWZKYmCglSpSQXLk81/+kJgKTt+pBhJoIVHxGwERNwERNwJTZmshy5+PcuXNSunTprO4OP3DmzBkpVaqUx45HTQQ2T9eDCDUR6PiMgImagImagMlVTWS5qxoZGZnVXeEnPP0eUhOBzRvvHzUR2PiMgImagImagMnVe5jlzgeXwgKfp99DaiKweeP9oyYCG58RMFETMFETMLl6D5lwDgAAAMAWdD4AAAAA2ILOBwAAAABb0PkAAAAAYAs6HwAAAABsQecDAAAAgC3ofAAAAACwBZ0PAAAAALag8wEAAADAFrl93QAgp3j11VdVrlKlispTpkxR+f79+15vEwAAgD/hygcAAAAAW9D5AAAAAGALOh8AAAAAbMGcj8fInVv/07z44osqz5w5U+U6deqoHB8fr/LatWtV/vTTT1U+cuRIltoJ7ypYsKDjsTmHw3zPNm7cqPKECRNUnjdvnspXrlzxRBNhs3Llyjker169Wr1Wr149lZOTk50ea8OGDSr3799f5UuXLmWhhQgUCxYsUHnAgAFOty9evLjKFy5c8HibAPiXiIgIlSdNmqRyaGioyp07d1b50KFDKnfv3l3l8+fPZ7eJbuPKBwAAAABb0PkAAAAAYAs6HwAAAABswZyPNCpWrOh4PHnyZPValy5dnO5rWZbKJUuWVHnw4MEq9+7dW+VZs2apbM4XgHeEhYWpPGPGDJX79evneGyOq7x69arKtWvXVvmDDz5QuUmTJir/4x//cKutsEenTp1UbtSokcq1atVyPH722WfVa+YcD1dzPmJiYlRetGiRyh06dHDeWAQ0s7Zc1Qt8o0WLFiqbc226du2a6WOdPn1a5RMnTqhcrFgxlePi4lQ+ePBgps+FwJA3b16VzTXDFi5cqHJwcLBbx8+fP3+29vcGrnwAAAAAsAWdDwAAAAC2oPMBAAAAwBbM+UijdevWjseu5nhkV2RkpMrvvPOOyuY6INzv3zvef/99lQcNGqTyihUrHI/fffdd9dqDBw9UTkhIUHnNmjUqL1myROVNmzapfOfOHdcNhkvm3JwyZcqoPHHiRJXr1q2rcoECBVSOjo72YOuca9u2rcpmzfTt29e2tsDz6tevr7I5vh/+6dtvv3X6ujfnYaRda0ok/dpC3v6tAs/Lly+fyiNGjFB57NixXj2/OUfZF7jyAQAAAMAWdD4AAAAA2ILOBwAAAABbPFFzPkJCQlResGCByr169cr0sW7duqXyqlWrVI6Pj1d51KhRKpvj0s3x/uY4T+Z8eId5P+1Tp06pPG7cOMfjK1euZOtcr7zyispLly5V+YcffsjW8ZHCnD81bdo0p9vnyqX/G4w/rbVQtGhRXzcB2RAeHq7y4sWLVTbnF5m2bNmi8o0bNzzTMNimdOnSKnfs2FHlixcvqvz3v/9d5cKFC6tszlFDYEg7d3DdunXqtT/+8Y9uHcvV/ua6HuYcj/v377t1Pm/gygcAAAAAW9D5AAAAAGALOh8AAAAAbJGj53zUqlVL5bVr16pcsWLFx+6blJSk8rBhw1T+97//rfLJkydVfv311zPbTBERKVSokMqVKlVS+fDhw24dDxl78cUXVa5atarK7733nsr/93//57FzBwUFeexYSPX222+r7O17pDs71759+1R2dT/1mJgYlQcMGOCZhsEvtG/fXuXq1as73d6cS2iu63L79m3PNAy26d69u8pTpkxR+eHDhyo/9dRTKpvzSREYzLXcVq5c6XjctGlTp/ueOXNG5eHDh6u8bds2lV2tM2P+9siTJ4/T7e3AlQ8AAAAAtqDzAQAAAMAWdD4AAAAA2CJHz/lo27atys7meJhmzZqlsrkmiCvbt29X2VzHw1znY+PGjSp/9913bp0PmdOhQweVzfG2rsZOZseaNWuctoV1PjKndevWKs+bNy9bx/v5559VrlOnjtPt586d63g8derUbJ178+bNKptrlCCwNGnSROU5c+a4tb95//6zZ89mt0nwMfN3iCk4OFjlY8eOebM58JKyZcuqvGLFCpUbNGjw2H2//PJLlUePHq2yOQck7ZohIiK5c7v3U551PgAAAAA8Meh8AAAAALAFnQ8AAAAAtshRcz7Wr1+v8ssvv+zW/vv373c8Hj9+fLbaYq4LEhUV5XT7MmXKqGzORYBndOzYUeWrV6+qvGnTJq+dOyEhQeWuXbuqPGLECK+dOyc5dOiQyub8KnPcvSudO3dWeenSpU6P52rtDjy5Jk6cqLK5fpMrly5d8mRz4CPNmjVzPH7uueecbmt+B/36669Ot585c2aW2wXvMdcIczbHw1xzrk+fPiq7mpPxpz/9SeXChQs73d78zjLnIPsCVz4AAAAA2ILOBwAAAABb0PkAAAAAYIuAnvNRqlQplc1xcK7ufXzkyBGVX3vtNcfj7N4H+cSJEyoHBQU53d4cGxwREaFyUlJSttqDFObcGl/eU91sCzKnXLlyKj/zzDNu7d+vXz+VT506pXJsbKzKzsbu2s0c2/vXv/5V5SFDhqjMHALva9GiheNxtWrV3Nr32rVrKqddQwaBa9SoUY7HYWFhTrc1/2Z/+eUXlc01wc6dO5fN1iErIiMjVZ42bZrK/fv3d7p/2rk8w4cPV6+5+3vz5s2bbm0fFxenMnM+AAAAADwx6HwAAAAAsAWdDwAAAAC2CKg5H1WrVlV53bp1KufLl8/p/uZYygEDBqh8+PDhLLfNnF/StGlTt/ZftGiRytevX89yW5B55v224f/y5MmjcnR0tFv7nz9/3unrkyZNUvmNN95w6/ieZM5vMdcgady4scoXLlxQ2VxvCNlnjv2ePHmy43HBggXdOtabb76p8pkzZ7LeMPgNd+rg8uXLTl+/d++e0wx7tG7dWuXevXurHBwcrLL5G27w4MGOx6dPn85WW9LOM8uMkJAQlZnzAQAAAOCJQecDAAAAgC3ofAAAAACwRUDN+fjiiy9UNueAmMz7948cOVLlvXv3eqZhIpIrl+7H1axZ0+n2ycnJKm/fvt1jbUGqokWLqmyut/L777/b1hZfnhuB6emnn1bZnOMB+7388ssq161bN9P7fv/99ypv27bNI22Cb5nfM+7OQ4P/qV27tsrmmkrh4eEqp13HQ0Tkgw8+UHnnzp1ZbkulSpVU7tWrl1v7m+t8+AOufAAAAACwBZ0PAAAAALbw62FX5rAq8zKYK1u2bFE5NjY2u016rFdffVXlypUrO93eHHb122+/ebxNSD9EwrIslc1Lp95knvubb76x7dw5mTnk0RVz+Jsr5uVyX/6tuvr/OmTIEJXNz8BNmzZ5vE05XatWrVSeP39+pvc1b6M6btw4lW/evJn1hsFvdOvWTeW0w2TMzxvzFqxXrlzxWruQdW+99ZbK5tA607fffqvy+vXrPd0kB1fLSpjMIWH+gCsfAAAAAGxB5wMAAACALeh8AAAAALCFX8/5MG+Nay5fb9q1a5fKAwcO9HibHomKilLZvK2aK6dPn1b52rVr2W4T3GeOv/WmMmXKqHzr1i3bzp2TmfOnXOnfv7/KruZB9O3b1+02eYu7/1/NeUZwLTIyUuUxY8aonD9//kwf68svv1TZm/MO4Tu9e/d+7Gvm3+DBgwdV9uQt/5F1NWrUUPkvf/mL0+2PHDmi8uzZsz3epkcuXryosnmb/rJlyzrd39XrvsCVDwAAAAC2oPMBAAAAwBZ0PgAAAADYwq/mfPzhD39QuXnz5k63v3//vsrmPdQfPnzokXaJpJ/j8dFHH6nsal2PpKQklc22wjdc3bvbk1q0aKGyP957+0nQtm1bXzcBfqxly5Yqv/DCC5ne9/PPP1fZnC+CnKFJkyYqlytX7rHbJiYmquzOOjEZKVWqlMrx8fHZOh5SjB49WuVixYo53X7o0KEqnzx50tNNcqhQoYLKefPmdbr9gwcPVN66davH25RdXPkAAAAAYAs6HwAAAABsQecDAAAAgC38as7Ha6+9prK5LoLJXNfDk/dQDwkJUXnWrFkq9+nTx63jHTt2TGXz/u/wjbCwMK8du1GjRiqb84b+9a9/ee3cOdmpU6dUPnDggMq1atVy63jm/dz/+c9/Zq1hCEjmeP3Fixe7tf+lS5ccj825gKzlkzOZ8wHy5cv32G3NdTxWrlzp1rnMOR4xMTEqL1y40K3jIYW5NkuXLl2cbv/VV1+pvG3bNo+36ZHcufVP827duqlcqFAhp/snJCSovGPHDs80zIO48gEAAADAFnQ+AAAAANiCzgcAAAAAW/jVnI/ChQu7tf1PP/3k0fOnHZO/du1a9ZqrNUdMaccBi4i88cYbWW8YsmzZsmUqL126VOW33npL5RkzZqh89erVTJ8rMjJS5eXLl6scGhqqsjlnCZlz6NAhlbt3767yli1bVC5evLjT4y1atEjl5ORklb/++mt3m4gA8u6776pszs0yXb58WeVOnTo5Hh8+fNhj7YL/KliwYKa3NX8LuMucT2KuG4LMMed39u3bV+VcufR/izfXkVuyZInK9+7d81jbgoODVW7Tpo3KI0eOdLq/uY5c+/btVb5+/XrWG+clXPkAAAAAYAs6HwAAAABsQecDAAAAgC38as5HxYoV3dreXDvDFXNcnblWx5QpUxyP3RnTKZJ+/L65dsC1a9fcOh68Y8+ePSrXrVtX5cGDB6s8ceJEx2NzLoC5Fsz06dNVLl26tMqrVq1Sed++fZloMVwxx9mbf4tdu3Z1un/RokVVXr9+vcrnzp1TuX///o7H5j38szu+22TWpzku2TR37lyVN2/e7NH25ARt27ZVObtrNjF368kzZMgQp6/fuXPH8dicR+guc+4Ba8dkTdWqVVV+/vnnnW5/4sQJlT35d26u3WKuOTJhwgSn+5tzPD777DOVA+EziSsfAAAAAGxB5wMAAACALeh8AAAAALCFX8352Lhxo8rm/fvN8c5VqlRR2RyDP3ToUJU7duyocr169TLdtgcPHqg8f/58lT/55BOVmePhn1q3bq1yXFycymPGjFE57fh/8z01tzXHbTqbKyCixwXDcwYOHKiyOderQ4cOTvc35/YUK1ZM5Q0bNjgem2uAbN26VeUFCxY4PVfTpk1VNu/P/s477zhtm8myLKevQ+SVV15ROW/evG7tP2fOHA+2BjlR2t8eP//8c7aOdfz4cacZmWP+nQcFBTnd3lzHI0+ePCqbcwVbtGjh9HjVq1d3PDbXGHH1GWR+rpu/N6dNm+Z0f3/ElQ8AAAAAtqDzAQAAAMAWdD4AAAAA2CLIyuIg4Rs3bkh0dLRHG2OOe/vpp59UTjtmztuWLVum8vjx41U+c+aMbW3xloSEBImKivLY8bxRE95mjp005wvcvn3b8dgcbx8ZGany2bNnVW7VqpXK//vf/7LcTjt4uh5E/KMmzPMXKlRI5SNHjqjsal6FM3fv3lXZnPdjMv+9zbaZ89zMtp06dUrlF154QeXLly87Pb8rOeEzwpyzY96/PzQ01On+PXv2VHn16tUqm2PDc7qcUBPuql+/vsqbNm1S2Wx/2jUkzLWAcqJAqAlzzSTz96WrNZRcMeeQuPPT2tzXXMfDXCvGnG/qj1zVBFc+AAAAANiCzgcAAAAAW9D5AAAAAGALv1rn49atWyqvWbNG5dKlS6uc3TGG5hj84cOHOx5v375dvfakjet9UgwbNkzlS5cuqfz+++87Hpv3+b548aLKbdq0Udnf53g8KRISEpzmuXPnqmyO1e3Ro4fKzsYimzVSoUKFTLczK9auXatydud45ETmeGpXczzMf8N9+/apzHfBk2fIkCEqm58BBw8eVDknzAnNaeLj41U2/47Dw8Nta8v169dVNueRjRo1yun2OQFXPgAAAADYgs4HAAAAAFvQ+QAAAABgC7+a82GaMGGCyuY97QcNGqRynTp1nB5v0qRJKq9cuVLlQ4cOudtEBLj79++rPHHiRKcZOc/QoUOdvr5u3TqV065HZH5G1atXz3MNk/RrBIwdO1blnTt3evR8OdHNmzdVjouLU7lMmTIqf/jhhyozdwsNGjRQ2Vxv59NPP1XZnA8I37tw4YLKDRs2VNmcZ1GkSBGVmzVrpvKVK1dU3rZtm8obN25UOTEx8bHb3rhx4zGtzrm48gEAAADAFnQ+AAAAANiCzgcAAAAAWwRZ5k3tM+nGjRtO73cP/5eQkJDttVLSoiYCm6frQYSaCHR8RsD0JNbEiRMnVN6zZ4/KXbt2tbM5fudJrAk456omuPIBAAAAwBZ0PgAAAADYgs4HAAAAAFv49TofAAAAvlS+fHlfNwHIUbjyAQAAAMAWdD4AAAAA2ILOBwAAAABb0PkAAAAAYAs6HwAAAABsQecDAAAAgC3ofAAAAACwBZ0PAAAAALag8wEAAADAFnQ+AAAAANgiy50Py7I82Q74gKffQ2oisHnj/aMmAhufETBREzBREzC5eg+z3PlITEzM6q7wE55+D6mJwOaN94+aCGx8RsBETcBETcDk6j0MsrLYxUxOTpZz585JZGSkBAUFZalx8A3LsiQxMVFKlCghuXJ5buQdNRGYvFUPItREoOIzAiZqAiZqAqbM1kSWOx8AAAAA4A4mnAMAAACwBZ0PAAAAALag8wEAAADAFnQ+AAAAANiCzgcAAAAAW9D5AAAAAGALOh8AAAAAbEHnAwAAAIAt6HwAAAAAsAWdDwAAAAC2oPMBAAAAwBZ0PgAAAADY4v8B7HRXOoxSsTcAAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 1000x300 with 6 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"n_samples_show = 6\n",
"\n",
"data_iter = iter(train_loader)\n",
"fig, axes = plt.subplots(nrows=1, ncols=n_samples_show, figsize=(10, 3))\n",
"\n",
"while n_samples_show > 0:\n",
" images, targets = data_iter.__next__()\n",
"\n",
" axes[n_samples_show - 1].imshow(images[0, 0].numpy().squeeze(), cmap=\"gray\")\n",
" axes[n_samples_show - 1].set_xticks([])\n",
" axes[n_samples_show - 1].set_yticks([])\n",
" axes[n_samples_show - 1].set_title(\"Labeled: {}\".format(targets[0].item()))\n",
"\n",
" n_samples_show -= 1"
]
},
{
"cell_type": "code",
"execution_count": 93,
"id": "structural-chuck",
"metadata": {},
"outputs": [],
"source": [
"# Test Dataset\n",
"# -------------\n",
"\n",
"# Set test shuffle seed (for reproducibility)\n",
"# manual_seed(5)\n",
"\n",
"n_samples = 50\n",
"\n",
"# Use pre-defined torchvision function to load MNIST test data\n",
"X_test = datasets.MNIST(\n",
" root=\"./data\", train=False, download=True, transform=transforms.Compose([transforms.ToTensor()])\n",
")\n",
"\n",
"# Filter out labels (originally 0-9), leaving only labels 0 and 1\n",
"idx = np.append(\n",
" np.where(X_test.targets == 0)[0][:n_samples], np.where(X_test.targets == 1)[0][:n_samples]\n",
")\n",
"X_test.data = X_test.data[idx]\n",
"X_test.targets = X_test.targets[idx]\n",
"\n",
"# Define torch dataloader with filtered data\n",
"test_loader = DataLoader(X_test, batch_size=batch_size, shuffle=True)"
]
},
{
"cell_type": "markdown",
"id": "abroad-morris",
"metadata": {},
"source": [
"### Step 2: Defining the QNN and Hybrid Model"
]
},
{
"cell_type": "markdown",
"id": "super-tokyo",
"metadata": {},
"source": [
"This second step shows the power of the `TorchConnector`. After defining our quantum neural network layer (in this case, a `EstimatorQNN`), we can embed it into a layer in our torch `Module` by initializing a torch connector as `TorchConnector(qnn)`.\n",
"\n",
"**⚠️ Attention:**\n",
"In order to have an adequate gradient backpropagation in hybrid models, we MUST set the initial parameter `input_gradients` to TRUE during the qnn initialization."
]
},
{
"cell_type": "code",
"execution_count": 94,
"id": "urban-purse",
"metadata": {},
"outputs": [],
"source": [
"# Define and create QNN\n",
"def create_qnn():\n",
" feature_map = ZZFeatureMap(2)\n",
" ansatz = RealAmplitudes(2, reps=1)\n",
" qc = QuantumCircuit(2)\n",
" qc.compose(feature_map, inplace=True)\n",
" qc.compose(ansatz, inplace=True)\n",
"\n",
" # REMEMBER TO SET input_gradients=True FOR ENABLING HYBRID GRADIENT BACKPROP\n",
" qnn = EstimatorQNN(\n",
" circuit=qc,\n",
" input_params=feature_map.parameters,\n",
" weight_params=ansatz.parameters,\n",
" input_gradients=True,\n",
" )\n",
" return qnn\n",
"\n",
"\n",
"qnn4 = create_qnn()"
]
},
{
"cell_type": "code",
"execution_count": 95,
"id": "exclusive-productivity",
"metadata": {},
"outputs": [],
"source": [
"# Define torch NN module\n",
"\n",
"\n",
"class Net(Module):\n",
" def __init__(self, qnn):\n",
" super().__init__()\n",
" self.conv1 = Conv2d(1, 2, kernel_size=5)\n",
" self.conv2 = Conv2d(2, 16, kernel_size=5)\n",
" self.dropout = Dropout2d()\n",
" self.fc1 = Linear(256, 64)\n",
" self.fc2 = Linear(64, 2) # 2-dimensional input to QNN\n",
" self.qnn = TorchConnector(qnn) # Apply torch connector, weights chosen\n",
" # uniformly at random from interval [-1,1].\n",
" self.fc3 = Linear(1, 1) # 1-dimensional output from QNN\n",
"\n",
" def forward(self, x):\n",
" x = F.relu(self.conv1(x))\n",
" x = F.max_pool2d(x, 2)\n",
" x = F.relu(self.conv2(x))\n",
" x = F.max_pool2d(x, 2)\n",
" x = self.dropout(x)\n",
" x = x.view(x.shape[0], -1)\n",
" x = F.relu(self.fc1(x))\n",
" x = self.fc2(x)\n",
" x = self.qnn(x) # apply QNN\n",
" x = self.fc3(x)\n",
" return cat((x, 1 - x), -1)\n",
"\n",
"\n",
"model4 = Net(qnn4)"
]
},
{
"cell_type": "markdown",
"id": "academic-specific",
"metadata": {},
"source": [
"### Step 3: Training"
]
},
{
"cell_type": "code",
"execution_count": 96,
"id": "precious-career",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training [10%]\tLoss: -1.2459\n",
"Training [20%]\tLoss: -1.8906\n",
"Training [30%]\tLoss: -2.5037\n",
"Training [40%]\tLoss: -3.0580\n",
"Training [50%]\tLoss: -3.7746\n",
"Training [60%]\tLoss: -4.3899\n",
"Training [70%]\tLoss: -4.9765\n",
"Training [80%]\tLoss: -5.6211\n",
"Training [90%]\tLoss: -6.1864\n",
"Training [100%]\tLoss: -6.8356\n"
]
}
],
"source": [
"# Define model, optimizer, and loss function\n",
"optimizer = optim.Adam(model4.parameters(), lr=0.003)\n",
"loss_func = NLLLoss()\n",
"\n",
"# Start training\n",
"epochs = 10 # Set number of epochs\n",
"loss_list = [] # Store loss history\n",
"model4.train() # Set model to training mode\n",
"\n",
"for epoch in range(epochs):\n",
" total_loss = []\n",
" for batch_idx, (data, target) in enumerate(train_loader):\n",
" optimizer.zero_grad(set_to_none=True) # Initialize gradient\n",
" output = model4(data) # Forward pass\n",
" loss = loss_func(output, target) # Calculate loss\n",
" loss.backward() # Backward pass\n",
" optimizer.step() # Optimize weights\n",
" total_loss.append(loss.item()) # Store loss\n",
" loss_list.append(sum(total_loss) / len(total_loss))\n",
" print(\"Training [{:.0f}%]\\tLoss: {:.4f}\".format(100.0 * (epoch + 1) / epochs, loss_list[-1]))"
]
},
{
"cell_type": "code",
"execution_count": 97,
"id": "spoken-stationery",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot loss convergence\n",
"plt.plot(loss_list)\n",
"plt.title(\"Hybrid NN Training Convergence\")\n",
"plt.xlabel(\"Training Iterations\")\n",
"plt.ylabel(\"Neg. Log Likelihood Loss\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "physical-closure",
"metadata": {},
"source": [
"Now we'll save the trained model, just to show how a hybrid model can be saved and re-used later for inference. To save and load hybrid models, when using the TorchConnector, follow the PyTorch recommendations of saving and loading the models."
]
},
{
"cell_type": "code",
"execution_count": 98,
"id": "regulation-bread",
"metadata": {},
"outputs": [],
"source": [
"torch.save(model4.state_dict(), \"model4.pt\")"
]
},
{
"cell_type": "markdown",
"id": "pacific-flour",
"metadata": {},
"source": [
"### Step 4: Evaluation"
]
},
{
"cell_type": "markdown",
"id": "fabulous-tribe",
"metadata": {},
"source": [
"We start from recreating the model and loading the state from the previously saved file. You create a QNN layer using another simulator or a real hardware. So, you can train a model on real hardware available on the cloud and then for inference use a simulator or vice verse. For a sake of simplicity we create a new quantum neural network in the same way as above."
]
},
{
"cell_type": "code",
"execution_count": 99,
"id": "prospective-flooring",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<All keys matched successfully>"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"qnn5 = create_qnn()\n",
"model5 = Net(qnn5)\n",
"model5.load_state_dict(torch.load(\"model4.pt\"))"
]
},
{
"cell_type": "code",
"execution_count": 100,
"id": "spectacular-conservative",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Performance on test data:\n",
"\tLoss: -7.0412\n",
"\tAccuracy: 100.0%\n"
]
}
],
"source": [
"model5.eval() # set model to evaluation mode\n",
"with no_grad():\n",
"\n",
" correct = 0\n",
" for batch_idx, (data, target) in enumerate(test_loader):\n",
" output = model5(data)\n",
" if len(output.shape) == 1:\n",
" output = output.reshape(1, *output.shape)\n",
"\n",
" pred = output.argmax(dim=1, keepdim=True)\n",
" correct += pred.eq(target.view_as(pred)).sum().item()\n",
"\n",
" loss = loss_func(output, target)\n",
" total_loss.append(loss.item())\n",
"\n",
" print(\n",
" \"Performance on test data:\\n\\tLoss: {:.4f}\\n\\tAccuracy: {:.1f}%\".format(\n",
" sum(total_loss) / len(total_loss), correct / len(test_loader) / batch_size * 100\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 101,
"id": "color-brave",
"metadata": {
"tags": [
"nbsphinx-thumbnail"
]
},
"outputs": [
{
"data": {
"image/png": "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dnJysrbvsssu0/Lff/8dusKAMMWZDwAAAABWMHwAAAAAsILhAwAAAIAVrPkAUKOY11TXrVtXyytWrNDyt99+G/KaAmXe9wPhrXv37lXuP3DggKVKYNOSJUu07L/mw+v1avv87wECiIisXbvW7RKs48wHAAAAACsYPgAAAABYwfABAAAAwArWfACoUZ544gktezweLW/YsMFmOUH19ddfa7lly5ZaTk1N1fKePXtCXhPOat++fZX7p0+fbqkS2LR3795K9508eVLLpaWloS4HEebQoUNul2AdZz4AAAAAWMHwAQAAAMAKhg8AAAAAVtTqNR/VXRtelfXr1we7HAABaNOmjZZbtWqlZaWUzXJC6ocfftByt27dtJyYmKhl1nyEXteuXZ3tYcOGafvy8/O1vHr1ais1IXwkJydr2bwPEfd+QW3EmQ8AAAAAVjB8AAAAALCiVl92ZfK/PKO6SzXMyx9QM6WlpTnb5mV527dvt10OzsG8jMHMNUnr1q21bH5F48GDB22WAxHp1auXs2323hdffKFl82tXUTOcOHFCy8eOHXO2GzZsaLscIOxx5gMAAACAFQwfAAAAAKxg+AAAAABgBWs+ApSRkeF2CbCgrKys0n2bNm2yWAmCZe7cuW6XELB+/fppefPmzVr+/fffbZYDEbnuuuucbXOt4OLFi22XAxeYX2n94YcfOtuPPPKItm/QoEFanjp1augKQ9ho1KiRs/3rr79q+/7880/L1biPMx8AAAAArGD4AAAAAGAFwwcAAAAAK2r1mo9t27YF/Fzu81E7+F9Db17PXbduXdvl4DyY92Mx+X8Hf7iJi4vT8sKFC7Vs/reVlJSEvCbomjZtquWbb77Z2Tav5V66dKmVmhBetm7d6mybaz7atWtnuxyEgZ49ezrbhYWF2r7S0lLb5biOMx8AAAAArGD4AAAAAGAFwwcAAAAAK2r1mo/169drubprxQN9LCJXcnKys21+5llZWVp++OGHrdSEqplrc0xJSUla9vl8oSynSl6vV8vz5s3Tct++fbV86tQpLU+bNi00haFSQ4cO1XKTJk2c7VWrVlmuBuHo6NGjle7r1auXxUrglhYtWmg5LS3N2c7OzrZdTtjhzAcAAAAAKxg+AAAAAFjB8AEAAADAilq95sPkf614ddeNV7cfNcPhw4edbT7zmuH+++/X8ptvvmntvc37eJhrPAYOHFjl89966y0t5+XlBaUunL/U1NRK9xUXF1usBOHq008/dbsEuCw6Wv/f6zp16rhUSXjizAcAAAAAKxg+AAAAAFjB8AEAAADACtZ8BOj33393uwRYUFJS4nYJqMZff/2l5cLCQi0nJiZquVOnTiGvqTITJ07UcnVrPEaPHq3ljz76KNgl4QL179+/0n0rVqywWAkigXl/qISEBC0PGDBAy8uXLw95TQg98++hvXv3ulRJeOLMBwAAAAArGD4AAAAAWMHwAQAAAMAK1nwE6PPPP3e7BAAi8scff2j5ySef1PLHH3+s5SFDhmj5+PHjWp40aZKWDx06pGX/728315O0atVKy5MnT9Zy9+7dtXzq1Cktjx07Vstz584VuKtbt25abtq0qUuVIBKZ94fiflG1Q8eOHbV85ZVXOtv79++3XU7Y4cwHAAAAACsYPgAAAABYwfABAAAAwArWfPjJz893ts3r9QBEhm+++UbLBQUFWm7Xrp2WH3roIS336dNHy1u2bNFyXFycs923b98Lqs1cnzJt2jQts8Yj/Nx1111avuSSS7Ts//fGhg0brNQEILzddNNNWt63b5+zvWjRItvlhB3OfAAAAACwguEDAAAAgBUMHwAAAACsYM2HH5/P52ynp6e7VwjC0ubNm7V88803a/nBBx/U8gcffBDymlCR/7W1IiJ33HGHlvPy8rRs3psjJSWlyuzxeJzt6r6z37wf0COPPKLlwsLCKp8P+/zX9IiIZGZmVvn4xYsXO9unT58OSU2IXIcPH9Zyw4YN3SkErjp69KizbfZEbcSZDwAAAABWMHwAAAAAsILhAwAAAIAVrPnws3LlSmfbvM537dq1Wi4qKrJSE8JHVlaWlmfMmKFl8/v/ER7MdRVdu3bVsrnm4/nnn9dyv379tPzmm29W+toLFy6s8r1ZExD+/v33Xy0XFxdrefny5VqeOXNmyGtC5DLvI2Tey2fjxo02y4FLzLWItR1nPgAAAABYwfABAAAAwAqGDwAAAABWeFR1X1RfiaNHj9a476uOjj67BOa5557T9h0/flzL06dPt1JTKB05ckQaNGgQtNeriT1RmwS7H0ToiUjHMQImegImegKm6nqCMx8AAAAArGD4AAAAAGAFwwcAAAAAK7jPh5+ysjJn+4UXXnCvEAAAAKAG4swHAAAAACsYPgAAAABYwfABAAAAwAqGDwAAAABWMHwAAAAAsILhAwAAAIAVDB8AAAAArGD4AAAAAGAFwwcAAAAAKxg+AAAAAFgR8PChlApmHXBBsD9DeiKyheLzoyciG8cImOgJmOgJmKr7DAMePo4dOxboUxEmgv0Z0hORLRSfHz0R2ThGwERPwERPwFTdZ+hRAY6Y5eXl4vP5xOv1isfjCag4uEMpJceOHZOkpCSJigrelXf0RGQKVT+I0BORimMETPQETPQETOfbEwEPHwAAAABwIVhwDgAAAMAKhg8AAAAAVjB8AAAAALCC4QMAAACAFQwfAAAAAKxg+AAAAABgBcMHAAAAACsYPgAAAABYwfABAAAAwAqGDwAAAABWMHwAAAAAsILhAwAAAIAV/we/mQeEcgDrdgAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 1000x300 with 6 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot predicted labels\n",
"\n",
"n_samples_show = 6\n",
"count = 0\n",
"fig, axes = plt.subplots(nrows=1, ncols=n_samples_show, figsize=(10, 3))\n",
"\n",
"model5.eval()\n",
"with no_grad():\n",
" for batch_idx, (data, target) in enumerate(test_loader):\n",
" if count == n_samples_show:\n",
" break\n",
" output = model5(data[0:1])\n",
" if len(output.shape) == 1:\n",
" output = output.reshape(1, *output.shape)\n",
"\n",
" pred = output.argmax(dim=1, keepdim=True)\n",
"\n",
" axes[count].imshow(data[0].numpy().squeeze(), cmap=\"gray\")\n",
"\n",
" axes[count].set_xticks([])\n",
" axes[count].set_yticks([])\n",
" axes[count].set_title(\"Predicted {}\".format(pred.item()))\n",
"\n",
" count += 1"
]
},
{
"cell_type": "markdown",
"id": "prompt-visibility",
"metadata": {},
"source": [
"🎉🎉🎉🎉\n",
"**You are now able to experiment with your own hybrid datasets and architectures using Qiskit Machine Learning.** \n",
"**Good Luck!**"
]
},
{
"cell_type": "code",
"execution_count": 102,
"id": "related-wheat",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"<h3>Version Information</h3><table><tr><th>Software</th><th>Version</th></tr><tr><td><code>qiskit</code></td><td>0.44.1</td></tr><tr><td><code>qiskit-terra</code></td><td>0.25.1</td></tr><tr><td><code>qiskit_machine_learning</code></td><td>0.6.1</td></tr><tr><th colspan='2'>System information</th></tr><tr><td>Python version</td><td>3.10.8</td></tr><tr><td>Python compiler</td><td>GCC 10.4.0</td></tr><tr><td>Python build</td><td>main, Nov 22 2022 08:26:04</td></tr><tr><td>OS</td><td>Linux</td></tr><tr><td>CPUs</td><td>8</td></tr><tr><td>Memory (Gb)</td><td>31.142807006835938</td></tr><tr><td colspan='2'>Wed Oct 04 03:03:10 2023 UTC</td></tr></table>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div style='width: 100%; background-color:#d5d9e0;padding-left: 10px; padding-bottom: 10px; padding-right: 10px; padding-top: 5px'><h3>This code is a part of Qiskit</h3><p>© Copyright IBM 2017, 2023.</p><p>This code is licensed under the Apache License, Version 2.0. You may<br>obtain a copy of this license in the LICENSE.txt file in the root directory<br> of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.<p>Any modifications or derivative works of this code must retain this<br>copyright notice, and modified files need to carry a notice indicating<br>that they have been altered from the originals.</p></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import qiskit.tools.jupyter\n",
"\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.8"
},
"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": false
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {
"020e76854d5b4cbf89de4fa4e0e7fe5d": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"width": "70px"
}
},
"0c6d3d2eca32484397afea46b84a7d63": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_be6c53929c594523b89fffdd02fd7063",
"style": "IPY_MODEL_c505d57d12f64261a0e396e592435e4a",
"value": "<h5>Message</h5>"
}
},
"20c30adc25d1482cbaba3dfc09db9dd5": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HBoxModel",
"state": {
"children": [
"IPY_MODEL_901ade06daad4608a24e52f25d07389b",
"IPY_MODEL_79eb23751bba4b2eb3815314ecd99409",
"IPY_MODEL_2534dc13c31249a0a7d72c4aad5d40d7",
"IPY_MODEL_76b4538f39654e5292a18e318b355a19",
"IPY_MODEL_0c6d3d2eca32484397afea46b84a7d63"
],
"layout": "IPY_MODEL_887b3b8baaee4608acceea37737e9ec6"
}
},
"2534dc13c31249a0a7d72c4aad5d40d7": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_d4164f3e3c2b4b7a95e44e4ede088f19",
"style": "IPY_MODEL_737a2908a22c48b482832dfb3930b234",
"value": "<h5>Status</h5>"
}
},
"25fcb880c5324fd0b629be2aeeba354b": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"width": "190px"
}
},
"28a9c58b53a54eef8c3deef65bfb776b": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"margin": "0px 0px 10px 0px"
}
},
"28f4f198e39948ea92fe41e677240ff0": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "ButtonStyleModel",
"state": {
"font_family": null,
"font_size": null,
"font_style": null,
"font_variant": null,
"font_weight": null,
"text_color": null,
"text_decoration": null
}
},
"34b5e3008f8047f98fac17f6af9df152": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"width": "145px"
}
},
"38eafe75b4f84b35a6cfddcb99d4d727": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"40860bd5f1b04a2098a255f4f07f01ed": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"6fda82bf00c6407bb14c52e236b5b6e9": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "ButtonModel",
"state": {
"button_style": "primary",
"description": "Clear",
"layout": "IPY_MODEL_ee08b620734940dc843327aa49e871c8",
"style": "IPY_MODEL_28f4f198e39948ea92fe41e677240ff0",
"tooltip": null
}
},
"737a2908a22c48b482832dfb3930b234": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"76b4538f39654e5292a18e318b355a19": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_020e76854d5b4cbf89de4fa4e0e7fe5d",
"style": "IPY_MODEL_38eafe75b4f84b35a6cfddcb99d4d727",
"value": "<h5>Queue</h5>"
}
},
"79eb23751bba4b2eb3815314ecd99409": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_34b5e3008f8047f98fac17f6af9df152",
"style": "IPY_MODEL_40860bd5f1b04a2098a255f4f07f01ed",
"value": "<h5>Backend</h5>"
}
},
"887b3b8baaee4608acceea37737e9ec6": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"margin": "0px 0px 0px 37px",
"width": "600px"
}
},
"901ade06daad4608a24e52f25d07389b": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_25fcb880c5324fd0b629be2aeeba354b",
"style": "IPY_MODEL_95174e8be52c433288ee8e18e71da63e",
"value": "<h5>Job ID</h5>"
}
},
"95174e8be52c433288ee8e18e71da63e": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"be6c53929c594523b89fffdd02fd7063": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {}
},
"c505d57d12f64261a0e396e592435e4a": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"c98a64a0bba2446c9687703c313686ab": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLModel",
"state": {
"layout": "IPY_MODEL_28a9c58b53a54eef8c3deef65bfb776b",
"style": "IPY_MODEL_e33245ea021140ed8b57d93b5f8d2b49",
"value": "<p style='font-family: IBM Plex Sans, Arial, Helvetica, sans-serif; font-size: 20px; font-weight: medium;'>Circuit Properties</p>"
}
},
"d4164f3e3c2b4b7a95e44e4ede088f19": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"width": "95px"
}
},
"e33245ea021140ed8b57d93b5f8d2b49": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "HTMLStyleModel",
"state": {
"description_width": "",
"font_size": null,
"text_color": null
}
},
"e33ae7a1c71149c88233957c654bb94b": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"grid_template_areas": "\n \". . . . right \"\n ",
"grid_template_columns": "20% 20% 20% 20% 20%",
"width": "100%"
}
},
"e65a38da17d2459b817f8a084178b1a0": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "2.0.0",
"model_name": "GridBoxModel",
"state": {
"children": [
"IPY_MODEL_6fda82bf00c6407bb14c52e236b5b6e9"
],
"layout": "IPY_MODEL_e33ae7a1c71149c88233957c654bb94b"
}
},
"ee08b620734940dc843327aa49e871c8": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "2.0.0",
"model_name": "LayoutModel",
"state": {
"grid_area": "right",
"padding": "0px 0px 0px 0px",
"width": "70px"
}
}
},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}