{ "cells": [ { "cell_type": "markdown", "id": "secondary-copying", "metadata": {}, "source": [ "# Torch Connector and Hybrid QNNs\n", "\n", "This tutorial introduces the `TorchConnector` class, and demonstrates how it allows for a natural integration of any `NeuralNetwork` from Qiskit Machine Learning into a PyTorch workflow. `TorchConnector` takes a `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 `EstimatorQNN`\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": 1, "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.circuit import Parameter\n", "from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap\n", "from qiskit_algorithms.utils import algorithm_globals\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": 2, "id": "secure-tragedy", "metadata": {}, "outputs": [ { "data": { "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==", "text/plain": [ "
" ] }, "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": 3, "id": "fewer-desperate", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "execution_count": 3, "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(output=\"mpl\", style=\"clifford\")" ] }, { "cell_type": "code", "execution_count": 4, "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": 5, "id": "likely-grace", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([-0.3285], grad_fn=<_TorchNNFunctionBackward>)" ] }, "execution_count": 5, "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": 6, "id": "following-extension", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25.535646438598633\n", "22.696760177612305\n", "20.039228439331055\n", "19.68790626525879\n", "19.267210006713867\n", "19.025371551513672\n", "18.154708862304688\n", "17.33785629272461\n", "19.082544326782227\n", "17.07332420349121\n", "16.21839141845703\n", "14.992581367492676\n", "14.929339408874512\n", "14.914534568786621\n", "14.907638549804688\n", "14.902363777160645\n", "14.902134895324707\n", "14.90211009979248\n", "14.902111053466797\n" ] }, { "data": { "text/plain": [ "tensor(25.5356, grad_fn=)" ] }, "execution_count": 6, "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": 7, "id": "efficient-bangkok", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 0.8\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Evaluate model and compute accuracy\n", "model1.eval()\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-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.neural_networks.SamplerQNN.html)." ] }, { "cell_type": "code", "execution_count": 8, "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": 9, "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.7055025100708008\n", "0.6669358611106873\n", "0.6768221259117126\n", "0.6784337759017944\n", "0.7485936284065247\n", "0.6641563773155212\n", "0.6561498045921326\n", "0.66301429271698\n", "0.6441987752914429\n", "0.6511136293411255\n", "0.6289191246032715\n", "0.6247060298919678\n", "0.6366127729415894\n", "0.6195870041847229\n", "0.6179186105728149\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": 10, "id": "falling-electronics", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 0.8\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Evaluate model and compute accuracy\n", "model2.eval()\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": 11, "id": "amateur-dubai", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "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": 12, "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 parameterized ansatz\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": 13, "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=)" ] }, "execution_count": 13, "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": 14, "id": "timely-happiness", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "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", "model3.eval()\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 repository](https://github.com/Qiskit/platypus/blob/main/notebooks/v2/ch-machine-learning/machine-learning-qiskit-pytorch.ipynb)." ] }, { "cell_type": "code", "execution_count": 15, "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": 16, "id": "worthy-charlotte", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "71.7%" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n", "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./data/MNIST/raw/train-images-idx3-ubyte.gz\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100.0%\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Extracting ./data/MNIST/raw/train-images-idx3-ubyte.gz to ./data/MNIST/raw\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100.0%\n", "100.0%" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n", "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./data/MNIST/raw/train-labels-idx1-ubyte.gz\n", "Extracting ./data/MNIST/raw/train-labels-idx1-ubyte.gz to ./data/MNIST/raw\n", "\n", "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n", "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw/t10k-images-idx3-ubyte.gz\n", "Extracting ./data/MNIST/raw/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100.0%\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n", "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz\n", "Extracting ./data/MNIST/raw/t10k-labels-idx1-ubyte.gz to ./data/MNIST/raw\n", "\n" ] } ], "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": 17, "id": "medieval-bibliography", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "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": 18, "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": 19, "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": 20, "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": 21, "id": "precious-career", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training [10%]\tLoss: -1.1630\n", "Training [20%]\tLoss: -1.5294\n", "Training [30%]\tLoss: -1.7855\n", "Training [40%]\tLoss: -1.9863\n", "Training [50%]\tLoss: -2.2257\n", "Training [60%]\tLoss: -2.4513\n", "Training [70%]\tLoss: -2.6758\n", "Training [80%]\tLoss: -2.8832\n", "Training [90%]\tLoss: -3.1006\n", "Training [100%]\tLoss: -3.3061\n" ] } ], "source": [ "# Define model, optimizer, and loss function\n", "optimizer = optim.Adam(model4.parameters(), lr=0.001)\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": 22, "id": "spoken-stationery", "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHHCAYAAABTMjf2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABiUklEQVR4nO3dd3QU5QLG4d9m03uAJLTQQgm9hCKEKgiIUgSliDQVEZAqKHhVQAVE6UVERbCAAtIVEEGk9957IIZekhACabv3Dy65xlASSJgk+z7n7Dns7Ozsu7vKvsx8843JarVaEREREbFBdkYHEBERETGKipCIiIjYLBUhERERsVkqQiIiImKzVIRERETEZqkIiYiIiM1SERIRERGbpSIkIiIiNktFSERERGyWipDIYwoNDcVkMjF69OjH2k7nzp0pVKhQql9v5syZj/V6Wdlff/2FyWTir7/+SvNz9fmJyD+pCInNmDlzJiaTiR07dtzz8bp161KmTJknnCrj3C0LJpOJnTt3pni8c+fOuLu7J1tWt25dTCYTTZs2TbF+agpf586dk17zQbfOnTs/9vvLyi5evMiAAQMICgrC1dUVNzc3goOD+eSTT4iIiDA6nohNsTc6gIjc8fXXX2OxWDJk20OHDmXp0qWpXv/XX39l586dBAcHp+l1unXrRoMGDZLunz59mg8//JA33niDWrVqJS0PDAxM03b/rXbt2ty6dQtHR8c0P7dgwYLcunULBweHx8rwqLZv306TJk2Ijo7mlVdeSfqMd+zYwaeffsq6detYuXKlIdlEbJGKkIjBbt68iZubW4b9MFeoUIFff/2VXbt2UalSpYeuX6BAAW7cuMGwYcNYsmRJml6revXqVK9ePen+jh07+PDDD6levTqvvPLKfZ939zNILTs7O5ydndOU7S6TyfTIz31cERERvPDCC5jNZnbv3k1QUFCyx4cPH87XX39tSLb0kpCQgMVieaSSKmIEHRoTuY86depQvnz5ez5WokQJGjVqlGL5uHHjKFiwIC4uLtSpU4cDBw4ke/zu4aiTJ0/SpEkTPDw8aN++fdJj/x4jFBERQefOnfHy8sLb25tOnTql+dBJr1698PHxYejQoala38PDg379+rF06VJ27dqVptdKjbuHKNeuXUuPHj3w8/Mjf/78AJw5c4YePXpQokQJXFxcyJkzJy+99BKh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", "text/plain": [ "
" ] }, "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": 23, "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": 24, "id": "prospective-flooring", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 24, "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": 25, "id": "spectacular-conservative", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Performance on test data:\n", "\tLoss: -3.3585\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": 26, "id": "color-brave", "metadata": { "tags": [ "nbsphinx-thumbnail" ] }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "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": 27, "id": "related-wheat", "metadata": {}, "outputs": [ { "data": { "text/html": [ "

Version Information

SoftwareVersion
qiskit0.45.2
qiskit_algorithms0.2.2
qiskit_machine_learning0.7.1
System information
Python version3.10.13
Python compilerGCC 9.4.0
Python buildmain, Jan 10 2024 19:45:45
OSLinux
CPUs1
Memory (Gb)7.744113922119141
Wed Jan 24 06:55:41 2024 UTC
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "

This code is a part of Qiskit

© Copyright IBM 2017, 2024.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import tutorial_magics\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.13" }, "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 } }, "nbformat": 4, "nbformat_minor": 5 }