1607 lines (1607 with data), 271.4 kB
{
"cells": [
{
"cell_type": "code",
"source": [
"# !pip install qiskit\n",
"# !pip install qiskit_machine_learning\n",
"# !pip install qiskit-aer-gpu-cu11\n",
"import time\n",
"seconds = time.time()\n",
"print(\"Time in seconds since beginning of run:\", seconds)\n",
"local_time = time.ctime(seconds)\n",
"print(local_time)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "Az2xrKMZoq7-",
"outputId": "3fa7f5f7-3524-4c82-a1f1-845cd83afc59"
},
"id": "Az2xrKMZoq7-",
"execution_count": 31,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Time in seconds since beginning of run: 1701624494.5674927\n",
"Sun Dec 3 17:28:14 2023\n"
]
}
]
},
{
"cell_type": "markdown",
"id": "secondary-copying",
"metadata": {
"id": "secondary-copying"
},
"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": 32,
"id": "banned-helicopter",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "banned-helicopter",
"outputId": "b8afe2e5-a9d3-4638-b5ac-8c1947f12b9f"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-32-90557e24ff14>:18: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random_seed`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" algorithm_globals.random_seed = 42\n"
]
}
],
"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": {
"id": "unique-snapshot"
},
"source": [
"## Part 1: Simple Classification & Regression"
]
},
{
"cell_type": "markdown",
"id": "surgical-penetration",
"metadata": {
"id": "surgical-penetration"
},
"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": 33,
"id": "secure-tragedy",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 487
},
"id": "secure-tragedy",
"outputId": "e8d5aa9e-1c51-48e5-8997-f23fc9b79734"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-33-ae84619b5aeb>:8: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" X = 2 * algorithm_globals.random.random([num_samples, num_inputs]) - 1\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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GhGRweFSDVyqwegpVUpR+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//vMfjBkzBoIgYN68eejatSvu3r0rdlhEBkMqBVYUrNNbJMkpfL58eUE9Mmx6TXDs7OwglUqRkZGhUZ6RkQFHR8dX7rtkyRIsXLgQhw8ffu009O7u7rCzs8PNmzeLfd3c3BwymUxjI6qKrKyssH79euzYsQM1atTAiRMnIJfL8dtvv4kdGpHBCAwEwsKAuprr9MLFpaA8sHKt01tl6TXBMTMzQ+vWrTXu96tUKhw9ehQ+Pj4l7rdo0SLMnz8fERER8PT0fO37pKam4uHDh3DiTVEirQwZMgRxcXFo2bIl7t+/j4CAAGzZskXssIgMRmAgcPs2cPx4QYfi48eBpCQmN5WJqb7fICQkBCNGjICnpye8vLywfPly5OTkYNSoUQCAoKAg1K1bFwsWLAAAfP3115gzZw527twJNzc3dV+dGjVqoEaNGsjOzsbnn3+Ofv36wdHREbdu3cL06dPRqFEj+Pv767s5REajcePGOHv2LKZOnYoffviBc0kRvUQqBTp1EjsKKiu998EZOHAglixZgjlz5kAulyMhIQERERHqjsfJyclIS0tT11+9ejXy8vLQv39/ODk5qbclS5YAAKRSKS5evIjevXujcePGGD16NFq3bo2oqCiYm5vruzlERsXCwgKrVq3C5cuXNW4bX7p0ScSoiIjKT+/z4BgizoNDVLK9e/di4MCBmDp1Kr766iuYmZmJHRIREQADmgeHiCqfP/74AwDw3//+Fx06dMDt27fFDYiIqAyY4BCRhi+//BLh4eGwtbVFTEwMPDw8yjxrOBGRWJjgEFER//73vxEfHw8vLy88fvwY//73vxEcHIzc3FyxQyMi0goTHCIqlpubG6KiojB16lQAwDfffINTp06JHBURkXb0PkyciCovMzMzLFmyBB07dsSFCxfQtWtXsUMiItIKr+AQ0Wv16tULc+fOVT9PSUnBtGnT8OzZMxGjIiIqGRMcIioVQRAwdOhQLFmyBD4+Prhx44bYIRERFcEEh4hKRSKRYNasWbCzs0NCQgJatWqFXbt2iR0WEZEGJjhEVGoBAQFISEhAhw4dkJ2djSFDhmDs2LF48uSJ2KEREQFggkNEZVS3bl0cPXoUs2fPhkQiwYYNG+Dt7Y3k5GSxQyMiYoJDRGVnamqKefPm4fDhw3BwcIBEIoG9vb3YYRERcZg4EZWfn58fEhISkJ2dDUtLSwCAUqlEbm4urKysRI6OiKoiXsEhIp1wdHREo0aN1M8XLFgAT09PXL58WcSoiKiqYoJDRDqXk5ODdevWITExEV5eXti4cSMEQRA7LCKqQpjgEJHOVa9eHefPn0e3bt3w9OlTjBkzBsOHD0dWVpbYoRFRFcEEh4j0ok6dOvj111+xYMECSKVS7NixA56envjjjz/EDo2IqgAmOESkNyYmJpg5cyYiIyPh4uKCP//8E506dUJmZqbYoRGRkeMoKiLSu/bt2yM+Ph4jR47Ev/71L9jY2IgdEhEZOSY4RFQh7Ozs8NNPP2mUxcXFAQBat24tRkhEZMR4i4qIKoxEIoFEIgEAPH78GO+99x7atWuHlStXcpQVEekUExwiEk3Lli2Rl5eHSZMmoV+/fvj777/FDomIjAQTHCISha2tLcLDw7FixQpUq1YN+/fvR6tWrRAbGyt2aERkBJjgEJFoJBIJJk2ahDNnzsDd3R23b9/GO++8g6VLl/KWFRGVCxMcIhKdp6cnLly4gP79+yM/Px/Hjh1jgkNE5cJRVERkEGxsbLB3715s2rQJffv2hYlJwd9fgiCoOyYTEWmLV3CIyGBIJBKMHj0atWvXBlCQ3IwZMwZff/01VCqVyNERUWXCKzhEZLBOnDiBTZs2qf+9detW2NvbixwVEVUGvIJDRAarY8eOWL9+PSwsLPDrr79CLpfj5MmTYodFRJUAExwiMlgSiQRjxoxBbGwsmjZtirt376Jz58744osvoFQqxQ6PiAwYExwiMngtWrTA+fPnMWLECKhUKsyePRsjRowQOywiMmBMcIioUqhevTq2bNmCLVu2oEaNGhg5cqTYIRGRAauQBGfVqlVwc3ODhYUFvL29XztT6b59+9C0aVNYWFigRYsWOHTokMbrgiBgzpw5cHJygqWlJfz8/HDjxg19NoGIDMSIESNw+/Zt+Pn5qcsuX77MW1ZEpEHvCc6ePXsQEhKCuXPn4sKFC2jZsiX8/f1x7969YuufOXMGgwcPxujRoxEfH4++ffuib9++uHz5srrOokWL8M0332DNmjWIiYlB9erV4e/vj2fPnum7OURkAAqHkQPArVu38M4778DPzw93794VMSoiMiQSQc/ThXp7e6NNmzb49ttvAQAqlQqurq6YOHEiZs6cWaT+wIEDkZOTg59//lld1rZtW8jlcqxZswaCIMDZ2RlTp07FJ598AgDIzMyEg4MDtmzZgkGDBr02JoVCARsbG2RmZkImk+mopUQkhl9//RUDBgxAdnY27O3tsX37dvj7+4sdFhHpQWm+v/V6BScvLw9xcXEal5JNTEzg5+eH6OjoYveJjo7WqA8A/v7+6vpJSUlIT0/XqGNjYwNvb+8Sj5mbmwuFQqGxEZFx6N69O+Li4tCyZUvcv38fAQEBmDVrFvLz88UOjYhEpNcE58GDB1AqlXBwcNAod3BwQHp6erH7pKenv7J+4WNpjrlgwQLY2NioN1dX1zK1h4gMU+PGjXH27Fl8+OGHAAo+8507d0ZqaqrIkRGRWKrEKKrQ0FBkZmaqt5SUFLFDIiIds7CwwOrVq7Fnzx5YW1vj1KlT+O6778QOi4hEotcEx87ODlKpFBkZGRrlGRkZcHR0LHYfR0fHV9YvfCzNMc3NzSGTyTQ2IjJOAwYMQHx8PEaPHo3PPvtM7HCISCR6TXDMzMzQunVrHD16VF2mUqlw9OhR+Pj4FLuPj4+PRn0AOHLkiLp+gwYN4OjoqFFHoVAgJiamxGMSUdXSsGFDbNiwAWZmZgCA/Px8TJo0CX/99ZfIkRFRRdH7LaqQkBCsX78eW7duRWJiIsaPH4+cnByMGjUKABAUFITQ0FB1/eDgYEREROC///0vrl27hs8++wznz5/HhAkTABRM3T558mR88cUXOHjwIC5duoSgoCA4Ozujb9+++m4OAVCqlIi8HYldl3Yh8nYklCrOP0KG7YsvvsDKlSvh4eGBH3/8UexwiKgiCBVg5cqVQr169QQzMzPBy8tLOHv2rPq1jh07CiNGjNCov3fvXqFx48aCmZmZ8Oabbwq//PKLxusqlUqYPXu24ODgIJibmwtdu3YVrl+/rnU8mZmZAgAhMzOzXO2qin64+oPgstRFwGdQby5LXYQfrv4gdmhEJUpKShK8vLwEAAIAITg4WMjNzRU7LCIqpdJ8f+t9HhxDxHlwyiY8MRz99/aHAM1fGQkkAICwAWEIbBYoRmhEr5WXl4dZs2bhv//9LwDA09MTe/bsgbu7u8iREZG2DGYeHDIeSpUSwRHBRZIbAOqyyRGTebuKDJaZmRmWLFmCgwcPolatWjh//jw8PDzw22+/iR0aEekBExzSSlRyFFIVJc8pIkBAiiIFUclRFRgVUen16tUL8fHxaNeuHfLz81GvXj2xQyIiPTAVOwCqHNKy0nRaj0hM9erVQ2RkJP744w80a9ZMXa5QKHjbmshI8AoOacXJ2kmn9YjEVq1aNXh6eqqfR0VFoX79+ti9e7eIURGRrjDBIa341vOFi8xF3aH4ZRJI4CpzhW893wqOjEg3Vq9ejcePH2Pw4MH44IMP8PTpU7FDIqJyYIJDWpGaSLEiYEWxrxUmPcsDlkNqIq3IsIh0Ztu2bZg9ezYkEgnWrVsHb29vXLt2TeywiKiMmOBQqdSyrFVsGYeIU2VnamqKefPm4fDhw3BwcMClS5fg6emJ7du3ix0aEZUBExzSSuEcOA+fPizyWnFlRJWVn58fEhIS0KVLF+Tk5CAoKKjI8jFEZPg40R9HTLyWUqWE2wq3EoeJSyCBi8wFScFJvEVFRkOpVOKrr75CYmIiduzYAYmk+P5nRFRxONEf6RTnwKGqSCqVYvbs2RrJzePHj7Fz505Uwb8LDZJSCURGArt2FTwqOc8ovYAJDr0W58ChqqwwuREEAWPHjsXQoUMRFBSE7OxskSOr2sLDATc3oHNnYMiQgkc3t4JyIoAJDmmBc+AQFSQ4rVu3hlQqxffff4/WrVvjjz/+EDusKik8HOjfH0h96cLynTsF5UxyCGCCQ1rgHDhEgImJCWbOnInIyEi4uLjgzz//hLe3N9auXctbVhVIqQSCg4HifuSFZZMn83YVMcEhLbw4B87LSQ7nwKGqpn379khISEDPnj2Rm5uLDz/8EIMHD4ZCoRA7tCohKqrolZsXCQKQklJQj6o2JjiklcBmgQgbEIa6sroa5S4yF86BQ1VO7dq1cfDgQSxZsgSmpqY4deoU8vLyxA6rSkjTsquftvXIeHGxTdJaYLNA9GnSB1HJUUjLSoOTtRN86/nyyg1VSSYmJpg6dSreeecdqFQq2NnZqV8TBIHDyvXEScuuftrWI+PFeXA4Dw4R6dDWrVtx8OBBbNy4Eba2tmKHY3SUyoLRUnfuFN8PRyIBXFyApCRAyr+9jA7nwSEiEkFWVhamTJmC8PBweHh4IDY2VuyQjI5UCqz4/2XxXr5IVvh8+XImN8QEh4hIZ6ytrXH48GG4u7vj9u3baN++PZYtW8ZRVjoWGAiEhQF1NbsEwsWloDyQXQIJvEXFW1REpHOZmZkYM2YMwsLCAAC9e/fG5s2bUatW0cVqqeyUyoLRUmlpBX1ufH155cbYleb7mwkOExwi0gNBELBmzRpMmTIFubm5qF+/Pi5fvowaNWqIHRpRpcU+OEREIpNIJBg/fjzOnj2LN954A0OHDmVyQ1SBOEyciEiP5HI54uLiYGlpqS5LTk6GlZWVxtByItItXsEhItIza2trmJoW/D2Zm5uLfv36QS6XI4rT7RLpDRMcIqIKlJGRgezsbNy5cwedOnXCl19+CZVKJXZYREaHCQ4RUQWqV68ezp07h6CgIKhUKnz66acICAhARkaG2KERGRUmOEREFaxGjRrYunUrNm/eDCsrKxw5cgRyuRzHjh0TOzQio8EEh4hIJCNHjsS5c+fw5ptvIj09HaGhobxdRaQjTHCIiETUvHlzxMbGYsKECdi1axdMTPjfMpEu8JNERCQyKysrrFy5Eu7u7uqyxYsX4/DhwyJGRVS5McEhIjIwJ06cwIwZMxAQEIBPP/0U+fn5YodEVOnoNcF59OgRhg4dCplMBltbW4wePRrZ2dmvrD9x4kQ0adIElpaWqFevHiZNmoTMzEyNehKJpMi2e/dufTaFiKjCeHl54YMPPoAgCPjyyy/RpUsXpKamih0WUaWi1wRn6NChuHLlCo4cOYKff/4ZJ0+exLhx40qsf/fuXdy9exdLlizB5cuXsWXLFkRERGD06NFF6m7evBlpaWnqrW/fvnpsCVHFUqqUiLwdiV2XdiHydiSUKqXYIVEFsrS0xOrVq7Fnzx5YW1sjKioKcrkchw4dEjs0okpDb4ttJiYmonnz5jh37hw8PT0BABEREejRowdSU1Ph7Oys1XH27duHYcOGIScnRz0TqEQiwf79+8uc1HCxTTJk4YnhCI4IRqrin7/YXWQuWBGwAoHNAkWMjMRw8+ZNDBw4EBcuXAAAzJkzB59//rnIURGJwyAW24yOjoatra06uQEAPz8/mJiYICYmRuvjFDaiMLkp9PHHH8POzg5eXl7YtGkTXpWn5ebmQqFQaGxEhig8MRz99/bXSG4A4I7iDvrv7Y/wxHCRIiOxNGrUCGfOnMHEiRMBQKMjMhGVTG8JTnp6OurUqaNRZmpqilq1aiE9PV2rYzx48ADz588vcltr3rx52Lt3L44cOYJ+/frho48+wsqVK0s8zoIFC2BjY6PeXF1dS98gIj1TqpQIjgiGgKLJemHZ5IjJvF1VBZmbm+Obb75BbGwsRowYoS5/uX8iEf2j1AnOzJkzi+3k++J27dq1cgemUCjQs2dPNG/eHJ999pnGa7Nnz8Y777wDDw8PzJgxA9OnT8fixYtLPFZoaCgyMzPVW0pKSrnjI9K1qOSoIlduXiRAQIoiBVHJXKCxqmrTpo363w8ePECLFi0wZcoU5OXliRgVkWEyfX0VTVOnTsXIkSNfWcfd3R2Ojo64d++eRnl+fj4ePXoER0fHV+6flZWFgIAAWFtbY//+/ahWrdor63t7e2P+/PnIzc2Fubl5kdfNzc2LLScyJGlZaTqtR8btp59+QkpKCpYvX47Tp09jz549aNCggdhh6ZRSCURFAWlpgJMT4OsLSKViR0WVRakTHHt7e9jb27+2no+PDx4/foy4uDi0bt0aAHDs2DGoVCp4e3uXuJ9CoYC/vz/Mzc1x8OBBWFhYvPa9EhISULNmTSYxVKk5WTvptB4Zt1GjRsHOzg4jRozAuXPn4OHhgY0bN6Jfv35ih6YT4eFAcDDw4uh4FxdgxQogkH3tSQt664PTrFkzBAQEYOzYsYiNjcXp06cxYcIEDBo0SD2C6s6dO2jatCliY2MBFCQ33bp1Q05ODjZu3AiFQoH09HSkp6dDqSzod/DTTz9hw4YNuHz5Mm7evInVq1fjq6++UnfAI6qsfOv5wkXmAgkkxb4ugQSuMlf41vOt4MjIUPXq1QsJCQlo164dMjMz0b9/f0yYMAHPnj0TO7RyCQ8H+vfXTG4A4M6dgvJw9rUnLeh1HpwdO3agadOm6Nq1K3r06IH27dtj3bp16tefP3+O69ev48mTJwCACxcuICYmBpcuXUKjRo3g5OSk3gr7zVSrVg2rVq2Cj48P5HI51q5di6VLl2Lu3Ln6bAqR3klNpFgRsAIAiiQ5hc+XByyH1ITX6Okf9erVQ2RkJGbMmAEAWLVqVZF+i5WJUllw5aa4gbGFZZMnF9QjehW9zYNjyDgPDhmy4ubBcZW5YnnAcs6DQ6/066+/4rPPPsPhw4dhY2MjdjhlEhkJdO78+nrHjwOdOuk7GjI0pfn+LnUfHCLSr8BmgejTpA+ikqOQlpUGJ2sn+Nbz5ZUbeq3u3bsjICAAEknBFT9BELBhwwYMGzYMlpaWIkennTQt+9BrW4+qLi62SWSApCZSdHLrhMEtBqOTWycmN6S1wuQGANasWYNx48ahbdu2uH79uohRac9Jyz702tajqosJDhGRkXrjjTdQp04dXLx4Ea1bt8b3338vdkiv5etbMFpKUnxfe0gkgKtrQT2iV2GCQ0RkpPz8/JCQkIAuXbogJycHw4cPx/vvv4+cnByxQyuRVFowFBwomuQUPl++nPPh0OsxwSEiMmJOTk44fPgwPv/8c5iYmGDz5s3w8vLClStXxA6tRIGBQFgYULeuZrmLS0E558EhbXAUFUdREVEVERkZiSFDhiAjIwPHjx9Hhw4dxA7plTiTMb2Mo6iIiKiITp06ISEhoUhyIwiCRudkQyGVcig4lR1vURERVSF16tTBwIED1c+vXbuGNm3a4OLFiyJGRaR7THCIiKqwkJAQxMXFwdvbG+vWrUMV7LVARooJDhFRFbZt2zb06NEDz549wwcffIAhQ4ZAoVCIHRZRuTHBISKqwuzs7PDTTz9h0aJFMDU1xe7du9G6dWvEx8eLHRpRuTDBISKq4kxMTDBt2jScPHkS9erVw82bN9G2bVtER0eLHRpRmXEUFRERAQB8fHwQHx+PUaNG4eHDh2jTpo3YIRGVGRMcIiJSq1WrFg4cOICsrCyYmhZ8ReTl5SExMREtW7YUOToi7fEWFRERaZBIJBqTqM2cORNt2rTB8uXLOcqKKg0mOEREVCKlUonU1FQ8f/4cU6ZMQd++ffHo0SOxwyJ6LSY4RERUIqlUij179mDVqlUwMzPDwYMH4eHhwQ7IZPCY4BAR0StJJBJ89NFHOHv2LBo1aoTk5GR06NABixcvhkqlEjs8omIxwSEiIq14eHggLi4OgwYNQn5+PubPn487d+6IHRZRsTiKioiItCaTybBz50506dIFNWvWhKurq9ghERWLCQ4REZWKRCLB2LFjNcp+//13xMbGYubMmTAx4c0BEh8THCIiKpfHjx9j6NChuHfvHk6cOIHt27ejTp06YodFVRzTbCIiKhcbGxssXLgQlpaWOHz4MORyOSIjI8UOi6o4JjhERFQuEokEo0aNwvnz59G8eXOkpaWha9eu+Pzzz6FUKsUOj6ooJjhERKQTzZs3x7lz5/D+++9DpVLhs88+Q7du3fD06VOxQ6MqiAkOERHpjJWVFTZu3Ijt27ejevXqqFu3LiwsLMQOi6ogdjImIiKdGzZsGLy8vODs7AyJRAIAUCgUsLKyUi/iSaRPvIJDRER60bhxY9SoUQMAIAgChg4dii5duiA1NVXkyKgqYIJDRER6d/36dZw4cQJRUVGQy+U4dOiQ2CGRkWOCQ0REete0aVNcuHABrVq1wsOHD9GzZ09Mnz4dz58/Fzs0MlJMcIiIqEI0atQIZ86cwYQJEwAAixcvRseOHZGcnCxyZGSM9JrgPHr0CEOHDoVMJoOtrS1Gjx6N7OzsV+7TqVMnSCQSje3DDz/UqJOcnIyePXvCysoKderUwbRp05Cfn6/PphARkQ6Ym5tj5cqVCAsLg42NDaKjoxEYGAhBEMQOjYyMXruyDx06FGlpaThy5AieP3+OUaNGYdy4cdi5c+cr9xs7dizmzZunfm5lZaX+t1KpRM+ePeHo6IgzZ84gLS0NQUFBqFatGr766iu9tYWIiHSnX79+aNWqFYYPH46lS5eqR1oR6YpE0FPanJiYqJ70ydPTEwAQERGBHj16IDU1Fc7OzsXu16lTJ8jlcixfvrzY13/99Vf861//wt27d+Hg4AAAWLNmDWbMmIH79+/DzMzstbEpFArY2NggMzMTMpmsbA0kIqJyEwRBI7kJDw+Hh4cHGjRoIGJUZKhK8/2tt1tU0dHRsLW1VSc3AODn5wcTExPExMS8ct8dO3bAzs4Ob731FkJDQ/HkyRON47Zo0UKd3ACAv78/FAoFrly5UuzxcnNzoVAoNDYiIhLfi8lNQkIChgwZAg8PD4SHh4sYFRkDvSU46enpRVaTNTU1Ra1atZCenl7ifkOGDMH333+P48ePIzQ0FNu3b8ewYcM0jvticgNA/byk4y5YsAA2NjbqzdXVtazNIiIiPalVqxZatWqFzMxM9OvXDxMnTkRubq7YYVElVeoEZ+bMmUU6Ab+8Xbt2rcwBjRs3Dv7+/mjRogWGDh2Kbdu2Yf/+/bh161aZjxkaGorMzEz1lpKSUuZjERGRftSrVw8nTpzA9OnTAQDffvst2rVrh5s3b4ocGVVGpe5kPHXqVIwcOfKVddzd3eHo6Ih79+5plOfn5+PRo0dwdHTU+v28vb0BADdv3kTDhg3h6OiI2NhYjToZGRkAUOJxzc3NYW5urvV7EhGROKpVq4avv/4aHTt2RFBQkHrunA0bNmDAgAFih0eVSKkTHHt7e9jb27+2no+PDx4/foy4uDi0bt0aAHDs2DGoVCp10qKNhIQEAICTk5P6uF9++SXu3bunvgV25MgRyGQyNG/evJStIaKKolQpEZUchbSsNDhZO8G3ni+kJlKxwyID1aNHD3WfnKioKPz5559ih0SVjN5GUQFA9+7dkZGRgTVr1qiHiXt6eqqHid+5cwddu3bFtm3b4OXlhVu3bmHnzp3o0aMHateujYsXL2LKlClwcXHBiRMnABQME5fL5XB2dsaiRYuQnp6O4cOHY8yYMVoPE+coKqKKFZ4YjuCIYKQq/lmDyEXmghUBKxDYLFDEyMjQ5efnY+vWrRg5ciSk0oKE+OWRV1R1GMQoKqBgNFTTpk3RtWtX9OjRA+3bt8e6devUrz9//hzXr19Xj5IyMzPD77//jm7duqFp06aYOnUq+vXrh59++km9j1Qqxc8//wypVAofHx8MGzYMQUFBGvPmEJHhCE8MR/+9/TWSGwC4o7iD/nv7IzyRo2WoZKamphg9erQ6uXn69Cnat2+P77//XuTIyNDp9QqOoeIVHKKKoVQp4bbCrUhyU0gCCVxkLkgKTuLtKtLKsmXLEBISAgB4//33sXLlSo3JYMm4GcwVHCKq2qKSo0pMbgBAgIAURQqikqMqMCqqzCZNmoTPPvsMEokEmzZtQps2bXD16lWxwyIDxASHiPQmLStNp/WIpFIp5s6di6NHj8LR0RFXr16Fp6cntmzZInZoZGCY4BCR3jhZO+m0HlGhzp07IyEhAe+++y6ePn2KUaNG4euvvxY7LDIgTHCISG986/nCReYCCYof8SKBBK4yV/jW863gyMgYODg4ICIiAl9++SXq1KmDIUOGiB0SGRAmOESkN1ITKVYErACAIklO4fPlAcvZwZjKzMTEBLNmzcKNGzc0luE5e/YsquAYGnoBExwi0qvAZoEIGxCGurK6GuUuMheEDQjjPDikEy+OqPnpp5/g4+ODIUOGcHHlKqzUMxkTEZVWYLNA9GnShzMZU4VISUmBVCrF7t27cf78eezduxceHh5ih0UVjPPgcB4cIqJKrbhlQGJjYjFo0CAkJyfDzMwMS5cuxUcffcQZkCs5zoNDRERVQnhiONxWuKHz1s4YEj4Enbd2htsKN6TZpiE+Ph69e/dGXl4eJkyYgPfeew+PHz8WO2SqIExwiMjgKFVKRN6OxK5LuxB5OxJKlVLskMgAvW4ZkMiMSBw4cADLli1DtWrV8MMPP+D48eMiRUsVjbeoeIuKyKBwYU7SRmmXATl37hwOHTqEuXPnVnCkpEu8RUVElRIX5iRtlXYZkDZt2mgkN+np6Xj//ffx6NEjvcdK4mCCQ0QGQalSIjgiGAKKXlQuLJscMZm3qwhA+ZcBGT16NDZv3gwPDw9ER0frMjQyEExwiMggcGFOKo3yLgMyf/58NGzYEMnJyejQoQMWL14MlUqlyxBJZExwiMggcGFOKo3yLgPSqlUrXLhwAQMHDkR+fj6mT5+OXr164cGDB/oMmyoQExwiMghcmJNKQxfLgMhkMuzatQtr166Fubk5Dh06BLlcjitXrugvcKowTHCIyCBwYU4qLV0sAyKRSDBu3DjExsaiSZMmqF69OurXr6+vkKkCcZg4h4kTGYzCUVQANDobFyY9XLuKilPcTMZlWQYkOzsbGRkZaNiwIQBAEAT8/fffqFWrlq5DpjLiMHEiqpS4MCeVhdREik5unTC4xWB0cutU5jXOatSooU5uAGD58uV48803OTlgJcUrOLyCQ2RwdPUXOVFZ5efno02bNkhISICJiQnmzJmDTz/9FFIpfw/FVJrvbyY4THCIiKgYOTk5mDhxIjZv3gwA6NKlC77//ns4ObGju1h4i4qIiKicqlevjk2bNmHbtm2oXr06jh07BrlcjiNHjogdGmmBCQ4REdErDB8+HOfPn0eLFi1w79499OrVC3fv3hU7LHoNU7EDICIiMnRNmzZFTEwMJk+ejCZNmsDZ2VnskOg1mOAQERFpwdLSEmvXrsWLXVcvXryIO3fuoHv37iJGRsXhLSoiIqJSkEgK5mXKzs7GgAED0KNHD8yYMQPPnz8XOTJ6ERMcIiKiMjA1NYWfnx8AYNGiRejUqROSk5NFjooKMcEhIiIqAwsLC3z77bfYt28fZDIZzpw5A7lcjp9++kns0AhMcIiIiMqlf//+iI+Ph6enJ/7++2/07t0bU6dO5S0rkTHBISIiKid3d3ecPn0akydPBgD88ccfMDHhV6yYOIqKiIhIB8zMzLBs2TJ06dIFbdq0US/roFKpmOyIQK8/8UePHmHo0KGQyWSwtbXF6NGjkZ2dXWL927dvQyKRFLvt27dPXa+413fv3q3PphAREWmlV69ecHR0VD+fMGECJk6ciNzcXBGjqnr0uhZV9+7dkZaWhrVr1+L58+cYNWoU2rRpg507dxZbX6lU4v79+xpl69atw+LFi5GWloYaNWoUBC2RYPPmzQgICFDXs7W1hYWFhVZxcS0qIiKqCBcvXkTLli0BAK1atcKePXvQqFEjkaOqvAxiLarExERERERgw4YN8Pb2Rvv27bFy5Urs3r27xCmupVIpHB0dNbb9+/djwIAB6uSmkK2trUY9bZMbIiKiivL222/j559/Ru3atXHhwgW0atUKe/fuFTusKkFvCU50dDRsbW3h6empLvPz84OJiQliYmK0OkZcXBwSEhIwevToIq99/PHHsLOzg5eXFzZt2oRXXYjKzc2FQqHQ2IiIiCpCz549kZCQgPbt2yMrKwsDBw7Ehx9+iKdPn4odmlHTW4KTnp6OOnXqaJSZmpqiVq1aSE9P1+oYGzduRLNmzdCuXTuN8nnz5mHv3r04cuQI+vXrh48++ggrV64s8TgLFiyAjY2NenN1dS19g4iIiMrIxcUFx48fx6xZsyCRSLB27Vr07NnzlX+cU/mUOsGZOXNmiR2BC7dr166VO7CnT59i586dxV69mT17Nt555x14eHhgxowZmD59OhYvXlzisUJDQ5GZmaneUlJSyh0fERFRaZiamuLLL79EREQE6tSpg8mTJ6uXfSDdK/Uw8alTp2LkyJGvrOPu7g5HR0fcu3dPozw/Px+PHj3S6F1ekrCwMDx58gRBQUGvrevt7Y358+cjNzcX5ubmRV43NzcvtpyIiKiidevWDbdu3dLoW3rhwgU0bdoUVlZWIkZmXEqd4Njb28Pe3v619Xx8fPD48WPExcWhdevWAIBjx45BpVLB29v7tftv3LgRvXv31uq9EhISULNmTSYxRERUKbyY3KSkpODdd9+Fk5MT9u7di+bNm4sYmfHQWx+cZs2aISAgAGPHjkVsbCxOnz6NCRMmYNCgQXB2dgYA3LlzB02bNkVsbKzGvjdv3sTJkycxZsyYIsf96aefsGHDBly+fBk3b97E6tWr8dVXX2HixIn6agoREZHe3L17F2ZmZrhy5QratGmDLVu2iB2SUdDrRH87duxA06ZN0bVrV/To0QPt27fHunXr1K8/f/4c169fx5MnTzT227RpE1xcXNCtW7cix6xWrRpWrVoFHx8fyOVyrF27FkuXLsXcuXP12RQiIiK98Pb2RkJCAvz8/PDkyROMGjUKI0aMeOXEuPR6ep3oz1Bxoj8iIjI0KpUKCxYswJw5c6BSqdC0aVPs2bMHb7/9ttihGQyDmOiPiIiItGdiYoL//Oc/OH78OJydnXHt2jWsXbtW7LAqLSY4REREBqRDhw5ISEjAxIkTsWTJErHDqbSY4BARERkYe3t7fPPNN7C0tARQsFbjBx98gPj4eJEjqzyY4BARERm4b775BuvWrUPbtm3x3XffcQZkLTDBISIiMnBBQUHo1asX8vLy8PHHH2PAgAHIzMwUOyyDxgSHiIjIwNWuXRs//vgjli5dClNTU4SFhcHDwwPnz58XOzSDxQSHiIioEpBIJJgyZQpOnz4NNzc3JCUloV27dti+fbvYoRkkJjhERESViJeXF+Lj4xEYGAgTExO0aNFC7JAMEhMcIiKiSsbW1hZhYWE4f/485HK5uvzBgwfiBWVgmOAQEZWCUqVE5O1I7Lq0C5G3I6FUKcUOiaooiUSCt956S/08NjYW9evXx3//+1+oVCoRIzMMpV5NnIioqgpPDEdwRDBSFanqMheZC1YErEBgs0ARIyMC9uzZgydPnuCTTz7B8ePHsXXrVtSuXVvssETDKzhERFoITwxH/739NZIbALijuIP+e/sjPDFcpMiICixZsgRr1qyBubk5fvnlF8jlcpw6dUrssETDBIeI6DWUKiWCI4IhoOjkaoVlkyMm83YViUoikeCDDz5ATEwMGjdujNTUVHTq1AkLFiyokresmOAQEb1GVHJUkSs3LxIgIEWRgqjkqAqMiqh4LVu2xPnz5zF06FAolUrMmjUL+/btEzusCsc+OEREr5GWlabTekT6Zm1tje3bt6NLly6IiIjAe++9J3ZIFY5XcIiIXsPJ2kmn9YgqgkQiwfvvv489e/bAxKTg6z47OxsrV66EUmn8t1OZ4BCRQTHEYdi+9XzhInOBBJJiX5dAAleZK3zr+VZwZESvJ5H883v78ccfY9KkSejWrRvS09NFjEr/mOAQkcEITwyH2wo3dN7aGUPCh6Dz1s5wW+Em+gglqYkUKwJWAECRJKfw+fKA5ZCaSCs8NqLS6Nq1K6ysrHDs2DHI5XL8/vvvYoekN0xwiMggGPow7MBmgQgbEIa6sroa5S4yF4QNCOM8OFQpBAUFIS4uDm+99RYyMjLQrVs3zJ49G/n5+WKHpnMSQRCKjns0cgqFAjY2NsjMzIRMJhM7HKIqT6lSwm2FW4kjlSSQwEXmgqTgJNGvkihVSkQlRyEtKw1O1k7wrecrekxEpfX06VMEBwdj/fr1AIAOHTpg9+7dcHIy7H5kpfn+5igqIhJdaYZhd3LrVHGBFUNqIhU9BqLysrS0xLp169C5c2eMGzcO165dEzsknWOCQ0Si4zBsInEMHjwYnp6eyMjI0Lh6o1Kp1COvKqvKHT0RGQUOwyYSzxtvvIH27durn4eFhaFDhw5ISUkRMaryY4JDRKLjMGwiw5CXl4epU6fi9OnTkMvl+Omnn8QOqcyY4BCR6DgMm8gwmJmZ4fjx4/D09MSjR4/Qu3dvTJ06FXl5eWKHVmpMcIjIIHAYNpFhcHd3x6lTpxAcHAwAWLp0KXx9fXH79m1xAyslDhPnMHEig8Jh2ESG48CBAxg1ahQeP34MW1tbXL9+HXXq1BEtHg4TJ6JKi8OwiQxH37594eHhgYEDB8LHx0fU5Ka0mOAQERFRierXr4+oqCi8eMMnNTUVubm5aNiwoYiRvRr74BAREdErVatWDWZmZgCA/Px8DB48GK1atcK+fftEjqxkTHCIiIhIa5mZmRAEAQqFAgMGDMBHH32EZ8+eiR1WEXpLcL788ku0a9cOVlZWsLW11WofQRAwZ84cODk5wdLSEn5+frhx44ZGnUePHmHo0KGQyWSwtbXF6NGjkZ2drYcWEBER0ctq166NyMhIhIaGAgBWr16Ntm3b4s8//xQ5Mk16S3Dy8vLw3nvvYfz48Vrvs2jRInzzzTdYs2YNYmJiUL16dfj7+2tkhkOHDsWVK1dw5MgR/Pzzzzh58iTGjRunjyYQERFRMUxNTfHVV18hIiIC9vb2+OOPP9CqVSvs2LFD7NDU9D5MfMuWLZg8eTIeP378ynqCIMDZ2RlTp07FJ598AqDgMpiDgwO2bNmCQYMGITExEc2bN8e5c+fg6ekJAIiIiECPHj2QmpoKZ2dnrWLiMHEiIiLduHv3LoYOHYrIyEi89dZbiIuLU/fX0bXSfH8bTB+cpKQkpKenw8/PT11mY2MDb29vREdHAwCio6Nha2urTm4AwM/PDyYmJoiJiSnx2Lm5uVAoFBobERERlZ+zszN+//13fP7559i7d6/ekpvSMpgEJz09HQDg4OCgUe7g4KB+LT09vcgYfFNTU9SqVUtdpzgLFiyAjY2NenN1ddVx9ERERFWXVCrFnDlz0KxZM7FDUStVgjNz5kxIJJJXbteuXdNXrGUWGhqKzMxM9VbZV0glIiKiVyvVRH9Tp07FyJEjX1nH3d29TIE4OjoCADIyMuDk5KQuz8jIgFwuV9e5d++exn75+fl49OiRev/imJubw9zcvExxERERUeVTqgTH3t4e9vb2egmkQYMGcHR0xNGjR9UJjUKhQExMjHoklo+PDx4/foy4uDi0bt0aAHDs2DGoVCp4e3vrJS4iIiKqfPTWByc5ORkJCQlITk6GUqlEQkICEhISNOasadq0Kfbv3w8AkEgkmDx5Mr744gscPHgQly5dQlBQEJydndG3b18AQLNmzRAQEICxY8ciNjYWp0+fxoQJEzBo0CCtR1ARERGR8dPbWlRz5szB1q1b1c89PDwAAMePH0enTp0AANevX0dmZqa6zvTp05GTk4Nx48bh8ePHaN++PSIiImBhYaGus2PHDkyYMAFdu3aFiYkJ+vXrh2+++UZfzSAiIqJKSO/z4BgizoNDRERU+VTKeXCIiIiIdIUJDhERERkdJjhERERkdJjgEBERkdFhgkNERERGhwkOERERGR0mOERERGR0mOAQERGR0WGCQ0REREZHb0s1GLLCyZsVCoXIkRAREZG2Cr+3tVmEoUomOFlZWQAAV1dXkSMhIiKi0srKyoKNjc0r61TJtahUKhXu3r0La2trSCQSnR5boVDA1dUVKSkpRrnOFdtX+Rl7G9m+ys/Y22js7QP010ZBEJCVlQVnZ2eYmLy6l02VvIJjYmICFxcXvb6HTCYz2l9cgO0zBsbeRrav8jP2Nhp7+wD9tPF1V24KsZMxERERGR0mOERERGR0mODomLm5OebOnQtzc3OxQ9ELtq/yM/Y2sn2Vn7G30djbBxhGG6tkJ2MiIiIybryCQ0REREaHCQ4REREZHSY4REREZHSY4BAREZHRYYJTSl9++SXatWsHKysr2NraarWPIAiYM2cOnJycYGlpCT8/P9y4cUOjzqNHjzB06FDIZDLY2tpi9OjRyM7O1kMLXq20cdy+fRsSiaTYbd++fep6xb2+e/fuimhSEWX5WXfq1KlI/B9++KFGneTkZPTs2RNWVlaoU6cOpk2bhvz8fH02pVilbd+jR48wceJENGnSBJaWlqhXrx4mTZqEzMxMjXpinsNVq1bBzc0NFhYW8Pb2Rmxs7Cvr79u3D02bNoWFhQVatGiBQ4cOabyuzWeyIpWmfevXr4evry9q1qyJmjVrws/Pr0j9kSNHFjlXAQEB+m5GiUrTvi1bthSJ3cLCQqOOoZ0/oHRtLO7/E4lEgp49e6rrGNI5PHnyJHr16gVnZ2dIJBIcOHDgtftERkaiVatWMDc3R6NGjbBly5YidUr7uS41gUplzpw5wtKlS4WQkBDBxsZGq30WLlwo2NjYCAcOHBD++OMPoXfv3kKDBg2Ep0+fqusEBAQILVu2FM6ePStERUUJjRo1EgYPHqynVpSstHHk5+cLaWlpGtvnn38u1KhRQ8jKylLXAyBs3rxZo96L7a9IZflZd+zYURg7dqxG/JmZmerX8/Pzhbfeekvw8/MT4uPjhUOHDgl2dnZCaGiovptTRGnbd+nSJSEwMFA4ePCgcPPmTeHo0aPCG2+8IfTr10+jnljncPfu3YKZmZmwadMm4cqVK8LYsWMFW1tbISMjo9j6p0+fFqRSqbBo0SLh6tWrwqeffipUq1ZNuHTpkrqONp/JilLa9g0ZMkRYtWqVEB8fLyQmJgojR44UbGxshNTUVHWdESNGCAEBARrn6tGjRxXVJA2lbd/mzZsFmUymEXt6erpGHUM6f4JQ+jY+fPhQo32XL18WpFKpsHnzZnUdQzqHhw4dEv7zn/8I4eHhAgBh//79r6z/v//9T7CyshJCQkKEq1evCitXrhSkUqkQERGhrlPan1lZMMEpo82bN2uV4KhUKsHR0VFYvHixuuzx48eCubm5sGvXLkEQBOHq1asCAOHcuXPqOr/++qsgkUiEO3fu6Dz2kugqDrlcLrz//vsaZdp8KCpCWdvYsWNHITg4uMTXDx06JJiYmGj8R7x69WpBJpMJubm5OoldG7o6h3v37hXMzMyE58+fq8vEOodeXl7Cxx9/rH6uVCoFZ2dnYcGCBcXWHzBggNCzZ0+NMm9vb+GDDz4QBEG7z2RFKm37Xpafny9YW1sLW7duVZeNGDFC6NOnj65DLZPStu91/7ca2vkThPKfw2XLlgnW1tZCdna2usyQzuGLtPl/YPr06cKbb76pUTZw4EDB399f/by8PzNt8BaVniUlJSE9PR1+fn7qMhsbG3h7eyM6OhoAEB0dDVtbW3h6eqrr+Pn5wcTEBDExMRUWqy7iiIuLQ0JCAkaPHl3ktY8//hh2dnbw8vLCpk2btFruXtfK08YdO3bAzs4Ob731FkJDQ/HkyRON47Zo0QIODg7qMn9/fygUCly5ckX3DSmBrn6XMjMzIZPJYGqquVxdRZ/DvLw8xMXFaXx+TExM4Ofnp/78vCw6OlqjPlBwLgrra/OZrChlad/Lnjx5gufPn6NWrVoa5ZGRkahTpw6aNGmC8ePH4+HDhzqNXRtlbV92djbq168PV1dX9OnTR+MzZEjnD9DNOdy4cSMGDRqE6tWra5Qbwjksi9d9BnXxM9NGlVxssyKlp6cDgMYXX+HzwtfS09NRp04djddNTU1Rq1YtdZ2KoIs4Nm7ciGbNmqFdu3Ya5fPmzUOXLl1gZWWFw4cP46OPPkJ2djYmTZqks/i1UdY2DhkyBPXr14ezszMuXryIGTNm4Pr16wgPD1cft7hzXPhaRdHFOXzw4AHmz5+PcePGaZSLcQ4fPHgApVJZ7M/22rVrxe5T0rl48fNWWFZSnYpSlva9bMaMGXB2dtb4sggICEBgYCAaNGiAW7duYdasWejevTuio6MhlUp12oZXKUv7mjRpgk2bNuHtt99GZmYmlixZgnbt2uHKlStwcXExqPMHlP8cxsbG4vLly9i4caNGuaGcw7Io6TOoUCjw9OlT/P333+X+vdcGExwAM2fOxNdff/3KOomJiWjatGkFRaRb2ravvJ4+fYqdO3di9uzZRV57sczDwwM5OTlYvHixzr4c9d3GF7/sW7RoAScnJ3Tt2hW3bt1Cw4YNy3xcbVXUOVQoFOjZsyeaN2+Ozz77TOM1fZ9DKr2FCxdi9+7diIyM1OiIO2jQIPW/W7RogbfffhsNGzZEZGQkunbtKkaoWvPx8YGPj4/6ebt27dCsWTOsXbsW8+fPFzEy/di4cSNatGgBLy8vjfLKfA4NBRMcAFOnTsXIkSNfWcfd3b1Mx3Z0dAQAZGRkwMnJSV2ekZEBuVyurnPv3j2N/fLz8/Ho0SP1/uWhbfvKG0dYWBiePHmCoKCg19b19vbG/PnzkZubq5O1SiqqjYW8vb0BADdv3kTDhg3h6OhYZARARkYGAFSac5iVlYWAgABYW1tj//79qFat2ivr6/ocFsfOzg5SqVT9syyUkZFRYnscHR1fWV+bz2RFKUv7Ci1ZsgQLFy7E77//jrfffvuVdd3d3WFnZ4ebN29W6JdjedpXqFq1avDw8MDNmzcBGNb5A8rXxpycHOzevRvz5s177fuIdQ7LoqTPoEwmg6WlJaRSabl/L7Sis948VUxpOxkvWbJEXZaZmVlsJ+Pz58+r6/z222+idTIuaxwdO3YsMvKmJF988YVQs2bNMsdaVrr6WZ86dUoAIPzxxx+CIPzTyfjFEQBr164VZDKZ8OzZM9014DXK2r7MzEyhbdu2QseOHYWcnByt3quizqGXl5cwYcIE9XOlUinUrVv3lZ2M//Wvf2mU+fj4FOlk/KrPZEUqbfsEQRC+/vprQSaTCdHR0Vq9R0pKiiCRSIQff/yx3PGWVlna96L8/HyhSZMmwpQpUwRBMLzzJwhlb+PmzZsFc3Nz4cGDB699DzHP4YugZSfjt956S6Ns8ODBRToZl+f3QqtYdXakKuKvv/4S4uPj1UOh4+Pjhfj4eI0h0U2aNBHCw8PVzxcuXCjY2toKP/74o3Dx4kWhT58+xQ4T9/DwEGJiYoRTp04Jb7zxhmjDxF8VR2pqqtCkSRMhJiZGY78bN24IEolE+PXXX4sc8+DBg8L69euFS5cuCTdu3BC+++47wcrKSpgzZ47e21Oc0rbx5s2bwrx584Tz588LSUlJwo8//ii4u7sLHTp0UO9TOEy8W7duQkJCghARESHY29uLNky8NO3LzMwUvL29hRYtWgg3b97UGJaan58vCIK453D37t2Cubm5sGXLFuHq1avCuHHjBFtbW/WIteHDhwszZ85U1z99+rRgamoqLFmyREhMTBTmzp1b7DDx130mK0pp27dw4ULBzMxMCAsL0zhXhf8HZWVlCZ988okQHR0tJCUlCb///rvQqlUr4Y033qjQZLus7fv888+F3377Tbh165YQFxcnDBo0SLCwsBCuXLmirmNI508QSt/GQu3btxcGDhxYpNzQzmFWVpb6uw6AsHTpUiE+Pl7466+/BEEQhJkzZwrDhw9X1y8cJj5t2jQhMTFRWLVqVbHDxF/1M9MFJjilNGLECAFAke348ePqOvj/+UIKqVQqYfbs2YKDg4Ngbm4udO3aVbh+/brGcR8+fCgMHjxYqFGjhiCTyYRRo0ZpJE0V5XVxJCUlFWmvIAhCaGio4OrqKiiVyiLH/PXXXwW5XC7UqFFDqF69utCyZUthzZo1xdatCKVtY3JystChQwehVq1agrm5udCoUSNh2rRpGvPgCIIg3L59W+jevbtgaWkp2NnZCVOnTtUYZl1RStu+48ePF/s7DUBISkoSBEH8c7hy5UqhXr16gpmZmeDl5SWcPXtW/VrHjh2FESNGaNTfu3ev0LhxY8HMzEx48803hV9++UXjdW0+kxWpNO2rX79+sedq7ty5giAIwpMnT4Ru3boJ9vb2QrVq1YT69esLY8eO1ekXR2mVpn2TJ09W13VwcBB69OghXLhwQeN4hnb+BKH0v6PXrl0TAAiHDx8ucixDO4cl/R9R2KYRI0YIHTt2LLKPXC4XzMzMBHd3d43vxEKv+pnpgkQQRBirS0RERKRHnAeHiIiIjA4THCIiIjI6THCIiIjI6DDBISIiIqPDBIeIiIiMDhMcIiIiMjpMcIiIiMjoMMEhIiIio8MEh4iIiIwOExwiIiIyOkxwiIiIyOgwwSEiIiKj839iSB6y5xPYbgAAAABJRU5ErkJggg==\n"
},
"metadata": {}
}
],
"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": {
"id": "hazardous-rehabilitation"
},
"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": 34,
"id": "fewer-desperate",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 171
},
"id": "fewer-desperate",
"outputId": "4e382ab0-19d6-4e26-85f9-6c5aca07e2d5"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" ┌──────────────────────────┐»\n",
"q_0: ┤0 ├»\n",
" │ ZZFeatureMap(x[0],x[1]) │»\n",
"q_1: ┤1 ├»\n",
" └──────────────────────────┘»\n",
"« ┌──────────────────────────────────────────────────────────┐\n",
"«q_0: ┤0 ├\n",
"« │ RealAmplitudes(θ[0],θ[1],θ[2],θ[3],θ[4],θ[5],θ[6],θ[7]) │\n",
"«q_1: ┤1 ├\n",
"« └──────────────────────────────────────────────────────────┘"
],
"text/html": [
"<pre style=\"word-wrap: normal;white-space: pre;background: #fff0;line-height: 1.1;font-family: "Courier New",Courier,monospace\"> ┌──────────────────────────┐»\n",
"q_0: ┤0 ├»\n",
" │ ZZFeatureMap(x[0],x[1]) │»\n",
"q_1: ┤1 ├»\n",
" └──────────────────────────┘»\n",
"« ┌──────────────────────────────────────────────────────────┐\n",
"«q_0: ┤0 ├\n",
"« │ RealAmplitudes(θ[0],θ[1],θ[2],θ[3],θ[4],θ[5],θ[6],θ[7]) │\n",
"«q_1: ┤1 ├\n",
"« └──────────────────────────────────────────────────────────┘</pre>"
]
},
"metadata": {},
"execution_count": 34
}
],
"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()"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "humanitarian-flavor",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "humanitarian-flavor",
"outputId": "3c17bc1d-533a-42c1-fc85-f27352daf3c5"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Initial weights: [-0.01256962 0.06653564 0.04005302 -0.03752667 0.06645196 0.06095287\n",
" -0.02250432 -0.04233438]\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-35-1a9034c67aa2>:9: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn1.num_weights) - 1)\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": 36,
"id": "likely-grace",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "likely-grace",
"outputId": "7642e8b9-545b-414c-9d18-50d7b780806a"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor([-0.3285], grad_fn=<_TorchNNFunctionBackward>)"
]
},
"metadata": {},
"execution_count": 36
}
],
"source": [
"# Test with a single input\n",
"model1(X_[0, :])"
]
},
{
"cell_type": "markdown",
"id": "gorgeous-segment",
"metadata": {
"id": "gorgeous-segment"
},
"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": 37,
"id": "following-extension",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "following-extension",
"outputId": "681535bf-5b9a-49be-9689-efa44748d217"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"25.535646438598633\n",
"22.696760177612305\n",
"20.039228439331055\n",
"19.68790626525879\n",
"19.267210006713867\n",
"19.025375366210938\n",
"18.154708862304688\n",
"17.33785629272461\n",
"19.082605361938477\n",
"17.073301315307617\n",
"16.21840476989746\n",
"14.992582321166992\n",
"14.929340362548828\n",
"14.914533615112305\n",
"14.907636642456055\n",
"14.902364730834961\n",
"14.902135848999023\n",
"14.90211009979248\n",
"14.902111053466797\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor(25.5356, grad_fn=<MseLossBackward0>)"
]
},
"metadata": {},
"execution_count": 37
}
],
"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": 38,
"id": "efficient-bangkok",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 448
},
"id": "efficient-bangkok",
"outputId": "5524b672-5c20-4428-f028-570e2dad2e91"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy: 0.8\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "abstract-parish"
},
"source": [
"The red circles indicate wrongly classified data points."
]
},
{
"cell_type": "markdown",
"id": "typical-cross",
"metadata": {
"id": "typical-cross"
},
"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": 39,
"id": "present-operator",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "present-operator",
"outputId": "aea19e82-f81f-4dd4-877c-716f17b9eb10"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Initial weights: [ 0.0364991 -0.0720495 -0.06001836 -0.09852755]\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-39-2506a60ae15a>:25: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn2.num_weights) - 1)\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": {
"id": "liquid-reviewer"
},
"source": [
"For a reminder on optimizer and loss function choices, you can go back to [this section](#Optimizer)."
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "marked-harvest",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "marked-harvest",
"outputId": "4a4e16b4-137b-4c3d-e991-36e00210de4f"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"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": 41,
"id": "falling-electronics",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 448
},
"id": "falling-electronics",
"outputId": "28a5a07c-8ee3-4509-9e2f-df02df4fa9ac"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy: 0.45\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "aboriginal-white"
},
"source": [
"The red circles indicate wrongly classified data points."
]
},
{
"cell_type": "markdown",
"id": "scheduled-nicaragua",
"metadata": {
"id": "scheduled-nicaragua"
},
"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": 42,
"id": "amateur-dubai",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 523
},
"id": "amateur-dubai",
"outputId": "bf407976-f862-49e6-f71c-39ce9cf78fe4"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-42-78479be938b8>:8: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" X = (ub - lb) * algorithm_globals.random.random([num_samples, 1]) + lb\n",
"<ipython-input-42-78479be938b8>:9: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" y = f(X) + eps * (2 * algorithm_globals.random.random([num_samples, 1]) - 1)\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "protected-genre"
},
"source": [
"#### A. Regression with PyTorch and `EstimatorQNN`"
]
},
{
"cell_type": "markdown",
"id": "lovely-semiconductor",
"metadata": {
"id": "lovely-semiconductor"
},
"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": 43,
"id": "brazilian-adapter",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "brazilian-adapter",
"outputId": "6b532444-0065-416a-99c9-ff9c6cd63937"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"<ipython-input-43-bbd64a0fc417>:21: DeprecationWarning: The property ``qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals.random`` is deprecated as of qiskit 0.45.0. It will be removed no earlier than 3 months after the release date. This algorithm utility has been migrated to an independent package: https://github.com/qiskit-community/qiskit-algorithms. You can run ``pip install qiskit_algorithms`` and import ``from qiskit_algorithms.utils`` instead. \n",
" initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn3.num_weights) - 1)\n"
]
}
],
"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": {
"id": "waiting-competition"
},
"source": [
"For a reminder on optimizer and loss function choices, you can go back to [this section](#Optimizer)."
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "bibliographic-consciousness",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "bibliographic-consciousness",
"outputId": "eae94aa5-adbd-4855-bfc7-e7ea481ab691"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"14.947757720947266\n",
"2.948650360107422\n",
"8.952412605285645\n",
"0.37905153632164\n",
"0.24995625019073486\n",
"0.2483610212802887\n",
"0.24835753440856934\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"tensor(14.9478, grad_fn=<MseLossBackward0>)"
]
},
"metadata": {},
"execution_count": 44
}
],
"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": 45,
"id": "timely-happiness",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 430
},
"id": "timely-happiness",
"outputId": "5d93e466-d47a-428f-c441-3e5a310e7696"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "individual-georgia"
},
"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": 46,
"id": "otherwise-military",
"metadata": {
"id": "otherwise-military"
},
"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": {
"id": "bronze-encounter"
},
"source": [
"### Step 1: Defining Data-loaders for train and test"
]
},
{
"cell_type": "markdown",
"id": "parliamentary-middle",
"metadata": {
"id": "parliamentary-middle"
},
"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": 47,
"id": "worthy-charlotte",
"metadata": {
"id": "worthy-charlotte"
},
"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": {
"id": "completed-spring"
},
"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": 48,
"id": "medieval-bibliography",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 170
},
"id": "medieval-bibliography",
"outputId": "c7902afd-c2d8-43e5-ea61-135788a89412"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1000x300 with 6 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": 49,
"id": "structural-chuck",
"metadata": {
"id": "structural-chuck"
},
"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": {
"id": "abroad-morris"
},
"source": [
"### Step 2: Defining the QNN and Hybrid Model"
]
},
{
"cell_type": "markdown",
"id": "super-tokyo",
"metadata": {
"id": "super-tokyo"
},
"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": 50,
"id": "urban-purse",
"metadata": {
"id": "urban-purse"
},
"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": 51,
"id": "exclusive-productivity",
"metadata": {
"id": "exclusive-productivity"
},
"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": {
"id": "academic-specific"
},
"source": [
"### Step 3: Training"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "precious-career",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "precious-career",
"outputId": "478486ed-bea4-4680-8276-901363300ee3"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Training [10%]\tLoss: -1.2637\n",
"Training [20%]\tLoss: -1.9163\n",
"Training [30%]\tLoss: -2.4675\n",
"Training [40%]\tLoss: -3.1040\n",
"Training [50%]\tLoss: -3.7613\n",
"Training [60%]\tLoss: -4.4366\n",
"Training [70%]\tLoss: -5.1119\n",
"Training [80%]\tLoss: -5.4390\n",
"Training [90%]\tLoss: -6.1217\n",
"Training [100%]\tLoss: -6.7849\n"
]
}
],
"source": [
"# Define model, optimizer, and loss function\n",
"optimizer = optim.Adam(model4.parameters(), lr=0.003, weight_decay=0.01)\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": 53,
"id": "spoken-stationery",
"metadata": {
"scrolled": true,
"colab": {
"base_uri": "https://localhost:8080/",
"height": 472
},
"id": "spoken-stationery",
"outputId": "6de920df-3230-4a25-f3c6-c53a1082def2"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "physical-closure"
},
"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": 54,
"id": "regulation-bread",
"metadata": {
"id": "regulation-bread"
},
"outputs": [],
"source": [
"torch.save(model4.state_dict(), \"model4.pt\")"
]
},
{
"cell_type": "markdown",
"id": "pacific-flour",
"metadata": {
"id": "pacific-flour"
},
"source": [
"### Step 4: Evaluation"
]
},
{
"cell_type": "markdown",
"id": "fabulous-tribe",
"metadata": {
"id": "fabulous-tribe"
},
"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": 55,
"id": "prospective-flooring",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "prospective-flooring",
"outputId": "d695fc88-fa9f-458b-d28b-86e741d58654"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<All keys matched successfully>"
]
},
"metadata": {},
"execution_count": 55
}
],
"source": [
"qnn5 = create_qnn()\n",
"model5 = Net(qnn5)\n",
"model5.load_state_dict(torch.load(\"model4.pt\"))"
]
},
{
"cell_type": "code",
"execution_count": 56,
"id": "spectacular-conservative",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "spectacular-conservative",
"outputId": "f16e5366-d578-4000-ac69-c4fa307d69b3"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Performance on test data:\n",
"\tLoss: -6.9134\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": 57,
"id": "color-brave",
"metadata": {
"tags": [
"nbsphinx-thumbnail"
],
"colab": {
"base_uri": "https://localhost:8080/",
"height": 170
},
"id": "color-brave",
"outputId": "3dda1bd4-659c-423c-9d14-231749297601"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1000x300 with 6 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"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": {
"id": "prompt-visibility"
},
"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": 58,
"id": "related-wheat",
"metadata": {
"tags": [],
"colab": {
"base_uri": "https://localhost:8080/",
"height": 536
},
"id": "related-wheat",
"outputId": "11dd1644-539c-42c5-a83c-5f6591eca934"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.HTML object>"
],
"text/html": [
"<h3>Version Information</h3><table><tr><th>Software</th><th>Version</th></tr><tr><td><code>qiskit</code></td><td>0.45.1</td></tr><tr><td><code>qiskit_algorithms</code></td><td>0.2.1</td></tr><tr><td><code>qiskit_machine_learning</code></td><td>0.7.1</td></tr><tr><th colspan='2'>System information</th></tr><tr><td>Python version</td><td>3.10.12</td></tr><tr><td>Python compiler</td><td>GCC 11.4.0</td></tr><tr><td>Python build</td><td>main, Nov 20 2023 15:14:05</td></tr><tr><td>OS</td><td>Linux</td></tr><tr><td>CPUs</td><td>6</td></tr><tr><td>Memory (Gb)</td><td>83.48070526123047</td></tr><tr><td colspan='2'>Sun Dec 03 17:29:55 2023 UTC</td></tr></table>"
]
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.HTML object>"
],
"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>"
]
},
"metadata": {}
}
],
"source": [
"import qiskit.tools.jupyter\n",
"\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
]
},
{
"cell_type": "code",
"source": [
"seconds = time.time()\n",
"print(\"Time in seconds since end of run:\", seconds)\n",
"local_time = time.ctime(seconds)\n",
"print(local_time)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "40cv8lXho6XN",
"outputId": "77517b1a-96d2-4810-bda2-c06893d1a875"
},
"id": "40cv8lXho6XN",
"execution_count": 59,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Time in seconds since end of run: 1701624595.475633\n",
"Sun Dec 3 17:29:55 2023\n"
]
}
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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
},
"colab": {
"provenance": [],
"machine_shape": "hm",
"gpuType": "A100"
},
"accelerator": "GPU"
},
"nbformat": 4,
"nbformat_minor": 5
}