{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "flsf21MK3KTd" }, "source": [ "# Quanvolution (Quantum convolution) for MNIST image classification with [TorchQuantum](https://github.com/mit-han-lab/torchquantum).\n", "

\n", "\"torchquantum\n", "

\n", "\n", "Tutorial Author: Zirui Li, Hanrui Wang\n" ] }, { "cell_type": "markdown", "metadata": { "id": "mF5Ayfdg83rT" }, "source": [ "### Outline\n", "1. Introduction to Quanvolutional Neural Network.\n", "2. Build and train a Quanvolutional Neural Network.\n", " - a. Compare Quanvolutional Neural Network with a classic model.\n", " - b. Evaluate on real quantum computer.\n", "3. Compare multiple models with or without a trainable quanvolutional filter." ] }, { "cell_type": "markdown", "metadata": { "id": "QD-1NDsh-jTm" }, "source": [ "In this tutorial, we use `tq.QuantumDevice`, `tq.GeneralEncoder`, `tq.RandomLayer`, `tq.MeasureAll`, `tq.PauliZ` class from TrochQuantum.\n", "\n", "You can learn how to build, train and evaluate a quanvolutional filter using TorchQuantum in this tutorial." ] }, { "cell_type": "markdown", "metadata": { "id": "qJv0wED75YTq" }, "source": [ "## Introduction to Quanvolutional Neural Network.\n", "### Convolutional Neural Network\n", "Convolutional neural network is a classic neural network genre, mostly applied to anylize visual images. They are known for their convolutional layers that perform convolution. Typically the convolution operation is the Frobenius inner product of the convolution filter with the input image followed by an activation function. The convolution filter slides along the input image and generates a feature map. We can use the feature map for classification.\n", "\n", "
\n", "\"conv-full-layer\"\n", "
\n", "\n", "### Quantum convolution\n", "One can extend the same idea also to the context of quantum variational circuits. Replace the classical convolution filters with variational quantum circuits and we get quanvolutional neural networks with quanvolutional filters. The quanvolutional filters perform more complex operations in a higher dimension Hilbert space than Frobenius inner product. Therefore, quanvolutional filters have more potential than traditional convolution filters.\n", "\n", "
\n", "\"conv-full-layer\"\n", "
" ] }, { "cell_type": "markdown", "metadata": { "id": "Vi8LaD0p_5rm" }, "source": [ "## Build and train a Quanvolutional Neural Network." ] }, { "cell_type": "markdown", "metadata": { "id": "pfwd2SNaOA4z" }, "source": [ "### Installation\n", "Install torchquantum and all the libs we need." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "azb47tvSiaBp", "outputId": "f0c4c497-aba5-479c-8979-3996db1174b6" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting qiskit==0.32.1\n", " Downloading qiskit-0.32.1.tar.gz (13 kB)\n", "Collecting qiskit-terra==0.18.3\n", " Downloading qiskit_terra-0.18.3-cp37-cp37m-manylinux2010_x86_64.whl (6.1 MB)\n", "\u001b[K |████████████████████████████████| 6.1 MB 4.1 MB/s \n", "\u001b[?25hCollecting qiskit-aer==0.9.1\n", " Downloading qiskit_aer-0.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (17.9 MB)\n", "\u001b[K |████████████████████████████████| 17.9 MB 633 kB/s \n", "\u001b[?25hCollecting qiskit-ibmq-provider==0.18.1\n", " Downloading qiskit_ibmq_provider-0.18.1-py3-none-any.whl (237 kB)\n", "\u001b[K |████████████████████████████████| 237 kB 73.3 MB/s \n", "\u001b[?25hCollecting qiskit-ignis==0.6.0\n", " Downloading qiskit_ignis-0.6.0-py3-none-any.whl (207 kB)\n", "\u001b[K |████████████████████████████████| 207 kB 65.4 MB/s \n", "\u001b[?25hCollecting qiskit-aqua==0.9.5\n", " Downloading qiskit_aqua-0.9.5-py3-none-any.whl (2.1 MB)\n", "\u001b[K |████████████████████████████████| 2.1 MB 60.5 MB/s \n", "\u001b[?25hRequirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit==0.32.1) (1.4.1)\n", "Requirement already satisfied: numpy>=1.16.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit==0.32.1) (1.21.5)\n", "Requirement already satisfied: h5py<3.3.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (3.1.0)\n", "Collecting quandl\n", " Downloading Quandl-3.7.0-py2.py3-none-any.whl (26 kB)\n", "Requirement already satisfied: scikit-learn>=0.20.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.0.2)\n", "Collecting yfinance>=0.1.62\n", " Downloading yfinance-0.1.70-py2.py3-none-any.whl (26 kB)\n", "Requirement already satisfied: psutil>=5 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (5.4.8)\n", "Collecting docplex>=2.21.207\n", " Downloading docplex-2.22.213.tar.gz (634 kB)\n", "\u001b[K |████████████████████████████████| 634 kB 68.2 MB/s \n", "\u001b[?25hRequirement already satisfied: setuptools>=40.1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (57.4.0)\n", "Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.7.1)\n", "Collecting retworkx>=0.8.0\n", " Downloading retworkx-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB)\n", "\u001b[K |████████████████████████████████| 1.6 MB 21.6 MB/s \n", "\u001b[?25hRequirement already satisfied: fastdtw<=0.3.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (0.3.4)\n", "Collecting dlx<=1.0.4\n", " Downloading dlx-1.0.4.tar.gz (5.5 kB)\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.3.5)\n", "Requirement already satisfied: urllib3>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (1.24.3)\n", "Requirement already satisfied: python-dateutil>=2.8.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.8.2)\n", "Collecting requests-ntlm>=1.1.0\n", " Downloading requests_ntlm-1.1.0-py2.py3-none-any.whl (5.7 kB)\n", "Requirement already satisfied: requests>=2.19 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.23.0)\n", "Collecting websocket-client>=1.0.1\n", " Downloading websocket_client-1.2.3-py3-none-any.whl (53 kB)\n", "\u001b[K |████████████████████████████████| 53 kB 2.7 MB/s \n", "\u001b[?25hCollecting python-constraint>=1.4\n", " Downloading python-constraint-1.4.0.tar.bz2 (18 kB)\n", "Collecting fastjsonschema>=2.10\n", " Downloading fastjsonschema-2.15.3-py3-none-any.whl (22 kB)\n", "Collecting symengine>0.7\n", " Downloading symengine-0.8.1-cp37-cp37m-manylinux2010_x86_64.whl (38.2 MB)\n", "\u001b[K |████████████████████████████████| 38.2 MB 116 kB/s \n", "\u001b[?25hCollecting tweedledum<2.0,>=1.1\n", " Downloading tweedledum-1.1.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (943 kB)\n", "\u001b[K |████████████████████████████████| 943 kB 22.1 MB/s \n", "\u001b[?25hCollecting ply>=3.10\n", " Downloading ply-3.11-py2.py3-none-any.whl (49 kB)\n", "\u001b[K |████████████████████████████████| 49 kB 8.3 MB/s \n", "\u001b[?25hRequirement already satisfied: dill>=0.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit==0.32.1) (0.3.4)\n", "Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit==0.32.1) (4.3.3)\n", "Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from docplex>=2.21.207->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.15.0)\n", "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<3.3.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.5.2)\n", "Requirement already satisfied: importlib-resources>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (5.4.0)\n", "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (3.10.0.2)\n", "Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (21.4.0)\n", "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (4.11.0)\n", "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (0.18.1)\n", "Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from importlib-resources>=1.4.0->jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (3.7.0)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2021.10.8)\n", "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.10)\n", "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (3.0.4)\n", "Collecting cryptography>=1.3\n", " Downloading cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl (3.6 MB)\n", "\u001b[K |████████████████████████████████| 3.6 MB 31.3 MB/s \n", "\u001b[?25hCollecting ntlm-auth>=1.0.2\n", " Downloading ntlm_auth-1.5.0-py2.py3-none-any.whl (29 kB)\n", "Requirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (1.15.0)\n", "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.21)\n", "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.1.0)\n", "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (3.1.0)\n", "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy>=1.3->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.2.1)\n", "Collecting requests>=2.19\n", " Downloading requests-2.27.1-py2.py3-none-any.whl (63 kB)\n", "\u001b[K |████████████████████████████████| 63 kB 814 kB/s \n", "\u001b[?25hRequirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit==0.32.1) (0.0.10)\n", "Collecting lxml>=4.5.1\n", " Downloading lxml-4.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.4 MB)\n", "\u001b[K |████████████████████████████████| 6.4 MB 30.3 MB/s \n", "\u001b[?25hRequirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->qiskit-aqua==0.9.5->qiskit==0.32.1) (2018.9)\n", "Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.0.11)\n", "Collecting inflection>=0.3.1\n", " Downloading inflection-0.5.1-py2.py3-none-any.whl (9.5 kB)\n", "Requirement already satisfied: more-itertools in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit==0.32.1) (8.12.0)\n", "Building wheels for collected packages: qiskit, dlx, docplex, python-constraint\n", " Building wheel for qiskit (setup.py) ... \u001b[?25l\u001b[?25hdone\n", " Created wheel for qiskit: filename=qiskit-0.32.1-py3-none-any.whl size=11777 sha256=911365fec91e5c648d2569b156af429c0aff7c3d95d453a7d24e6bf8d7d1a315\n", " Stored in directory: /root/.cache/pip/wheels/0f/62/0a/c53eda1ead41c137c47c9730bc2771a8367b1ce00fb64e8cc6\n", " Building wheel for dlx (setup.py) ... \u001b[?25l\u001b[?25hdone\n", " Created wheel for dlx: filename=dlx-1.0.4-py3-none-any.whl size=5718 sha256=cb913d8c2b19d87e8784f4220a02752c4858e3ebe531b0e80ab22c5625c1bd0b\n", " Stored in directory: /root/.cache/pip/wheels/78/55/c8/dc61e772445a566b7608a476d151e9dcaf4e092b01b0c4bc3c\n", " Building wheel for docplex (setup.py) ... \u001b[?25l\u001b[?25hdone\n", " Created wheel for docplex: filename=docplex-2.22.213-py3-none-any.whl size=696882 sha256=192bab0a2587503608ce12a090c9f129f2a6b0e88f3a41e568c07ca585b4e3ff\n", " Stored in directory: /root/.cache/pip/wheels/90/69/6b/1375c68a5b7ff94c40263b151c86f58bd72200bf0c465b5ba3\n", " Building wheel for python-constraint (setup.py) ... \u001b[?25l\u001b[?25hdone\n", " Created wheel for python-constraint: filename=python_constraint-1.4.0-py2.py3-none-any.whl size=24081 sha256=77684dcb7c666715267053a0114cf933c5c52cb7af9a30645de961f9af12c323\n", " Stored in directory: /root/.cache/pip/wheels/07/27/db/1222c80eb1e431f3d2199c12569cb1cac60f562a451fe30479\n", "Successfully built qiskit dlx docplex python-constraint\n", "Installing collected packages: tweedledum, symengine, retworkx, python-constraint, ply, fastjsonschema, requests, qiskit-terra, ntlm-auth, lxml, inflection, cryptography, yfinance, websocket-client, requests-ntlm, quandl, qiskit-ignis, docplex, dlx, qiskit-ibmq-provider, qiskit-aqua, qiskit-aer, qiskit\n", " Attempting uninstall: requests\n", " Found existing installation: requests 2.23.0\n", " Uninstalling requests-2.23.0:\n", " Successfully uninstalled requests-2.23.0\n", " Attempting uninstall: lxml\n", " Found existing installation: lxml 4.2.6\n", " Uninstalling lxml-4.2.6:\n", " Successfully uninstalled lxml-4.2.6\n", "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "google-colab 1.0.0 requires requests~=2.23.0, but you have requests 2.27.1 which is incompatible.\n", "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\u001b[0m\n", "Successfully installed cryptography-36.0.1 dlx-1.0.4 docplex-2.22.213 fastjsonschema-2.15.3 inflection-0.5.1 lxml-4.7.1 ntlm-auth-1.5.0 ply-3.11 python-constraint-1.4.0 qiskit-0.32.1 qiskit-aer-0.9.1 qiskit-aqua-0.9.5 qiskit-ibmq-provider-0.18.1 qiskit-ignis-0.6.0 qiskit-terra-0.18.3 quandl-3.7.0 requests-2.27.1 requests-ntlm-1.1.0 retworkx-0.11.0 symengine-0.8.1 tweedledum-1.1.1 websocket-client-1.2.3 yfinance-0.1.70\n" ] } ], "source": [ "!pip install qiskit==0.32.1" ] }, { "cell_type": "markdown", "metadata": { "id": "F2-0UpluOIQl" }, "source": [ "Download and cd to the repo." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "6sNqLl9tjjAf", "outputId": "0521caf5-e275-4379-87f4-fdf3cce8cb5e" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Cloning into 'torchquantum'...\n", "remote: Enumerating objects: 10737, done.\u001b[K\n", "remote: Counting objects: 100% (7529/7529), done.\u001b[K\n", "remote: Compressing objects: 100% (3777/3777), done.\u001b[K\n", "remote: Total 10737 (delta 3765), reused 7076 (delta 3348), pack-reused 3208\u001b[K\n", "Receiving objects: 100% (10737/10737), 3.19 MiB | 12.92 MiB/s, done.\n", "Resolving deltas: 100% (5732/5732), done.\n", "Checking out files: 100% (50055/50055), done.\n" ] } ], "source": [ "!git clone https://github.com/mit-han-lab/torchquantum.git" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0c2MCqFXjxkD", "outputId": "bde0ae24-ccf7-4d0f-d9fd-c45373d300ed" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/content/torchquantum\n" ] } ], "source": [ "%cd torchquantum" ] }, { "cell_type": "markdown", "metadata": { "id": "PO1xLbaOOxWk" }, "source": [ "Install torch-quantum." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3c6nfq3KkVXG", "outputId": "66d0d71e-9755-4db4-ccab-605afeeca03c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Obtaining file:///content/torchquantum\n", "Requirement already satisfied: numpy>=1.19.2 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (1.21.5)\n", "Requirement already satisfied: torchvision>=0.9.0.dev20210130 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (0.11.1+cu111)\n", "Requirement already satisfied: tqdm>=4.56.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (4.62.3)\n", "Requirement already satisfied: setuptools>=52.0.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (57.4.0)\n", "Requirement already satisfied: torch>=1.8.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (1.10.0+cu111)\n", "Collecting torchpack>=0.3.0\n", " Downloading torchpack-0.3.1-py3-none-any.whl (34 kB)\n", "Requirement already satisfied: qiskit>=0.32.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (0.32.1)\n", "Collecting matplotlib>=3.3.2\n", " Downloading matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (11.2 MB)\n", "\u001b[K |████████████████████████████████| 11.2 MB 6.5 MB/s \n", "\u001b[?25hCollecting pathos>=0.2.7\n", " Downloading pathos-0.2.8-py2.py3-none-any.whl (81 kB)\n", "\u001b[K |████████████████████████████████| 81 kB 12.1 MB/s \n", "\u001b[?25hRequirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (2.8.2)\n", "Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (3.0.7)\n", "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (0.11.0)\n", "Collecting fonttools>=4.22.0\n", " Downloading fonttools-4.29.1-py3-none-any.whl (895 kB)\n", "\u001b[K |████████████████████████████████| 895 kB 55.2 MB/s \n", "\u001b[?25hRequirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (7.1.2)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (1.3.2)\n", "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (21.3)\n", "Collecting ppft>=1.6.6.4\n", " Downloading ppft-1.6.6.4-py3-none-any.whl (65 kB)\n", "\u001b[K |████████████████████████████████| 65 kB 4.1 MB/s \n", "\u001b[?25hCollecting pox>=0.3.0\n", " Downloading pox-0.3.0-py2.py3-none-any.whl (30 kB)\n", "Requirement already satisfied: multiprocess>=0.70.12 in /usr/local/lib/python3.7/dist-packages (from pathos>=0.2.7->torchquantum==0.1.0) (0.70.12.2)\n", "Requirement already satisfied: dill>=0.3.4 in /usr/local/lib/python3.7/dist-packages (from pathos>=0.2.7->torchquantum==0.1.0) (0.3.4)\n", "Requirement already satisfied: six>=1.7.3 in /usr/local/lib/python3.7/dist-packages (from ppft>=1.6.6.4->pathos>=0.2.7->torchquantum==0.1.0) (1.15.0)\n", "Requirement already satisfied: qiskit-ibmq-provider==0.18.1 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.18.1)\n", "Requirement already satisfied: qiskit-aqua==0.9.5 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.9.5)\n", "Requirement already satisfied: qiskit-aer==0.9.1 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.9.1)\n", "Requirement already satisfied: qiskit-ignis==0.6.0 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.6.0)\n", "Requirement already satisfied: qiskit-terra==0.18.3 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.18.3)\n", "Requirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.4.1)\n", "Requirement already satisfied: quandl in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.7.0)\n", "Requirement already satisfied: scikit-learn>=0.20.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.0.2)\n", "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.3.5)\n", "Requirement already satisfied: h5py<3.3.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.1.0)\n", "Requirement already satisfied: fastdtw<=0.3.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.3.4)\n", "Requirement already satisfied: dlx<=1.0.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.0.4)\n", "Requirement already satisfied: retworkx>=0.8.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.11.0)\n", "Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.7.1)\n", "Requirement already satisfied: docplex>=2.21.207 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (2.22.213)\n", "Requirement already satisfied: yfinance>=0.1.62 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.1.70)\n", "Requirement already satisfied: psutil>=5 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (5.4.8)\n", "Requirement already satisfied: urllib3>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.24.3)\n", "Requirement already satisfied: requests-ntlm>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.0)\n", "Requirement already satisfied: websocket-client>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.2.3)\n", "Requirement already satisfied: requests>=2.19 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.27.1)\n", "Requirement already satisfied: symengine>0.7 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (0.8.1)\n", "Requirement already satisfied: fastjsonschema>=2.10 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (2.15.3)\n", "Requirement already satisfied: ply>=3.10 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.11)\n", "Requirement already satisfied: python-constraint>=1.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (1.4.0)\n", "Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (4.3.3)\n", "Requirement already satisfied: tweedledum<2.0,>=1.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.1)\n", "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<3.3.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.5.2)\n", "Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (21.4.0)\n", "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (4.11.0)\n", "Requirement already satisfied: importlib-resources>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (5.4.0)\n", "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (0.18.1)\n", "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.10.0.2)\n", "Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from importlib-resources>=1.4.0->jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.7.0)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.10)\n", "Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.0.11)\n", "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2021.10.8)\n", "Requirement already satisfied: cryptography>=1.3 in /usr/local/lib/python3.7/dist-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (36.0.1)\n", "Requirement already satisfied: ntlm-auth>=1.0.2 in /usr/local/lib/python3.7/dist-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.5.0)\n", "Requirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.15.0)\n", "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.21)\n", "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.0)\n", "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.1.0)\n", "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy>=1.3->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.2.1)\n", "Requirement already satisfied: tensorboard in /usr/local/lib/python3.7/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.0) (2.8.0)\n", "Collecting toml\n", " Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)\n", "Collecting tensorpack\n", " Downloading tensorpack-0.11-py2.py3-none-any.whl (296 kB)\n", "\u001b[K |████████████████████████████████| 296 kB 57.1 MB/s \n", "\u001b[?25hCollecting multimethod\n", " Downloading multimethod-1.7-py3-none-any.whl (9.5 kB)\n", "Collecting loguru\n", " Downloading loguru-0.6.0-py3-none-any.whl (58 kB)\n", "\u001b[K |████████████████████████████████| 58 kB 2.6 MB/s \n", "\u001b[?25hRequirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.0) (3.13)\n", "Requirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.0.10)\n", "Requirement already satisfied: lxml>=4.5.1 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (4.7.1)\n", "Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (2018.9)\n", "Requirement already satisfied: more-itertools in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (8.12.0)\n", "Requirement already satisfied: inflection>=0.3.1 in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.5.1)\n", "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.3.6)\n", "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.8.1)\n", "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.0)\n", "Requirement already satisfied: grpcio>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.43.0)\n", "Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.37.1)\n", "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.4.6)\n", "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.35.0)\n", "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.6.1)\n", "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.1)\n", "Requirement already satisfied: protobuf>=3.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.17.3)\n", "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.2.8)\n", "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (4.2.4)\n", "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (4.8)\n", "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.3.1)\n", "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.4.8)\n", "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.2.0)\n", "Requirement already satisfied: msgpack>=0.5.2 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.3)\n", "Requirement already satisfied: pyzmq>=16 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (22.3.0)\n", "Collecting msgpack-numpy>=0.4.4.2\n", " Downloading msgpack_numpy-0.4.7.1-py2.py3-none-any.whl (6.7 kB)\n", "Requirement already satisfied: tabulate>=0.7.7 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (0.8.9)\n", "Requirement already satisfied: termcolor>=1.1 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (1.1.0)\n", "Installing collected packages: msgpack-numpy, toml, tensorpack, ppft, pox, multimethod, loguru, fonttools, torchpack, pathos, matplotlib, torchquantum\n", " Attempting uninstall: matplotlib\n", " Found existing installation: matplotlib 3.2.2\n", " Uninstalling matplotlib-3.2.2:\n", " Successfully uninstalled matplotlib-3.2.2\n", " Running setup.py develop for torchquantum\n", "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.\u001b[0m\n", "Successfully installed fonttools-4.29.1 loguru-0.6.0 matplotlib-3.5.1 msgpack-numpy-0.4.7.1 multimethod-1.7 pathos-0.2.8 pox-0.3.0 ppft-1.6.6.4 tensorpack-0.11 toml-0.10.2 torchpack-0.3.1 torchquantum-0.1.0\n" ] }, { "data": { "application/vnd.colab-display-data+json": { "pip_warning": { "packages": [ "matplotlib", "mpl_toolkits" ] } } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "!pip install --editable ." ] }, { "cell_type": "markdown", "metadata": { "id": "18tqleq4O3cX" }, "source": [ "Change PYTHONPATH and install other packages." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "d7ZPp7FikrZz", "outputId": "514f9e33-cc82-4ca8-daad-63c7971bd78d" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "env: PYTHONPATH=.\n" ] } ], "source": [ "%env PYTHONPATH=." ] }, { "cell_type": "markdown", "metadata": { "id": "rhsBhV23PD4g" }, "source": [ "Run the following code to store a qiskit token. You can replace it with your own token from your IBMQ account if you like.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Iw9rQ6dcnrhe" }, "outputs": [], "source": [ "from qiskit import IBMQ\n", "# IBMQ.save_account('', overwrite=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Nvn9EkRH5fTs", "outputId": "9dc223b4-acbf-4fcc-9dc9-dd772d71eecc" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting matplotlib==3.1.3\n", " Downloading matplotlib-3.1.3-cp37-cp37m-manylinux1_x86_64.whl (13.1 MB)\n", "\u001b[K |████████████████████████████████| 13.1 MB 4.3 MB/s \n", "\u001b[?25hRequirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib==3.1.3) (3.0.7)\n", "Requirement already satisfied: numpy>=1.11 in /usr/local/lib/python3.7/dist-packages (from matplotlib==3.1.3) (1.21.5)\n", "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib==3.1.3) (0.11.0)\n", "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib==3.1.3) (2.8.2)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib==3.1.3) (1.3.2)\n", "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.1->matplotlib==3.1.3) (1.15.0)\n", "Installing collected packages: matplotlib\n", " Attempting uninstall: matplotlib\n", " Found existing installation: matplotlib 3.5.1\n", " Uninstalling matplotlib-3.5.1:\n", " Successfully uninstalled matplotlib-3.5.1\n", "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", "torchquantum 0.1.0 requires matplotlib>=3.3.2, but you have matplotlib 3.1.3 which is incompatible.\n", "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.\u001b[0m\n", "Successfully installed matplotlib-3.1.3\n" ] }, { "data": { "application/vnd.colab-display-data+json": { "pip_warning": { "packages": [ "matplotlib", "mpl_toolkits" ] } } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "!pip install matplotlib==3.1.3" ] }, { "cell_type": "markdown", "metadata": { "id": "-42mdL8CG5Vi" }, "source": [ "### Step\n", "Our code requires torchquantum lib, mnist dataset, pytorch and numpy. We need torch and the logsoftmax function from `torch.nn.functional`, optimizers(`optim`), `torchquantum` module, MNIST dataset(`MNIST`), cosine annealing learning rate(`CosineAnnealingLR`).\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "N5acspJ8G1n3" }, "outputs": [], "source": [ "import torch\n", "import torch.nn.functional as F\n", "import torch.optim as optim\n", "import numpy as np\n", "\n", "import torchquantum as tq\n", "import random\n", "\n", "from torchquantum.datasets import MNIST\n", "from torch.optim.lr_scheduler import CosineAnnealingLR" ] }, { "cell_type": "markdown", "metadata": { "id": "QiOV-xIGKXVK" }, "source": [ "### Build a quanvolutional filter\n", "Our quanvolution model is a hybrid model. It consists of two parts, the quanvolutional filter part and the classical layer part. To build the model, firstly we define our quanvolutional filter.\n", "\n", "Our quanvolutional filter’s structure is the same as the figure described above. It has four qubits. The `tq.QuantumDevice` module stores the state vector. Usually a Quantum Neural Network module consists of three parts: encoder, ansatz and measurement. We can create an encoder by passing a list of gates to `tq.GeneralEncoder`. Each entry in the list contains `input_idx`, `func`, and `wires`. Here, each qubit has a rotation-Y gate. 4 RY gates in total. They can encode the 2x2 input data to the quantum state. Then we decide our ansatz to be a random layer. We call `tq.RandomLayer` to create an ansatz composed by 8 basic gates with no more than 8 trainable parameters. And finally we perform Pauli-Z measurements on each qubit by creating a `tq.MeasureAll` module and passing `tq.PauliZ` to it. The measure function will return four expectation values from four qubits. The four results go to four channels.\n", "\n", "Next look at how quanvolutional filter works. We get the batch size. Our image is 28x28. So we reshape our input data to `(bsz, 28, 28)`.\n", "\n", "We initialize the `data_list`. The list stores the outputs in each stride.\n", "\n", "The double loop is to iterate all the possible positions that the quanvolutional filter window may stride in. Here the stride is 2.\n", "\n", "Then we catenate the data in the 2x2 window. Here we catenate four lists to one big list, so we need to reshape the list to `(4, bsz)` and transpose it to `(bsz, 4)`.\n", "\n", "Next if you want to use qiskit’s remote noise model or real quantum machine, you can set `use_qiskit=True` and pass these 5 parameters: `q_device`, `encoder`, `q_layer`, `measure`, and `data`. The `qiskit_processor` will receive these parameters, put the data in the encoder, run the while circuits and return the measurement result. Remember only when the model is doing an inference can you use qiskit remote.\n", "\n", "If you are training or not using qiskit remote, you can run the three parts one by one on google colab’s GPU.\n", "\n", "After each stride, we append the measurement result to `data_list`.\n", "\n", "Finally, we catenate the `data_list` along dimension 1 and return the result.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "iBnWI5yqKfMB" }, "outputs": [], "source": [ "class QuanvolutionFilter(tq.QuantumModule):\n", " def __init__(self):\n", " super().__init__()\n", " self.n_wires = 4\n", " self.q_device = tq.QuantumDevice(n_wires=self.n_wires)\n", " self.encoder = tq.GeneralEncoder(\n", " [ {'input_idx': [0], 'func': 'ry', 'wires': [0]},\n", " {'input_idx': [1], 'func': 'ry', 'wires': [1]},\n", " {'input_idx': [2], 'func': 'ry', 'wires': [2]},\n", " {'input_idx': [3], 'func': 'ry', 'wires': [3]},])\n", "\n", " self.q_layer = tq.RandomLayer(n_ops=8, wires=list(range(self.n_wires)))\n", " self.measure = tq.MeasureAll(tq.PauliZ)\n", "\n", " def forward(self, x, use_qiskit=False):\n", " bsz = x.shape[0]\n", " size = 28\n", " x = x.view(bsz, size, size)\n", "\n", " data_list = []\n", "\n", " for c in range(0, size, 2):\n", " for r in range(0, size, 2):\n", " data = torch.transpose(torch.cat((x[:, c, r], x[:, c, r+1], x[:, c+1, r], x[:, c+1, r+1])).view(4, bsz), 0, 1)\n", " if use_qiskit:\n", " data = self.qiskit_processor.process_parameterized(\n", " self.q_device, self.encoder, self.q_layer, self.measure, data)\n", " else:\n", " self.encoder(self.q_device, data)\n", " self.q_layer(self.q_device)\n", " data = self.measure(self.q_device)\n", "\n", " data_list.append(data.view(bsz, 4))\n", " \n", " result = torch.cat(data_list, dim=1).float()\n", " \n", " return result\n" ] }, { "cell_type": "markdown", "metadata": { "id": "KpVfJUezK7ny" }, "source": [ "### Build the whole hybrid model.\n", "\n", "Then we look at the whole model. The whole model consists of a `QuanvolutionFilter` and full connect layer(`torch.nn.Linear`). The size of input is 4\\*14\\*14 because a 28x28 image after quanvolutional filter turns into a 4 channel 14x14 feature. As the task is MNIST 10 digits classification, the size of output is 10. At last the model perform `F.logsoftmax` to the result for classification.\n", "\n", "
\n", "\"conv-full-layer\"\n", "
\n", "\n", "Here, we also has a model without quanvolutional filters used for comparison. Its full connect layer’s input size is simple 28x28.\n", "\n", "
\n", "\"conv-full-layer\"\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UbhzYiGcK9xk" }, "outputs": [], "source": [ "class HybridModel(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.qf = QuanvolutionFilter()\n", " self.linear = torch.nn.Linear(4*14*14, 10)\n", " \n", " def forward(self, x, use_qiskit=False):\n", " with torch.no_grad():\n", " x = self.qf(x, use_qiskit)\n", " x = self.linear(x)\n", " return F.log_softmax(x, -1)\n", "\n", "class HybridModel_without_qf(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.linear = torch.nn.Linear(28*28, 10)\n", " \n", " def forward(self, x, use_qiskit=False):\n", " x = x.view(-1, 28*28)\n", " x = self.linear(x)\n", " return F.log_softmax(x, -1)" ] }, { "cell_type": "markdown", "metadata": { "id": "AXwEp5SILF_Z" }, "source": [ "### Load the dataset MNIST\n", "We use MNIST classification dataset(10 digits and 1000 training samples).\n", "\n", "The `root` is the folder that stores the dataset. If there’s no MNIST dataset in root, it will automatically download MNIST.\n", "Next, we set the `train_valid_split_ratio`, `n_test_samples`, and `n_train_samples`.\n", "\n", "The dataset now contains three splits, 'train', 'valid' and 'test'. For each split, we create a dataloader with a random sampler, `batch_size` is 10, `num_workers` is 8 and `pin_memory` is true." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 512, "referenced_widgets": [ "ddcca6cc591f45a887f80bcc5d27ce13", "c8c570bdf96340c1bbf4e612f3d0c3c4", "30b8e4960e564891ad81ac242c228b25", "c46454929cae4e89976f42d9bc391a94", "ace3e747ccfd4f9f9faf46ce34936ce1", "d274e40c0adb4d3e80e8d1cf5ad475ee", "a8e8fb1c355445698cbc828dddffb9e5", "d312e5166b28438da2b9e91de91f0e09", "dc961678433f488babca027e197d2aa1", "5335eb0e67f84c85b9efacc7793d24fd", "34e1a2b9f934411090026a0ee98a3b5b", "23dbd6346f684afebcc4ea0d3e72a67e", "e85d5726a566462e962baa75f32074d6", "3b090dcf208c4822892a0afc2ba2e6a9", "d0a2f52a311541a686f592a985e1aac0", "41e329d1bd764c7cad4d2e834df50cd9", "5de520efee524ca28ed5b1b42861bef7", "b6d2f65a2e644523b7ecc6e3e9e17de3", "4abe9a5443514e00a536c839a9a5e04d", "b2ca643df597463dad1d5efe8abf64c4", "c168c7416db742f5bc74d45fe4a9bf05", "26d0390ad17048799741582271721a3e", "f314f3212d8f49468ccce3ad1cb8af6e", "694229176eb84488811763e57ccdbd9f", "32bd67ddf3a44b879cb123aa797627c0", "237d834d5fd74efa947683722d3e0e37", "29be09a9c5344928a9d2dda75ed8680c", "7584295a605c4a99a4dccce31be4cb2d", "e81b4f6589d649758fd2cd18da8ab35f", "f86c7ffecc394345a4eeb587cfd404d1", "c893fabe4af6410d837a0bd191df61d9", "f69883e80817409c9a10a2ec6d6ef68c", "45f166ea914e49c5bcf2ec39a649e351", "ae65786c8b1e4e789ecb72bcd6b9b211", "cfc67a5bebd247838d29b9babacbc103", "5953a85cd7334c828cf5005b2807fa41", "952170c8ff4d4fa9b7141d372b35cdd1", "7cbce63b72c843e9ad824dce59a7e2fb", "18acae4757154a10a7e2b9ebe4fbd53b", "364f865b5e334ac6add27ef1a32b8173", "e2b60171e7ca45bea357831419d2f9c6", "3f37e8639ddd4a6eac44420ce3275cd7", "1c75908cdb0d4909a266ef3f0184c13d", "393cc69622f3428fba3e10886e5ab65d" ] }, "id": "taGjJMVcLN2L", "outputId": "3b8c1fcd-ade1-4530-d104-36b76b1341f7" }, "outputs": [ { "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 ./mnist_data/MNIST/raw/train-images-idx3-ubyte.gz\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ddcca6cc591f45a887f80bcc5d27ce13", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/9912422 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import matplotlib\n", "\n", "fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)\n", "\n", "ax1.plot(accu_list1, label=\"with quanvolution filter\")\n", "ax1.plot(accu_list2, label=\"without quanvolution filter\")\n", "ax1.set_ylabel(\"Accuracy\")\n", "ax1.set_ylim([0.6, 1])\n", "ax1.set_xlabel(\"Epoch\")\n", "ax1.legend()\n", "\n", "ax2.plot(loss_list1, label=\"with quanvolution filter\")\n", "ax2.plot(loss_list2, label=\"without quanvolution filter\")\n", "ax2.set_ylabel(\"Loss\")\n", "ax2.set_ylim([0, 2])\n", "ax2.set_xlabel(\"Epoch\")\n", "ax2.legend()\n", "plt.tight_layout()\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": { "id": "PMU08GNiEKTW" }, "source": [ "Here we can also see the image before quanvolutional filter and after quanvolutional filter." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 690 }, "id": "710VuJZMJGGe", "outputId": "e02f51bf-08bb-4e71-9343-2ebe4bdef14c" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py:481: UserWarning: This DataLoader will create 8 worker processes in total. Our suggested max number of worker in current system is 2, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n", " cpuset_checked))\n" ] }, { "data": { "image/png": "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lFt7/24DsBtAcaTWHwBjok6zuDAm6qI0LoyJOu4//lhX/DEm6rj/+IuLmER7klwM4IjX66PQ6D9fCFEO4BwAm3rfuksI8aUQ4gUhRFYEi8KYqIuKuDAm6qIoLoyJuqiIC2OiLoriwpioi4q4MCb+hhqTaE+So4IQIg3A/wG4V0p5BsDTAEYAmAygAcATGhZPE4yJP8ZEHePijzHxx5ioY1z8MSb+GBN/oYhJtCfJ9QBKvV6X9L4XMUIII3qC/JqU8m0AkFKekFI6pZQuAM+h57JCpDAm6jSNC2OiLgrjwpio4/7jj3XFH2OijvuPv7iISbQnyZsBjBJCVAghTABuBPBepFYuhBAAlgHYLaX8rdf7RV6zzQOwM1JlAmMSiGZxYUzURWlcGBN13H/8sa74Y0zUcf/xFxcxMYS+eKEjpXQIIe4CsAo9d0q+IKX8KoJFuADA/wOwQwixvfe9/wSwQAgxGYAEUAfgjkgViDFRp3FcGBN1URcXxkQd9x9/rCv+GBN13H/8xUtM+MQ9IiIiIiKFaO9uQUREREQUcUySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTAJJmIiIiISIFJMhERERGRApNkIiIiIiIFJslERERERApMkomIiIiIFJgkExEREREpMEkmIiIiIlJgkkxEREREpMAkmYiIiIhIgUkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTAJJmIiIiISIFJMhERERGRApNkIiIiIiIFJslERERERApMkomIiIiIFJgkExEREREpMEkmIiIiIlJgkkxEREREpMAkmYiIiIhIgUkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTA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DBZj4k+rmACMixrGxB9j4i+aYwIwLmoYE3+MibqYj0ssJMmbAYwSQlQIIUwAbgTwXgTW+x6ARb1/LwLwbgTWGSzGxJ9WMQEYFzWMiT/GxF80xwRgXNQwJv4YE3WxHxcpZdRPAK4CsA9ALYCfhmH5bwBoAGBHT5+ZWwDkoOeuyK8BrAaQrXUcGBNtY8K4MCaMSWLFhHFhTBiTxI4LHyZCRERERKQQC90tiIiIiIgiikkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTAJJmIiIiISIFJMhERERGRApNkIiIiIiIFJslERERERApMkomIiIiIFJgkExER0T9G8QAAIABJREFUEREpMEkmIiIiIlJgkkxEREREpMAkmYiIiIhIgUkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTAJJmIiIiISIFJMhERERGRApNkIiIiIiIFJslERERERApMkomIiIiIFJgkExEREREpMEkmIiIiIlJgkkxEREREpMAkmYiIiIhIgUkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUmCQTERERESkwSSYiIiIiUmCSTERERESkwCSZiIiIiEiBSTIRERERkQKTZCIiIiIiBSbJREREREQKTJKJiIiIiBSYJBMRERERKTBJJiIiIiJSYJJMRERERKTAJJmIiIiISIFJMhERERGRApNkIiIiIiIFJslERERERApMkomIiIiIFJgkExEREREpMEkmIiIiIlJgkkxEREREpMAkmYiIiIhIgUkyEREREZECk2QiIiIiIgUmyURERERECkySiYiIiIgUBpUkCyFmhbogRERERETRQkgpB/4lIQ5LKcvCUB4iIiIiIs0ZAn0ghHgv0EcAcoayUiHElQB+D0AP4Hkp5a+HsjwiIiIiolAK2JIshGgGsBBAu/IjAP8rpSwY1AqF0APY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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import matplotlib\n", "\n", "n_samples = 10\n", "n_channels = 4\n", "for feed_dict in dataflow['test']:\n", " inputs = feed_dict['image'].to(device)\n", " break \n", "sample = inputs[:n_samples]\n", "after_quanv = model.qf(sample).view(n_samples, 14*14, 4).cpu().detach().numpy()\n", "\n", "fig, axes = plt.subplots(1 + n_channels, n_samples, figsize=(10, 10))\n", "for k in range(n_samples):\n", " axes[0, 0].set_ylabel(\"image\")\n", " if k != 0:\n", " axes[0, k].yaxis.set_visible(False)\n", " \n", " norm = matplotlib.colors.Normalize(vmin=0, vmax=1)\n", " \n", " axes[0, k].imshow(sample[k, 0, :, :].cpu(), norm=norm, cmap=\"gray\")\n", "\n", " for c in range(n_channels):\n", " axes[c + 1, 0].set_ylabel(\"channel {}\".format(c))\n", " if k != 0:\n", " axes[c, k].yaxis.set_visible(False)\n", " axes[c + 1, k].imshow(after_quanv[k, :, c].reshape(14, 14), norm=norm, cmap=\"gray\")\n", "\n", "plt.tight_layout()\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": { "id": "6Z_yKJ7WNKCQ" }, "source": [ "### Evaluate on real quantum computer.\n", "\n", "At last, we can run our quanvolutional filter on IBMQ’s real quantum machine. The process is really slow so I will not show it here. If you have higher priority access to IBMQ qiskit, you can check the code cell in installation and replace our token with your advance token. That will make the process faster." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "mR6wlvcbMLwx" }, "outputs": [], "source": [ "# test\n", "valid_test(dataflow, 'test', model, device, qiskit=False)\n", "\n", "# run on Qiskit simulator and real Quantum Computers\n", "try:\n", " from qiskit import IBMQ\n", " from torchquantum.plugin import QiskitProcessor\n", " # firstly perform simulate\n", " print(f\"\\nTest with Qiskit Simulator\")\n", " processor_simulation = QiskitProcessor(use_real_qc=False)\n", " model.qf.set_qiskit_processor(processor_simulation)\n", " valid_test(dataflow, 'test', model, device, qiskit=True)\n", " # then try to run on REAL QC\n", " backend_name = 'ibmq_quito'\n", " print(f\"\\nTest on Real Quantum Computer {backend_name}\")\n", " processor_real_qc = QiskitProcessor(use_real_qc=True,backend_name=backend_name)\n", " model.qf.set_qiskit_processor(processor_real_qc)\n", " valid_test(dataflow, 'test', model, device, qiskit=True)\n", "except ImportError:\n", " print(\"Please install qiskit, create an IBM Q Experience Account and \"\n", " \"save the account token according to the instruction at \"\n", " \"'https://github.com/Qiskit/qiskit-ibmq-provider', \"\n", " \"then try again.\")\n" ] }, { "cell_type": "markdown", "metadata": { "id": "NkbKoXwfnwAC" }, "source": [ "## Trainable Quanvolutional Filter\n", "In this section, we consider the case that quanvolutional filters are trainable, and we compare various models with nearly the same number of trainale parameters. The four model compared here are described by the following figure.\n", "\n", "\n", "
\n", "\"conv-full-layer\"\n", "
\n", "\n", "The Model1 contains a trainable quanvolutional filter and a fully connected layer.\n", "\n", "The Model2 contains a trainable quanvolutional filter and a quantum fully connected layer. We use `U3CU3Layer0` from `torchquantum.layers` to implement the QFC layer.\n", "\n", "When building the ansatz part of the QFC, we need to pass a dict describing the architecture of the ansatz. Here the dict is `{'n_wires': self.n_wires, 'n_blocks': 4, 'n_layers_per_block': 2}`, which means the ansatz contains n_wires qubits, there are 4 blocks and in each block are 2 layers. Passing the arch to `U3CU3Layer0` we will get a trainable ansatz with 4 blocks and in each block contains 4 U3 gates followed by 4 CU3 gates.\n", "\n", "The Model3 is simply a QFC layer.\n", "\n", "The Model4 is two fully connected layers.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "b46xdprmqcgK" }, "outputs": [], "source": [ "from torchquantum.encoding import encoder_op_list_name_dict\n", "from torchquantum.layers import U3CU3Layer0\n", "\n", "class TrainableQuanvFilter(tq.QuantumModule):\n", " def __init__(self):\n", " super().__init__()\n", " self.n_wires = 4\n", " self.q_device = tq.QuantumDevice(n_wires=self.n_wires)\n", " self.encoder = tq.GeneralEncoder(\n", " [ {'input_idx': [0], 'func': 'ry', 'wires': [0]},\n", " {'input_idx': [1], 'func': 'ry', 'wires': [1]},\n", " {'input_idx': [2], 'func': 'ry', 'wires': [2]},\n", " {'input_idx': [3], 'func': 'ry', 'wires': [3]},])\n", " \n", " self.arch = {'n_wires': self.n_wires, 'n_blocks': 5, 'n_layers_per_block': 2}\n", " self.q_layer = U3CU3Layer0(self.arch)\n", " self.measure = tq.MeasureAll(tq.PauliZ)\n", "\n", " def forward(self, x, use_qiskit=False):\n", " bsz = x.shape[0]\n", " x = F.avg_pool2d(x, 6).view(bsz, 4, 4)\n", " size = 4\n", " stride = 2\n", " x = x.view(bsz, size, size)\n", "\n", " data_list = []\n", "\n", " for c in range(0, size, stride):\n", " for r in range(0, size, stride):\n", " data = torch.transpose(torch.cat((x[:, c, r], x[:, c, r+1], x[:, c+1, r], x[:, c+1, r+1])).view(4, bsz), 0, 1)\n", " if use_qiskit:\n", " data = self.qiskit_processor.process_parameterized(\n", " self.q_device, self.encoder, self.q_layer, self.measure, data)\n", " else:\n", " self.encoder(self.q_device, data)\n", " self.q_layer(self.q_device)\n", " data = self.measure(self.q_device)\n", "\n", " data_list.append(data.view(bsz, 4))\n", " \n", " # transpose to (bsz, channel, 2x2)\n", " result = torch.transpose(torch.cat(data_list, dim=1).view(bsz, 4, 4), 1, 2).float()\n", " \n", " return result\n", "\n", "class QuantumClassifier(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.n_wires = 4\n", " self.q_device = tq.QuantumDevice(n_wires=4)\n", " self.encoder = tq.GeneralEncoder(encoder_op_list_name_dict['4x4_ryzxy'])\n", " self.arch = {'n_wires': self.n_wires, 'n_blocks': 8, 'n_layers_per_block': 2}\n", " self.ansatz = U3CU3Layer0(self.arch)\n", " self.measure = tq.MeasureAll(tq.PauliZ)\n", " \n", " def forward(self, x, use_qiskit=False):\n", " bsz = x.shape[0]\n", " x = F.avg_pool2d(x, 6).view(bsz, 16)\n", "\n", " if use_qiskit:\n", " x = self.qiskit_processor.process_parameterized(\n", " self.q_device, self.encoder, self.q_layer, self.measure, x)\n", " else:\n", " self.encoder(self.q_device, x)\n", " self.ansatz(self.q_device)\n", " x = self.measure(self.q_device)\n", "\n", " return x\n", "\n", "class QFC(tq.QuantumModule):\n", " def __init__(self):\n", " super().__init__()\n", " self.n_wires = 4\n", " self.q_device = tq.QuantumDevice(n_wires=self.n_wires)\n", " self.encoder = tq.GeneralEncoder(encoder_op_list_name_dict['4x4_ryzxy'])\n", " self.arch = {'n_wires': self.n_wires, 'n_blocks': 4, 'n_layers_per_block': 2}\n", "\n", " self.q_layer = U3CU3Layer0(self.arch)\n", " self.measure = tq.MeasureAll(tq.PauliZ)\n", "\n", " def forward(self, x, use_qiskit=False):\n", " bsz = x.shape[0]\n", " data = x\n", " if use_qiskit:\n", " data = self.qiskit_processor.process_parameterized(\n", " self.q_device, self.encoder, self.q_layer, self.measure, data)\n", " else:\n", " self.encoder(self.q_device, data)\n", " self.q_layer(self.q_device)\n", " data = self.measure(self.q_device)\n", " return data\n", "\n", "\n", "class Model1(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.qf = TrainableQuanvFilter()\n", " self.linear = torch.nn.Linear(16, 4)\n", " \n", " def forward(self, x, use_qiskit=False):\n", " x = x.view(-1, 28, 28)\n", " x = self.qf(x)\n", " x = x.reshape(-1, 16)\n", " x = self.linear(x)\n", " return F.log_softmax(x, -1)\n", "\n", "class Model2(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.qf = TrainableQuanvFilter()\n", " self.qfc = QFC()\n", " \n", " def forward(self, x, use_qiskit=False):\n", " x = x.view(-1, 28, 28)\n", " x = self.qf(x)\n", " x = x.reshape(-1, 16)\n", " x = self.qfc(x)\n", " return F.log_softmax(x, -1)\n", "\n", "class Model3(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.qfc = QuantumClassifier()\n", " \n", " def forward(self, x, use_qiskit=False):\n", " x = self.qfc(x)\n", " return F.log_softmax(x, -1)\n", "\n", "class Model4(torch.nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.linear1 = torch.nn.Linear(16, 9)\n", " self.linear2 = torch.nn.Linear(9, 4)\n", " \n", " def forward(self, x, use_qiskit=False):\n", " x = x.view(-1, 28, 28)\n", " bsz = x.shape[0]\n", " x = F.avg_pool2d(x, 6).view(bsz, 16)\n", "\n", " x = self.linear1(x)\n", " x = self.linear2(x)\n", " return F.log_softmax(x, -1)" ] }, { "cell_type": "markdown", "metadata": { "id": "PkTvypANsRIL" }, "source": [ "Here we do the MNIST 4 classification tasks." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "veZRy9L-sKBC" }, "outputs": [], "source": [ "dataset = MNIST(\n", " root='./mnist_data',\n", " train_valid_split_ratio=[0.9, 0.1],\n", " digits_of_interest=[0, 1, 2, 3],\n", " n_test_samples=300,\n", " n_train_samples=500,\n", ")\n", "\n", "dataflow = dict()\n", "for split in dataset:\n", " sampler = torch.utils.data.RandomSampler(dataset[split])\n", " dataflow[split] = torch.utils.data.DataLoader(\n", " dataset[split],\n", " batch_size=10,\n", " sampler=sampler,\n", " num_workers=8,\n", " pin_memory=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kDvJ7RmcsqAy" }, "outputs": [], "source": [ "use_cuda = torch.cuda.is_available()\n", "device = torch.device(\"cuda\" if use_cuda else \"cpu\")\n", "accus = []\n", "\n", "model_list = [Model1().to(device), Model2().to(device), Model3().to(device), Model4().to(device)]\n", "for model in model_list:\n", " n_epochs = 15\n", "\n", " optimizer = optim.Adam(model.parameters(), lr=5e-3, weight_decay=1e-4)\n", " scheduler = CosineAnnealingLR(optimizer, T_max=n_epochs)\n", " for epoch in range(1, n_epochs + 1):\n", " # train\n", " print(f\"Epoch {epoch}:\")\n", " train(dataflow, model, device, optimizer)\n", " print(optimizer.param_groups[0]['lr'])\n", " # valid\n", " accu, loss = valid_test(dataflow, 'test', model, device)\n", " scheduler.step()\n", " accus.append(accu)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "wXfgOqfr42sx" }, "outputs": [], "source": [ "for i, accu in enumerate(accus):\n", " print('accuracy of model{0}: {1}'.format(i+1, accu))" ] } ], "metadata": { "accelerator": "GPU", "colab": { "collapsed_sections": [ "pfwd2SNaOA4z" ], "name": "Quanvolution example", "provenance": [] }, "kernelspec": { "display_name": "Python 3.10.5 64-bit ('3.10.5')", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10.5" }, "vscode": { "interpreter": { "hash": "0b2ecac4133ec89d164eeefcc4a6d2d5c9a232a58380a21c437a4c41906128d5" } }, "widgets": { "application/vnd.jupyter.widget-state+json": { "18acae4757154a10a7e2b9ebe4fbd53b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "1c75908cdb0d4909a266ef3f0184c13d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "237d834d5fd74efa947683722d3e0e37": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_c893fabe4af6410d837a0bd191df61d9", "max": 1648877, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_f86c7ffecc394345a4eeb587cfd404d1", "value": 1648877 } }, "23dbd6346f684afebcc4ea0d3e72a67e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_3b090dcf208c4822892a0afc2ba2e6a9", "IPY_MODEL_d0a2f52a311541a686f592a985e1aac0", "IPY_MODEL_41e329d1bd764c7cad4d2e834df50cd9" ], "layout": "IPY_MODEL_e85d5726a566462e962baa75f32074d6" } }, "26d0390ad17048799741582271721a3e": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "29be09a9c5344928a9d2dda75ed8680c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_45f166ea914e49c5bcf2ec39a649e351", "placeholder": "​", "style": "IPY_MODEL_f69883e80817409c9a10a2ec6d6ef68c", "value": " 1649664/? [00:00<00:00, 6011445.81it/s]" } }, "30b8e4960e564891ad81ac242c228b25": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_a8e8fb1c355445698cbc828dddffb9e5", "placeholder": "​", "style": "IPY_MODEL_d274e40c0adb4d3e80e8d1cf5ad475ee", "value": "" } }, "32bd67ddf3a44b879cb123aa797627c0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_e81b4f6589d649758fd2cd18da8ab35f", "placeholder": "​", "style": "IPY_MODEL_7584295a605c4a99a4dccce31be4cb2d", "value": "" } }, "34e1a2b9f934411090026a0ee98a3b5b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "364f865b5e334ac6add27ef1a32b8173": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "393cc69622f3428fba3e10886e5ab65d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3b090dcf208c4822892a0afc2ba2e6a9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b6d2f65a2e644523b7ecc6e3e9e17de3", "placeholder": "​", "style": "IPY_MODEL_5de520efee524ca28ed5b1b42861bef7", "value": "" } }, "3f37e8639ddd4a6eac44420ce3275cd7": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "41e329d1bd764c7cad4d2e834df50cd9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_26d0390ad17048799741582271721a3e", "placeholder": "​", "style": "IPY_MODEL_c168c7416db742f5bc74d45fe4a9bf05", "value": " 29696/? [00:00<00:00, 1002987.94it/s]" } }, "45f166ea914e49c5bcf2ec39a649e351": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4abe9a5443514e00a536c839a9a5e04d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "5335eb0e67f84c85b9efacc7793d24fd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "5953a85cd7334c828cf5005b2807fa41": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_364f865b5e334ac6add27ef1a32b8173", "placeholder": "​", "style": "IPY_MODEL_18acae4757154a10a7e2b9ebe4fbd53b", "value": "" } }, "5de520efee524ca28ed5b1b42861bef7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "694229176eb84488811763e57ccdbd9f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7584295a605c4a99a4dccce31be4cb2d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "7cbce63b72c843e9ad824dce59a7e2fb": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_393cc69622f3428fba3e10886e5ab65d", "placeholder": "​", "style": "IPY_MODEL_1c75908cdb0d4909a266ef3f0184c13d", "value": " 5120/? [00:00<00:00, 87902.47it/s]" } }, "952170c8ff4d4fa9b7141d372b35cdd1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_3f37e8639ddd4a6eac44420ce3275cd7", "max": 4542, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_e2b60171e7ca45bea357831419d2f9c6", "value": 4542 } }, "a8e8fb1c355445698cbc828dddffb9e5": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ace3e747ccfd4f9f9faf46ce34936ce1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_34e1a2b9f934411090026a0ee98a3b5b", "placeholder": "​", "style": "IPY_MODEL_5335eb0e67f84c85b9efacc7793d24fd", "value": " 9913344/? [00:00<00:00, 30809548.66it/s]" } }, "ae65786c8b1e4e789ecb72bcd6b9b211": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_5953a85cd7334c828cf5005b2807fa41", "IPY_MODEL_952170c8ff4d4fa9b7141d372b35cdd1", "IPY_MODEL_7cbce63b72c843e9ad824dce59a7e2fb" ], "layout": "IPY_MODEL_cfc67a5bebd247838d29b9babacbc103" } }, "b2ca643df597463dad1d5efe8abf64c4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b6d2f65a2e644523b7ecc6e3e9e17de3": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c168c7416db742f5bc74d45fe4a9bf05": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "c46454929cae4e89976f42d9bc391a94": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_dc961678433f488babca027e197d2aa1", "max": 9912422, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_d312e5166b28438da2b9e91de91f0e09", "value": 9912422 } }, "c893fabe4af6410d837a0bd191df61d9": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c8c570bdf96340c1bbf4e612f3d0c3c4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "cfc67a5bebd247838d29b9babacbc103": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d0a2f52a311541a686f592a985e1aac0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b2ca643df597463dad1d5efe8abf64c4", "max": 28881, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_4abe9a5443514e00a536c839a9a5e04d", "value": 28881 } }, "d274e40c0adb4d3e80e8d1cf5ad475ee": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "d312e5166b28438da2b9e91de91f0e09": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "dc961678433f488babca027e197d2aa1": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ddcca6cc591f45a887f80bcc5d27ce13": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_30b8e4960e564891ad81ac242c228b25", "IPY_MODEL_c46454929cae4e89976f42d9bc391a94", "IPY_MODEL_ace3e747ccfd4f9f9faf46ce34936ce1" ], "layout": "IPY_MODEL_c8c570bdf96340c1bbf4e612f3d0c3c4" } }, "e2b60171e7ca45bea357831419d2f9c6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "e81b4f6589d649758fd2cd18da8ab35f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e85d5726a566462e962baa75f32074d6": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f314f3212d8f49468ccce3ad1cb8af6e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_32bd67ddf3a44b879cb123aa797627c0", "IPY_MODEL_237d834d5fd74efa947683722d3e0e37", "IPY_MODEL_29be09a9c5344928a9d2dda75ed8680c" ], "layout": "IPY_MODEL_694229176eb84488811763e57ccdbd9f" } }, "f69883e80817409c9a10a2ec6d6ef68c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "f86c7ffecc394345a4eeb587cfd404d1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } } } } }, "nbformat": 4, "nbformat_minor": 0 }