# QNN(量子ニューラルネットワーク)
* [TensorFlow Quantum](https://www.tensorflow.org/quantum/tutorials/mnist)を参考にする.
* [Classification with Quantum Neural Networks on Near Term Processors](https://arxiv.org/pdf/1802.06002.pdf)で紹介されたQNNのアプローチを構築.

### 必要なものをインストール

```python
!pip install tensorflow-gpu==2.1.0
```

    Collecting tensorflow-gpu==2.1.0
      Downloading tensorflow_gpu-2.1.0-cp37-cp37m-manylinux2010_x86_64.whl (421.8 MB)
         |████████████████████████████████| 421.8 MB 3.8 kB/s
    Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (0.37.1)
    Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.0.0)
    Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (0.8.1)
    Requirement already satisfied: scipy==1.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.4.1)
    Collecting tensorflow-estimator<2.2.0,>=2.1.0rc0
      Downloading tensorflow_estimator-2.1.0-py2.py3-none-any.whl (448 kB)
         |████████████████████████████████| 448 kB 58.5 MB/s
    Requirement already satisfied: numpy<2.0,>=1.16.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.21.5)
    Collecting gast==0.2.2
      Downloading gast-0.2.2.tar.gz (10 kB)
    Collecting keras-applications>=1.0.8
      Downloading Keras_Applications-1.0.8-py3-none-any.whl (50 kB)
         |████████████████████████████████| 50 kB 6.8 MB/s
    Requirement already satisfied: protobuf>=3.8.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (3.17.3)
    Requirement already satisfied: keras-preprocessing>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.1.2)
    Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.15.0)
    Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.1.0)
    Collecting tensorboard<2.2.0,>=2.1.0
      Downloading tensorboard-2.1.1-py3-none-any.whl (3.8 MB)
         |████████████████████████████████| 3.8 MB 41.5 MB/s
    Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (3.3.0)
    Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.44.0)
    Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (1.14.0)
    Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.7/dist-packages (from tensorflow-gpu==2.1.0) (0.2.0)
    Requirement already satisfied: h5py in /usr/local/lib/python3.7/dist-packages (from keras-applications>=1.0.8->tensorflow-gpu==2.1.0) (3.1.0)
    Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (3.3.6)
    Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (0.4.6)
    Requirement already satisfied: setuptools>=41.0.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (57.4.0)
    Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (2.23.0)
    Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (1.0.1)
    Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (1.35.0)
    Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (4.8)
    Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (0.2.8)
    Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (4.2.4)
    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<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (1.3.1)
    Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (4.11.3)
    Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (3.10.0.2)
    Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (3.7.0)
    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<2,>=1.6.3->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (0.4.8)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (2021.10.8)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (1.24.3)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (2.10)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (3.0.4)
    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<2.2.0,>=2.1.0->tensorflow-gpu==2.1.0) (3.2.0)
    Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py->keras-applications>=1.0.8->tensorflow-gpu==2.1.0) (1.5.2)
    Building wheels for collected packages: gast
      Building wheel for gast (setup.py) ... done
      Created wheel for gast: filename=gast-0.2.2-py3-none-any.whl size=7554 sha256=e715aa61c6e18d8f1ca4154a9e5eab5df3df02e2ae2f0e5100b6785255187638
      Stored in directory: /root/.cache/pip/wheels/21/7f/02/420f32a803f7d0967b48dd823da3f558c5166991bfd204eef3
    Successfully built gast
    Installing collected packages: tensorflow-estimator, tensorboard, keras-applications, gast, tensorflow-gpu
      Attempting uninstall: tensorflow-estimator
        Found existing installation: tensorflow-estimator 2.8.0
        Uninstalling tensorflow-estimator-2.8.0:
          Successfully uninstalled tensorflow-estimator-2.8.0
      Attempting uninstall: tensorboard
        Found existing installation: tensorboard 2.8.0
        Uninstalling tensorboard-2.8.0:
          Successfully uninstalled tensorboard-2.8.0
      Attempting uninstall: gast
        Found existing installation: gast 0.5.3
        Uninstalling gast-0.5.3:
          Successfully uninstalled gast-0.5.3
    ERROR: 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.
    tensorflow 2.8.0 requires tf-estimator-nightly==2.8.0.dev2021122109, which is not installed.
    tensorflow 2.8.0 requires tensorboard<2.9,>=2.8, but you have tensorboard 2.1.1 which is incompatible.
    tensorflow-probability 0.16.0 requires gast>=0.3.2, but you have gast 0.2.2 which is incompatible.
    Successfully installed gast-0.2.2 keras-applications-1.0.8 tensorboard-2.1.1 tensorflow-estimator-2.1.0 tensorflow-gpu-2.1.0

```python
!pip install cirq==0.7.0 pathos==0.2.5 tensorflow-quantum==0.2.0
```

    Collecting cirq==0.7.0
      Downloading cirq-0.7.0-py3-none-any.whl (1.2 MB)
         |████████████████████████████████| 1.2 MB 4.2 MB/s
    Collecting pathos==0.2.5
      Downloading pathos-0.2.5.tar.gz (162 kB)
         |████████████████████████████████| 162 kB 68.9 MB/s
    Collecting tensorflow-quantum==0.2.0
      Downloading tensorflow_quantum-0.2.0-cp37-cp37m-manylinux2010_x86_64.whl (4.5 MB)
         |████████████████████████████████| 4.5 MB 42.3 MB/s
    Collecting protobuf==3.8.0
      Downloading protobuf-3.8.0-cp37-cp37m-manylinux1_x86_64.whl (1.2 MB)
         |████████████████████████████████| 1.2 MB 47.8 MB/s
    Requirement already satisfied: requests~=2.18 in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (2.23.0)
    Collecting networkx==2.3
      Downloading networkx-2.3.zip (1.7 MB)
         |████████████████████████████████| 1.7 MB 51.2 MB/s
    Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (1.4.1)
    Requirement already satisfied: numpy~=1.16 in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (1.21.5)
    Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (1.3.5)
    Requirement already satisfied: matplotlib~=3.0 in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (3.2.2)
    Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (3.10.0.2)
    Requirement already satisfied: sortedcontainers~=2.0 in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (2.4.0)
    Requirement already satisfied: google-api-python-client~=1.6 in /usr/local/lib/python3.7/dist-packages (from cirq==0.7.0) (1.12.11)
    Collecting sympy==1.4
      Downloading sympy-1.4-py2.py3-none-any.whl (5.3 MB)
         |████████████████████████████████| 5.3 MB 38.4 MB/s
    Collecting ppft>=1.6.6.1
      Downloading ppft-1.6.6.4-py3-none-any.whl (65 kB)
         |████████████████████████████████| 65 kB 3.2 MB/s
    Requirement already satisfied: dill>=0.3.1 in /usr/local/lib/python3.7/dist-packages (from pathos==0.2.5) (0.3.4)
    Collecting pox>=0.2.7
      Downloading pox-0.3.0-py2.py3-none-any.whl (30 kB)
    Requirement already satisfied: multiprocess>=0.70.9 in /usr/local/lib/python3.7/dist-packages (from pathos==0.2.5) (0.70.12.2)
    Requirement already satisfied: decorator>=4.3.0 in /usr/local/lib/python3.7/dist-packages (from networkx==2.3->cirq==0.7.0) (4.4.2)
    Requirement already satisfied: six>=1.9 in /usr/local/lib/python3.7/dist-packages (from protobuf==3.8.0->cirq==0.7.0) (1.15.0)
    Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from protobuf==3.8.0->cirq==0.7.0) (57.4.0)
    Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy==1.4->cirq==0.7.0) (1.2.1)
    Requirement already satisfied: google-auth<3dev,>=1.16.0 in /usr/local/lib/python3.7/dist-packages (from google-api-python-client~=1.6->cirq==0.7.0) (1.35.0)
    Requirement already satisfied: uritemplate<4dev,>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from google-api-python-client~=1.6->cirq==0.7.0) (3.0.1)
    Requirement already satisfied: google-api-core<3dev,>=1.21.0 in /usr/local/lib/python3.7/dist-packages (from google-api-python-client~=1.6->cirq==0.7.0) (1.26.3)
    Requirement already satisfied: google-auth-httplib2>=0.0.3 in /usr/local/lib/python3.7/dist-packages (from google-api-python-client~=1.6->cirq==0.7.0) (0.0.4)
    Requirement already satisfied: httplib2<1dev,>=0.15.0 in /usr/local/lib/python3.7/dist-packages (from google-api-python-client~=1.6->cirq==0.7.0) (0.17.4)
    Collecting google-api-core<3dev,>=1.21.0
      Downloading google_api_core-2.7.1-py3-none-any.whl (114 kB)
         |████████████████████████████████| 114 kB 71.9 MB/s
      Downloading google_api_core-2.7.0-py3-none-any.whl (114 kB)
         |████████████████████████████████| 114 kB 69.5 MB/s
      Downloading google_api_core-2.6.1-py3-none-any.whl (114 kB)
         |████████████████████████████████| 114 kB 76.6 MB/s
      Downloading google_api_core-2.6.0-py2.py3-none-any.whl (114 kB)
         |████████████████████████████████| 114 kB 64.8 MB/s
      Downloading google_api_core-2.5.0-py2.py3-none-any.whl (111 kB)
         |████████████████████████████████| 111 kB 70.7 MB/s
      Downloading google_api_core-2.4.0-py2.py3-none-any.whl (111 kB)
         |████████████████████████████████| 111 kB 70.6 MB/s
      Downloading google_api_core-2.3.2-py2.py3-none-any.whl (109 kB)
         |████████████████████████████████| 109 kB 70.7 MB/s
      Downloading google_api_core-2.3.0-py2.py3-none-any.whl (109 kB)
         |████████████████████████████████| 109 kB 74.7 MB/s
      Downloading google_api_core-2.2.2-py2.py3-none-any.whl (95 kB)
         |████████████████████████████████| 95 kB 4.8 MB/s
      Downloading google_api_core-2.2.1-py2.py3-none-any.whl (95 kB)
         |████████████████████████████████| 95 kB 4.7 MB/s
      Downloading google_api_core-2.2.0-py2.py3-none-any.whl (95 kB)
         |████████████████████████████████| 95 kB 4.9 MB/s
      Downloading google_api_core-2.1.1-py2.py3-none-any.whl (95 kB)
         |████████████████████████████████| 95 kB 4.2 MB/s
      Downloading google_api_core-2.1.0-py2.py3-none-any.whl (94 kB)
         |████████████████████████████████| 94 kB 4.1 MB/s
      Downloading google_api_core-2.0.1-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 508 kB/s
      Downloading google_api_core-2.0.0-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 376 kB/s
      Downloading google_api_core-1.31.5-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.5 MB/s
      Downloading google_api_core-1.31.4-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.8 MB/s
      Downloading google_api_core-1.31.3-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.3 MB/s
      Downloading google_api_core-1.31.2-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.4 MB/s
      Downloading google_api_core-1.31.1-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.3 MB/s
      Downloading google_api_core-1.31.0-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.3 MB/s
      Downloading google_api_core-1.30.0-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.2 MB/s
      Downloading google_api_core-1.29.0-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.2 MB/s
      Downloading google_api_core-1.28.0-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 1.2 MB/s
      Downloading google_api_core-1.27.0-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.4 MB/s
      Downloading google_api_core-1.26.2-py2.py3-none-any.whl (93 kB)
         |████████████████████████████████| 93 kB 1.3 MB/s
      Downloading google_api_core-1.26.1-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 1.1 MB/s
      Downloading google_api_core-1.26.0-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 1.0 MB/s
      Downloading google_api_core-1.25.1-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 265 kB/s
      Downloading google_api_core-1.25.0-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 168 kB/s
      Downloading google_api_core-1.24.1-py2.py3-none-any.whl (92 kB)
         |████████████████████████████████| 92 kB 11.3 MB/s
      Downloading google_api_core-1.24.0-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 9.6 MB/s
      Downloading google_api_core-1.23.0-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 9.4 MB/s
      Downloading google_api_core-1.22.4-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 10.0 MB/s
      Downloading google_api_core-1.22.3-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 11.1 MB/s
      Downloading google_api_core-1.22.2-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 9.8 MB/s
      Downloading google_api_core-1.22.1-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 10.6 MB/s
      Downloading google_api_core-1.22.0-py2.py3-none-any.whl (91 kB)
         |████████████████████████████████| 91 kB 10.1 MB/s
      Downloading google_api_core-1.21.0-py2.py3-none-any.whl (90 kB)
         |████████████████████████████████| 90 kB 10.6 MB/s
    INFO: pip is looking at multiple versions of google-api-python-client to determine which version is compatible with other requirements. This could take a while.
    Collecting google-api-python-client~=1.6
      Downloading google_api_python_client-1.12.11-py2.py3-none-any.whl (62 kB)
         |████████████████████████████████| 62 kB 622 kB/s
      Downloading google_api_python_client-1.12.10-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 94 kB/s
      Downloading google_api_python_client-1.12.8-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 27 kB/s
      Downloading google_api_python_client-1.12.7-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 23 kB/s
      Downloading google_api_python_client-1.12.6-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 28 kB/s
      Downloading google_api_python_client-1.12.5-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 7.5 MB/s
      Downloading google_api_python_client-1.12.4-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 7.5 MB/s
    INFO: pip is looking at multiple versions of google-api-python-client to determine which version is compatible with other requirements. This could take a while.
      Downloading google_api_python_client-1.12.3-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 6.5 MB/s
      Downloading google_api_python_client-1.12.2-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 8.0 MB/s
      Downloading google_api_python_client-1.12.1-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 7.6 MB/s
      Downloading google_api_python_client-1.12.0-py2.py3-none-any.whl (61 kB)
         |████████████████████████████████| 61 kB 8.0 MB/s
      Downloading google_api_python_client-1.11.0-py2.py3-none-any.whl (60 kB)
         |████████████████████████████████| 60 kB 6.8 MB/s
    Collecting google-api-core<2dev,>=1.18.0
      Downloading google_api_core-1.20.1-py2.py3-none-any.whl (90 kB)
         |████████████████████████████████| 90 kB 9.3 MB/s
      Downloading google_api_core-1.19.1-py2.py3-none-any.whl (90 kB)
         |████████████████████████████████| 90 kB 10.2 MB/s
    Requirement already satisfied: googleapis-common-protos<2.0dev,>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from google-api-core<2dev,>=1.18.0->google-api-python-client~=1.6->cirq==0.7.0) (1.56.0)
    Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from google-api-core<2dev,>=1.18.0->google-api-python-client~=1.6->cirq==0.7.0) (2018.9)
    Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3dev,>=1.16.0->google-api-python-client~=1.6->cirq==0.7.0) (4.8)
    Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3dev,>=1.16.0->google-api-python-client~=1.6->cirq==0.7.0) (4.2.4)
    Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3dev,>=1.16.0->google-api-python-client~=1.6->cirq==0.7.0) (0.2.8)
    Collecting googleapis-common-protos<2.0dev,>=1.6.0
      Downloading googleapis_common_protos-1.55.0-py2.py3-none-any.whl (212 kB)
         |████████████████████████████████| 212 kB 64.5 MB/s
      Downloading googleapis_common_protos-1.54.0-py2.py3-none-any.whl (207 kB)
         |████████████████████████████████| 207 kB 69.8 MB/s
      Downloading googleapis_common_protos-1.53.0-py2.py3-none-any.whl (198 kB)
         |████████████████████████████████| 198 kB 72.1 MB/s
      Downloading googleapis_common_protos-1.52.0-py2.py3-none-any.whl (100 kB)
         |████████████████████████████████| 100 kB 9.8 MB/s
    Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib~=3.0->cirq==0.7.0) (0.11.0)
    Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib~=3.0->cirq==0.7.0) (2.8.2)
    Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib~=3.0->cirq==0.7.0) (1.4.0)
    Requirement 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.0->cirq==0.7.0) (3.0.7)
    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<3dev,>=1.16.0->google-api-python-client~=1.6->cirq==0.7.0) (0.4.8)
    Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests~=2.18->cirq==0.7.0) (2.10)
    Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests~=2.18->cirq==0.7.0) (1.24.3)
    Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests~=2.18->cirq==0.7.0) (3.0.4)
    Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests~=2.18->cirq==0.7.0) (2021.10.8)
    Building wheels for collected packages: pathos, networkx
      Building wheel for pathos (setup.py) ... done
      Created wheel for pathos: filename=pathos-0.2.5-py3-none-any.whl size=77595 sha256=88ed6c000eabbf3ce8d4533c00696122fa8e1b32f71f0e6cdea2da03d440da15
      Stored in directory: /root/.cache/pip/wheels/1f/53/6c/89b4af46fdc1e3976b9c183414af0db994678d1294a1e6dfb4
      Building wheel for networkx (setup.py) ... done
      Created wheel for networkx: filename=networkx-2.3-py2.py3-none-any.whl size=1556008 sha256=0bfb5b96f009793f81949034deb6ca4afd5da784977d574a2e1bd86c539d8360
      Stored in directory: /root/.cache/pip/wheels/44/e6/b8/4efaab31158e9e9ca9ed80b11f6b11130bac9a9672b3cbbeaf
    Successfully built pathos networkx
    Installing collected packages: protobuf, googleapis-common-protos, google-api-core, sympy, networkx, google-api-python-client, ppft, pox, cirq, tensorflow-quantum, pathos
      Attempting uninstall: protobuf
        Found existing installation: protobuf 3.17.3
        Uninstalling protobuf-3.17.3:
          Successfully uninstalled protobuf-3.17.3
      Attempting uninstall: googleapis-common-protos
        Found existing installation: googleapis-common-protos 1.56.0
        Uninstalling googleapis-common-protos-1.56.0:
          Successfully uninstalled googleapis-common-protos-1.56.0
      Attempting uninstall: google-api-core
        Found existing installation: google-api-core 1.26.3
        Uninstalling google-api-core-1.26.3:
          Successfully uninstalled google-api-core-1.26.3
      Attempting uninstall: sympy
        Found existing installation: sympy 1.7.1
        Uninstalling sympy-1.7.1:
          Successfully uninstalled sympy-1.7.1
      Attempting uninstall: networkx
        Found existing installation: networkx 2.6.3
        Uninstalling networkx-2.6.3:
          Successfully uninstalled networkx-2.6.3
      Attempting uninstall: google-api-python-client
        Found existing installation: google-api-python-client 1.12.11
        Uninstalling google-api-python-client-1.12.11:
          Successfully uninstalled google-api-python-client-1.12.11
    ERROR: 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.
    tensorflow 2.8.0 requires tf-estimator-nightly==2.8.0.dev2021122109, which is not installed.
    tensorflow 2.8.0 requires protobuf>=3.9.2, but you have protobuf 3.8.0 which is incompatible.
    tensorflow 2.8.0 requires tensorboard<2.9,>=2.8, but you have tensorboard 2.1.1 which is incompatible.
    tensorflow-metadata 1.7.0 requires protobuf<4,>=3.13, but you have protobuf 3.8.0 which is incompatible.
    earthengine-api 0.1.303 requires google-api-python-client<2,>=1.12.1, but you have google-api-python-client 1.11.0 which is incompatible.
    albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.
    Successfully installed cirq-0.7.0 google-api-core-1.19.1 google-api-python-client-1.11.0 googleapis-common-protos-1.52.0 networkx-2.3 pathos-0.2.5 pox-0.3.0 ppft-1.6.6.4 protobuf-3.8.0 sympy-1.4 tensorflow-quantum-0.2.0

## ライブラリのインポート

```python
import tensorflow as tf
import tensorflow_quantum as tfq

import cirq
import sympy
import numpy as np
import pandas as pd
import seaborn as sns
import collections

# visualization tools
%matplotlib inline
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit
```

# データの用意
* mnistのデータを用意
* 量子デバイス(今回はシミュレーション)では大きいデータ量を扱えないので画像データをダウンスケールする
* 二値分類を行うためmnistのデータを「3」と「6」のデータに絞る

### データの用意とダウンスケール

```python
#kerasでmnistのデータをダウンロード
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# 画像データを[0,255]から[0.0,1.0]にスケーリング
x_train, x_test = x_train[..., np.newaxis]/255.0, x_test[..., np.newaxis]/255.0

print("Number of original training examples:", len(x_train))
print("Number of original test examples:", len(x_test))
```

    Number of original training examples: 60000
    Number of original test examples: 10000

```python
def filter_36(x, y):
    keep = (y == 3) | (y == 6)
    x, y = x[keep], y[keep]
    y = y == 3
    return x,y
```

```python
#学習データを3と6に限定
x_train, y_train = filter_36(x_train, y_train)
x_test, y_test = filter_36(x_test, y_test)

print("Number of filtered training examples:", len(x_train))
print("Number of filtered test examples:", len(x_test))
```

    Number of filtered training examples: 12049
    Number of filtered test examples: 1968

```python
plt.imshow(x_train[7, :, :, 0])
plt.colorbar()
```

```python
#画像のデータをダウンスケールする
x_train_small = tf.image.resize(x_train, (4,4)).numpy()
x_test_small = tf.image.resize(x_test, (4,4)).numpy()

#ダウンスケール後の画像を表示
plt.imshow(x_train_small[7, :, :, 0])
```

### 両方のクラスに属する画像の削除

```python
# 両方のクラスに属する画像の削除
def remove_contradicting(xs, ys):
    mapping = collections.defaultdict(set)
    orig_x = {}
    # Determine the set of labels for each unique image:
    for x,y in zip(xs,ys):
       orig_x[tuple(x.flatten())] = x
       mapping[tuple(x.flatten())].add(y)

    new_x = []
    new_y = []
    for flatten_x in mapping:
      x = orig_x[flatten_x]
      labels = mapping[flatten_x]
      if len(labels) == 1:
          new_x.append(x)
          new_y.append(next(iter(labels)))
      else:
          # Throw out images that match more than one label.
          pass

    num_uniq_3 = sum(1 for value in mapping.values() if len(value) == 1 and True in value)
    num_uniq_6 = sum(1 for value in mapping.values() if len(value) == 1 and False in value)
    num_uniq_both = sum(1 for value in mapping.values() if len(value) == 2)

    print("Number of unique images:", len(mapping.values()))
    print("Number of unique 3s: ", num_uniq_3)
    print("Number of unique 6s: ", num_uniq_6)
    print("Number of unique contradicting labels (both 3 and 6): ", num_uniq_both)
    print()
    print("Initial number of images: ", len(xs))
    print("Remaining non-contradicting unique images: ", len(new_x))

    return np.array(new_x), np.array(new_y)
```

```python
x_train_nocon, y_train_nocon = remove_contradicting(x_train_small, y_train)
```

    Number of unique images: 10387
    Number of unique 3s:  4912
    Number of unique 6s:  5426
    Number of unique contradicting labels (both 3 and 6):  49

    Initial number of images:  12049
    Remaining non-contradicting unique images:  10338

### 出力のラベルを0,1に変換

```python
# 出力ラベルがブール値になっているので[0,1]の値に変換
y_train_binary = 1.0*y_train_nocon
y_test_binary = 1.0*y_test
```

# 入力する量子状態の用意
* 入力する値は0か1の二値で用意する
* 0か1の状態で入力するため，入力が1となる量子ビットに対してはXゲートを作用させ反転させてから入力する

### 量子状態の入力のための変換
* 量子状態の入力には0か1の値を用いるため，閾値を決め0か1の値に変換する．

```python
#0.5を閾値として0か１のバイナリー変数に変換
threshold = 0.5

x_train_bin = np.array(x_train_nocon > threshold, dtype = np.float32)
x_test_bin = np.array(x_test_small > threshold, dtype = np.float32)
```

### 入力する量子状態を変換する関数の用意

```python
def convert_to_circuit(image):
    """Encode truncated classical image into quantum datapoint."""
    values = np.ndarray.flatten(image)
    qubits = cirq.GridQubit.rect(4, 4)
    circuit = cirq.Circuit()
    for i, value in enumerate(values):
        if value:
            circuit.append(cirq.X(qubits[i]))
    return circuit

x_train_circ = [convert_to_circuit(x) for x in x_train_bin]
x_test_circ = [convert_to_circuit(x) for x in x_test_bin]
```

```python
SVGCircuit(x_train_circ[0])
```

```python
#画素値が閾値を超えたインデックスの表示
#閾値を超えているインデックスにXゲートがかかっているかを確認
bin_img = x_train_bin[0,:,:,0]
indices = np.array(np.where(bin_img)).T
indices
```

    array([[2, 2],
           [3, 1]])

### Cirq回路をtfqのためのテンソルに変換
* tfq.convert_to_tensorによってテンソル表現に変換する

```python
x_train_tfcirc = tfq.convert_to_tensor(x_train_circ)
x_test_tfcirc = tfq.convert_to_tensor(x_test_circ)
```

# QNNモデルの作成

* QNNモデルを作成するのに必要な量子回路の繰り返しを作るクラスの定義

```python
class CircuitLayerBuilder():
    def __init__(self, data_qubits, readout):
        self.data_qubits = data_qubits
        self.readout = readout

    def add_layer(self, circuit, gate, prefix):
        for i, qubit in enumerate(self.data_qubits):
            symbol = sympy.Symbol(prefix + '-' + str(i))
            circuit.append(gate(qubit, self.readout)**symbol)
```

* 量子回路の繰り返しを実際に出力してみる

```python
demo_builder = CircuitLayerBuilder(data_qubits = cirq.GridQubit.rect(4,1),
                                   readout=cirq.GridQubit(-1,-1))

circuit = cirq.Circuit()
demo_builder.add_layer(circuit, gate = cirq.XX, prefix='xx')
SVGCircuit(circuit)
```

* 実際に学習に使う量子回路の作成
* 入力はデータサイズの16量子ビット+出力を取り出すための1量子ビットの合計17量子ビット
* X軸回転とZ軸回転の両方を使い関数を表現するためXXゲートの操作のあと，ZZゲートの操作をする

```python
def create_quantum_model():
    """Create a QNN model circuit and readout operation to go along with it."""
    data_qubits = cirq.GridQubit.rect(4, 4)  # a 4x4 grid.
    readout = cirq.GridQubit(-1, -1)         # a single qubit at [-1,-1]
    circuit = cirq.Circuit()

    # Prepare the readout qubit.
    circuit.append(cirq.X(readout))
    circuit.append(cirq.H(readout))

    builder = CircuitLayerBuilder(
        data_qubits = data_qubits,
        readout=readout)

    # XXゲート，ZZゲートの繰り返し
    builder.add_layer(circuit, cirq.XX, "xx1")
    builder.add_layer(circuit, cirq.ZZ, "zz1")

    # 最後に測定量子ビットにアダマールゲートをかける
    circuit.append(cirq.H(readout))

    return circuit, cirq.Z(readout)
```

```python
#量子回路の作成
model_circuit, model_readout = create_quantum_model()

#量子回路の可視化
SVGCircuit(model_circuit)
```

* モデル全体の作成

```python
# 古典のTensorFlow同様にモデルを作成する
model = tf.keras.Sequential([
    # データを入力しtf.stringに変換するためのレイヤー
    tf.keras.layers.Input(shape=(), dtype=tf.string),
    # [-1,1]の間の値を出力する量子回路のレイヤー
    tfq.layers.PQC(model_circuit, model_readout),
])

# 損失関数，最適化関数，評価関数を指定してコンパイル
model.compile(
    loss = tf.keras.losses.BinaryCrossentropy(),
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
    metrics=['accuracy'])
```

```python
# モデルのパラメータなどを確認
print(model.summary())
```

    Model: "sequential_1"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    pqc_1 (PQC)                  (None, 1)                 32
    =================================================================
    Total params: 32
    Trainable params: 32
    Non-trainable params: 0
    _________________________________________________________________
    None

# QNNの学習
* 学習はTensorFlowでNNモデルを学習させる時とほとんど変わらない
* TensorFlow QuantumはGPUには載せられないため学習時間は結構かかる(2022/3/29時点)

```python
EPOCHS = 10
BATCH_SIZE = 32

#NUM_EXAMPLES = len(x_train_tfcirc)
NUM_EXAMPLES = 1000

#学習に時間がかかるのでデータを減らす
x_train_tfcirc_sub = x_train_tfcirc[:NUM_EXAMPLES]
y_train_binary_sub = y_train_binary[:NUM_EXAMPLES]
```

```python
# モデルの保存方法の指定
checkpoint_filepath = "weight.ckpt"
model_checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_filepath,   # 保存path
    save_weights_only=True,      # 重みのみを保存
    monitor='val_acc',             # validataionのACCの値に基づいて重みを保存する
    mode='max',                  # validataionのACCが最大となった時重みを保存する
    save_best_only=True          # ACCが改善したときのみ保存する
)

# モデルの学習の開始
qnn_history = model.fit(
      x_train_tfcirc_sub, y_train_binary_sub,
      batch_size=32,
      epochs=EPOCHS,
      verbose=1,
      validation_data=(x_test_tfcirc, y_test_binary),
      callbacks=[model_checkpoint_callback]
      )
```

    Train on 1000 samples, validate on 1968 samples
    Epoch 1/10
     992/1000 [============================>.] - ETA: 1s - loss: 1.5904 - accuracy: 0.5383WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 163s 163ms/sample - loss: 1.5810 - accuracy: 0.5400 - val_loss: 1.2817 - val_accuracy: 0.6494
    Epoch 2/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.9744 - accuracy: 0.8024WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 174s 174ms/sample - loss: 0.9697 - accuracy: 0.8030 - val_loss: 1.1291 - val_accuracy: 0.8415
    Epoch 3/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.9132 - accuracy: 0.8448WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 174s 174ms/sample - loss: 0.9074 - accuracy: 0.8460 - val_loss: 1.0848 - val_accuracy: 0.8476
    Epoch 4/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.9282 - accuracy: 0.7016WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 158s 158ms/sample - loss: 0.9383 - accuracy: 0.7020 - val_loss: 0.8874 - val_accuracy: 0.8526
    Epoch 5/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.7021 - accuracy: 0.8679WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 156s 156ms/sample - loss: 0.6997 - accuracy: 0.8680 - val_loss: 0.6399 - val_accuracy: 0.8572
    Epoch 6/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.6111 - accuracy: 0.8710WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 157s 157ms/sample - loss: 0.6227 - accuracy: 0.8710 - val_loss: 0.6680 - val_accuracy: 0.8557
    Epoch 7/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.6063 - accuracy: 0.8700WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 156s 156ms/sample - loss: 0.6039 - accuracy: 0.8690 - val_loss: 0.6351 - val_accuracy: 0.8557
    Epoch 8/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.5904 - accuracy: 0.8679WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 157s 157ms/sample - loss: 0.5863 - accuracy: 0.8690 - val_loss: 0.6200 - val_accuracy: 0.8557
    Epoch 9/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.5634 - accuracy: 0.8821WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 157s 157ms/sample - loss: 0.5641 - accuracy: 0.8790 - val_loss: 0.5255 - val_accuracy: 0.8603
    Epoch 10/10
     992/1000 [============================>.] - ETA: 1s - loss: 0.5411 - accuracy: 0.8810WARNING:tensorflow:Can save best model only with val_acc available, skipping.
    1000/1000 [==============================] - 157s 157ms/sample - loss: 0.5387 - accuracy: 0.8810 - val_loss: 0.6013 - val_accuracy: 0.8943
    1968/1968 [==============================] - 11s 6ms/sample - loss: 0.6013 - accuracy: 0.8943

# 学習結果の可視化

```python
# 学習ログをDataFrameに変換
history_df = pd.DataFrame(qnn_history.history)
# 学習ログの保存
#history_df.to_csv("history_df.csv", index=None)

# 損失のログの可視化
plt.plot(np.arange(len(history_df)), history_df['loss'], label='loss')
plt.plot(np.arange(len(history_df)), history_df['val_loss'], label='valid loss')
plt.legend()
plt.show()
```

```python
# ACCの値のログの可視化
plt.plot(np.arange(len(history_df)), history_df['accuracy'], label='accuracy')
plt.plot(np.arange(len(history_df)), history_df['val_accuracy'], label='val_accuracy')
plt.legend()
plt.show()
```