--- a
+++ b/Code/All Qiskit, PennyLane QML Nov 23/36a1 GAN A100 Light.gpu 10.10s kkawchak.ipynb
@@ -0,0 +1,716 @@
+{
+  "cells": [
+    {
+      "cell_type": "code",
+      "execution_count": 19,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "URenBt8iB4_G",
+        "outputId": "55500867-9b1c-44de-8414-838d3a0c02c8"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Time in seconds since beginning of run: 1700611267.2426076\n",
+            "Wed Nov 22 00:01:07 2023\n"
+          ]
+        }
+      ],
+      "source": [
+        "# This cell is added by sphinx-gallery\n",
+        "# It can be customized to whatever you like\n",
+        "%matplotlib inline\n",
+        "# !pip install pennylane pennylane-lightning-gpu custatevec-cu11 --upgrade\n",
+        "# !pip install pennylane-cirq\n",
+        "# !pip install tensorflow==2.8.1\n",
+        "# !pip install qsimcirq\n",
+        "import time\n",
+        "seconds = time.time()\n",
+        "print(\"Time in seconds since beginning of run:\", seconds)\n",
+        "local_time = time.ctime(seconds)\n",
+        "print(local_time)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "1xodSdeDB4_G"
+      },
+      "source": [
+        "Quantum generative adversarial networks with Cirq + TensorFlow {#quantum_GAN}\n",
+        "==============================================================\n",
+        "\n",
+        "::: {.meta}\n",
+        ":property=\\\"og:description\\\": This demo constructs and trains a Quantum\n",
+        "Generative Adversarial Network (QGAN) using PennyLane, Cirq, and\n",
+        "TensorFlow. :property=\\\"og:image\\\":\n",
+        "<https://pennylane.ai/qml/_images/qgan3.png>\n",
+        ":::\n",
+        "\n",
+        "*Author: Nathan Killoran --- Posted: 11 October 2019. Last updated: 30\n",
+        "January 2023.*\n",
+        "\n",
+        "This demo constructs a Quantum Generative Adversarial Network (QGAN)\n",
+        "([Lloyd and Weedbrook\n",
+        "(2018)](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.121.040502),\n",
+        "[Dallaire-Demers and Killoran\n",
+        "(2018)](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.98.012324))\n",
+        "using two subcircuits, a *generator* and a *discriminator*. The\n",
+        "generator attempts to generate synthetic quantum data to match a pattern\n",
+        "of \\\"real\\\" data, while the discriminator tries to discern real data\n",
+        "from fake data (see image below). The gradient of the discriminator's\n",
+        "output provides a training signal for the generator to improve its fake\n",
+        "generated data.\n",
+        "\n",
+        "|\n",
+        "\n",
+        "![](../demonstrations/QGAN/qgan.png){.align-center width=\"75.0%\"}\n",
+        "\n",
+        "|\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "Q8AMvcT-B4_H"
+      },
+      "source": [
+        "Using Cirq + TensorFlow\n",
+        "=======================\n",
+        "\n",
+        "PennyLane allows us to mix and match quantum devices and classical\n",
+        "machine learning software. For this demo, we will link together\n",
+        "Google\\'s [Cirq](https://cirq.readthedocs.io/en/stable/) and\n",
+        "[TensorFlow](https://www.tensorflow.org/) libraries.\n",
+        "\n",
+        "We begin by importing PennyLane, NumPy, and TensorFlow.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 20,
+      "metadata": {
+        "id": "jZnEogOMB4_H"
+      },
+      "outputs": [],
+      "source": [
+        "import numpy as np\n",
+        "import pennylane as qml\n",
+        "import tensorflow as tf"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "VE_Ig3zoB4_H"
+      },
+      "source": [
+        "We also declare a 3-qubit simulator device running in Cirq.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 21,
+      "metadata": {
+        "id": "qgDmLFu5B4_I"
+      },
+      "outputs": [],
+      "source": [
+        "dev = qml.device('lightning.gpu', wires=3)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "_6MqJwPsB4_I"
+      },
+      "source": [
+        "Generator and Discriminator\n",
+        "===========================\n",
+        "\n",
+        "In classical GANs, the starting point is to draw samples either from\n",
+        "some \\\"real data\\\" distribution, or from the generator, and feed them to\n",
+        "the discriminator. In this QGAN example, we will use a quantum circuit\n",
+        "to generate the real data.\n",
+        "\n",
+        "For this simple example, our real data will be a qubit that has been\n",
+        "rotated (from the starting state $\\left|0\\right\\rangle$) to some\n",
+        "arbitrary, but fixed, state.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 22,
+      "metadata": {
+        "id": "gjBLrnOnB4_I"
+      },
+      "outputs": [],
+      "source": [
+        "def real(angles, **kwargs):\n",
+        "    qml.Hadamard(wires=0)\n",
+        "    qml.Rot(*angles, wires=0)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "bPLhFqDEB4_I"
+      },
+      "source": [
+        "For the generator and discriminator, we will choose the same basic\n",
+        "circuit structure, but acting on different wires.\n",
+        "\n",
+        "Both the real data circuit and the generator will output on wire 0,\n",
+        "which will be connected as an input to the discriminator. Wire 1 is\n",
+        "provided as a workspace for the generator, while the discriminator's\n",
+        "output will be on wire 2.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 23,
+      "metadata": {
+        "id": "UoOK7QA9B4_I"
+      },
+      "outputs": [],
+      "source": [
+        "def generator(w, **kwargs):\n",
+        "    qml.Hadamard(wires=0)\n",
+        "    qml.RX(w[0], wires=0)\n",
+        "    qml.RX(w[1], wires=1)\n",
+        "    qml.RY(w[2], wires=0)\n",
+        "    qml.RY(w[3], wires=1)\n",
+        "    qml.RZ(w[4], wires=0)\n",
+        "    qml.RZ(w[5], wires=1)\n",
+        "    qml.CNOT(wires=[0, 1])\n",
+        "    qml.RX(w[6], wires=0)\n",
+        "    qml.RY(w[7], wires=0)\n",
+        "    qml.RZ(w[8], wires=0)\n",
+        "\n",
+        "\n",
+        "def discriminator(w):\n",
+        "    qml.Hadamard(wires=0)\n",
+        "    qml.RX(w[0], wires=0)\n",
+        "    qml.RX(w[1], wires=2)\n",
+        "    qml.RY(w[2], wires=0)\n",
+        "    qml.RY(w[3], wires=2)\n",
+        "    qml.RZ(w[4], wires=0)\n",
+        "    qml.RZ(w[5], wires=2)\n",
+        "    qml.CNOT(wires=[0, 2])\n",
+        "    qml.RX(w[6], wires=2)\n",
+        "    qml.RY(w[7], wires=2)\n",
+        "    qml.RZ(w[8], wires=2)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "BA6j3YglB4_I"
+      },
+      "source": [
+        "We create two QNodes. One where the real data source is wired up to the\n",
+        "discriminator, and one where the generator is connected to the\n",
+        "discriminator. In order to pass TensorFlow Variables into the quantum\n",
+        "circuits, we specify the `\"tf\"` interface.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 24,
+      "metadata": {
+        "id": "OLk5Bxs9B4_I"
+      },
+      "outputs": [],
+      "source": [
+        "@qml.qnode(dev, interface=\"tf\")\n",
+        "def real_disc_circuit(phi, theta, omega, disc_weights):\n",
+        "    real([phi, theta, omega])\n",
+        "    discriminator(disc_weights)\n",
+        "    return qml.expval(qml.PauliZ(2))\n",
+        "\n",
+        "\n",
+        "@qml.qnode(dev, interface=\"tf\")\n",
+        "def gen_disc_circuit(gen_weights, disc_weights):\n",
+        "    generator(gen_weights)\n",
+        "    discriminator(disc_weights)\n",
+        "    return qml.expval(qml.PauliZ(2))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "VbnRyFpjB4_I"
+      },
+      "source": [
+        "QGAN cost functions\n",
+        "===================\n",
+        "\n",
+        "There are two cost functions of interest, corresponding to the two\n",
+        "stages of QGAN training. These cost functions are built from two pieces:\n",
+        "the first piece is the probability that the discriminator correctly\n",
+        "classifies real data as real. The second piece is the probability that\n",
+        "the discriminator classifies fake data (i.e., a state prepared by the\n",
+        "generator) as real.\n",
+        "\n",
+        "The discriminator is trained to maximize the probability of correctly\n",
+        "classifying real data, while minimizing the probability of mistakenly\n",
+        "classifying fake data.\n",
+        "\n",
+        "$$Cost_D = \\mathrm{Pr}(real|\\mathrm{fake}) - \\mathrm{Pr}(real|\\mathrm{real})$$\n",
+        "\n",
+        "The generator is trained to maximize the probability that the\n",
+        "discriminator accepts fake data as real.\n",
+        "\n",
+        "$$Cost_G = - \\mathrm{Pr}(real|\\mathrm{fake})$$\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 25,
+      "metadata": {
+        "id": "qZOU-2G1B4_I"
+      },
+      "outputs": [],
+      "source": [
+        "def prob_real_true(disc_weights):\n",
+        "    true_disc_output = real_disc_circuit(phi, theta, omega, disc_weights)\n",
+        "    # convert to probability\n",
+        "    prob_real_true = (true_disc_output + 1) / 2\n",
+        "    return prob_real_true\n",
+        "\n",
+        "\n",
+        "def prob_fake_true(gen_weights, disc_weights):\n",
+        "    fake_disc_output = gen_disc_circuit(gen_weights, disc_weights)\n",
+        "    # convert to probability\n",
+        "    prob_fake_true = (fake_disc_output + 1) / 2\n",
+        "    return prob_fake_true\n",
+        "\n",
+        "\n",
+        "def disc_cost(disc_weights):\n",
+        "    cost = prob_fake_true(gen_weights, disc_weights) - prob_real_true(disc_weights)\n",
+        "    return cost\n",
+        "\n",
+        "\n",
+        "def gen_cost(gen_weights):\n",
+        "    return -prob_fake_true(gen_weights, disc_weights)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "uf3SAVEMB4_J"
+      },
+      "source": [
+        "Training the QGAN\n",
+        "=================\n",
+        "\n",
+        "We initialize the fixed angles of the \\\"real data\\\" circuit, as well as\n",
+        "the initial parameters for both generator and discriminator. These are\n",
+        "chosen so that the generator initially prepares a state on wire 0 that\n",
+        "is very close to the $\\left| 1 \\right\\rangle$ state.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 26,
+      "metadata": {
+        "id": "IWGiPa4dB4_J"
+      },
+      "outputs": [],
+      "source": [
+        "phi = np.pi / 6\n",
+        "theta = np.pi / 2\n",
+        "omega = np.pi / 7\n",
+        "np.random.seed(0)\n",
+        "eps = 1e-2\n",
+        "init_gen_weights = np.array([np.pi] + [0] * 8) + \\\n",
+        "                   np.random.normal(scale=eps, size=(9,))\n",
+        "init_disc_weights = np.random.normal(size=(9,))\n",
+        "\n",
+        "gen_weights = tf.Variable(init_gen_weights)\n",
+        "disc_weights = tf.Variable(init_disc_weights)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "NVz7yaXGB4_J"
+      },
+      "source": [
+        "We begin by creating the optimizer:\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 27,
+      "metadata": {
+        "id": "8XQoiYjiB4_J"
+      },
+      "outputs": [],
+      "source": [
+        "opt = tf.keras.optimizers.SGD(0.4)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "BrUfmFDWB4_J"
+      },
+      "source": [
+        "In the first stage of training, we optimize the discriminator while\n",
+        "keeping the generator parameters fixed.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 28,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "6_diImNYB4_J",
+        "outputId": "dc877ef3-2fb8-4d16-b2b9-680ae547815e"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Step 0: cost = -0.05727697679577842\n",
+            "Step 5: cost = -0.2634812508449048\n",
+            "Step 10: cost = -0.4273918853317506\n",
+            "Step 15: cost = -0.47261597484185947\n",
+            "Step 20: cost = -0.4840689974053044\n",
+            "Step 25: cost = -0.48946413443470116\n",
+            "Step 30: cost = -0.4928187788475247\n",
+            "Step 35: cost = -0.4949493282586438\n",
+            "Step 40: cost = -0.49627038768697207\n",
+            "Step 45: cost = -0.4970720262026469\n"
+          ]
+        }
+      ],
+      "source": [
+        "cost = lambda: disc_cost(disc_weights)\n",
+        "\n",
+        "for step in range(50):\n",
+        "    opt.minimize(cost, disc_weights)\n",
+        "    if step % 5 == 0:\n",
+        "        cost_val = cost().numpy()\n",
+        "        print(\"Step {}: cost = {}\".format(step, cost_val))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "dbm3F7-IB4_J"
+      },
+      "source": [
+        "At the discriminator's optimum, the probability for the discriminator to\n",
+        "correctly classify the real data should be close to one.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 29,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "URMw-4uBB4_J",
+        "outputId": "7ae5da96-8568-4153-d0cd-6d59221a84a2"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Prob(real classified as real):  0.9985872751209892\n"
+          ]
+        }
+      ],
+      "source": [
+        "print(\"Prob(real classified as real): \", prob_real_true(disc_weights).numpy())"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "7GO0YwksB4_J"
+      },
+      "source": [
+        "For comparison, we check how the discriminator classifies the\n",
+        "generator's (still unoptimized) fake data:\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 30,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "b4pWtXVHB4_J",
+        "outputId": "7a121edf-6a5e-4641-8bac-8439950ee10b"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Prob(fake classified as real):  0.5011127803383656\n"
+          ]
+        }
+      ],
+      "source": [
+        "print(\"Prob(fake classified as real): \", prob_fake_true(gen_weights, disc_weights).numpy())"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "JGr9atT9B4_J"
+      },
+      "source": [
+        "In the adversarial game we now have to train the generator to better\n",
+        "fool the discriminator. For this demo, we only perform one stage of the\n",
+        "game. For more complex models, we would continue training the models in\n",
+        "an alternating fashion until we reach the optimum point of the\n",
+        "two-player adversarial game.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 31,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "NVrGCFK5B4_J",
+        "outputId": "39db9092-333e-46f1-bb2d-2d005b37ce50"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Step 0: cost = -0.5833387118384104\n",
+            "Step 5: cost = -0.8915733598437307\n",
+            "Step 10: cost = -0.9784243532819915\n",
+            "Step 15: cost = -0.9946483809432042\n",
+            "Step 20: cost = -0.9984996426172494\n",
+            "Step 25: cost = -0.9995638464006635\n",
+            "Step 30: cost = -0.9998717844534688\n",
+            "Step 35: cost = -0.9999621462112331\n",
+            "Step 40: cost = -0.999988801241847\n",
+            "Step 45: cost = -0.9999966825023898\n"
+          ]
+        }
+      ],
+      "source": [
+        "cost = lambda: gen_cost(gen_weights)\n",
+        "\n",
+        "for step in range(50):\n",
+        "    opt.minimize(cost, gen_weights)\n",
+        "    if step % 5 == 0:\n",
+        "        cost_val = cost().numpy()\n",
+        "        print(\"Step {}: cost = {}\".format(step, cost_val))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "0K59ud11B4_J"
+      },
+      "source": [
+        "At the optimum of the generator, the probability for the discriminator\n",
+        "to be fooled should be close to 1.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 32,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "4_3Co4HYB4_J",
+        "outputId": "194fbb89-5379-43a7-a4b8-f765d2d2881e"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Prob(fake classified as real):  0.9999987450417567\n"
+          ]
+        }
+      ],
+      "source": [
+        "print(\"Prob(fake classified as real): \", prob_fake_true(gen_weights, disc_weights).numpy())"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "uJR4z50uB4_J"
+      },
+      "source": [
+        "At the joint optimum the discriminator cost will be close to zero,\n",
+        "indicating that the discriminator assigns equal probability to both real\n",
+        "and generated data.\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 33,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "byWE_IY1B4_J",
+        "outputId": "27ddbb17-239c-47f4-d22c-7621b0f5b62e"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Discriminator cost:  0.0014114699207674608\n"
+          ]
+        }
+      ],
+      "source": [
+        "print(\"Discriminator cost: \", disc_cost(disc_weights).numpy())"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "Ubhr8ZSsB4_J"
+      },
+      "source": [
+        "The generator has successfully learned how to simulate the real data\n",
+        "enough to fool the discriminator.\n",
+        "\n",
+        "Let\\'s conclude by comparing the states of the real data circuit and the\n",
+        "generator. We expect the generator to have learned to be in a state that\n",
+        "is very close to the one prepared in the real data circuit. An easy way\n",
+        "to access the state of the first qubit is through its [Bloch\n",
+        "sphere](https://en.wikipedia.org/wiki/Bloch_sphere) representation:\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 34,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "QZ2TkvG4B4_J",
+        "outputId": "e7baea95-a783-472c-d4b6-a71e4813d232"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Real Bloch vector: [<tf.Tensor: shape=(), dtype=float64, numpy=-0.21694186955877895>, <tf.Tensor: shape=(), dtype=float64, numpy=0.4504844339512096>, <tf.Tensor: shape=(), dtype=float64, numpy=-0.8660254037844386>]\n",
+            "Generator Bloch vector: [<tf.Tensor: shape=(), dtype=float64, numpy=-0.2840466575634104>, <tf.Tensor: shape=(), dtype=float64, numpy=0.4189322684453221>, <tf.Tensor: shape=(), dtype=float64, numpy=-0.8624441484467279>]\n"
+          ]
+        }
+      ],
+      "source": [
+        "obs = [qml.PauliX(0), qml.PauliY(0), qml.PauliZ(0)]\n",
+        "\n",
+        "@qml.qnode(dev, interface=\"tf\")\n",
+        "def bloch_vector_real(angles):\n",
+        "    real(angles)\n",
+        "    return [qml.expval(o) for o in obs]\n",
+        "\n",
+        "@qml.qnode(dev, interface=\"tf\")\n",
+        "def bloch_vector_generator(angles):\n",
+        "    generator(angles)\n",
+        "    return [qml.expval(o) for o in obs]\n",
+        "\n",
+        "print(f\"Real Bloch vector: {bloch_vector_real([phi, theta, omega])}\")\n",
+        "print(f\"Generator Bloch vector: {bloch_vector_generator(gen_weights)}\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "zAlOXLekB4_K"
+      },
+      "source": [
+        "About the author\n",
+        "================\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "seconds = time.time()\n",
+        "print(\"Time in seconds since end of run:\", seconds)\n",
+        "local_time = time.ctime(seconds)\n",
+        "print(local_time)"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 0
+        },
+        "id": "lypK7PwdDujD",
+        "outputId": "13d3f482-54c1-4dc9-c98f-ab9a44f2c9ab"
+      },
+      "execution_count": 35,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Time in seconds since end of run: 1700611277.3444774\n",
+            "Wed Nov 22 00:01:17 2023\n"
+          ]
+        }
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.17"
+    },
+    "colab": {
+      "provenance": [],
+      "machine_shape": "hm",
+      "gpuType": "A100"
+    },
+    "accelerator": "GPU"
+  },
+  "nbformat": 4,
+  "nbformat_minor": 0
+}