{ "cells": [ { "cell_type": "markdown", "id": "equivalent-affiliate", "metadata": {}, "source": [ "# Torch Connector\n", "\n", "This tutorial shows how the `TorchConnector` allows to use any `NeuralNetwork` from Qiskit Machine Learning and integrate it in a PyTorch workflow. The `TorchConnector` takes any `NeuralNetwork` and makes it available as a PyTorch `Module`.\n", "\n", "## Content:\n", "\n", "[Part 1: Simple Classification & Regression](#Part-1:-Simple-Classification-&-Regression)\n", "- Classification\n", " - Classification with PyTorch and the `OpflowQNN`\n", " - Classification with PyTorch and the `CircuitQNN`\n", "- Regression\n", " - Regression with PyTorch and the `OpflowQNN`\n", "\n", "[Part 2: MNIST Classification](#Part-2:-MNIST-Classification)\n", "\n", "Illustrates how to embed a (Quantum) `NeuralNetwork` into a target PyTorch workflow to classify MNIST data." ] }, { "cell_type": "code", "execution_count": 1, "id": "indirect-crime", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "from torch import Tensor\n", "from torch.nn import Linear, CrossEntropyLoss, MSELoss\n", "from torch.optim import LBFGS\n", "\n", "from qiskit import Aer, QuantumCircuit\n", "from qiskit.utils import QuantumInstance\n", "from qiskit.opflow import AerPauliExpectation\n", "from qiskit.circuit import Parameter\n", "from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap\n", "from qiskit_machine_learning.neural_networks import CircuitQNN, TwoLayerQNN\n", "from qiskit_machine_learning.connectors import TorchConnector\n", "\n", "qi = QuantumInstance(Aer.get_backend('statevector_simulator'))" ] }, { "cell_type": "markdown", "id": "interested-laundry", "metadata": {}, "source": [ "# Part 1: Simple Classification & Regression" ] }, { "cell_type": "markdown", "id": "educational-beverage", "metadata": {}, "source": [ "## Classification\n", "\n", "First, we show how the `TorchConnector` can be used to use a Quantum `NeuralNetwork` to solve a classification tasks. Therefore, we generate a simple random data set." ] }, { "cell_type": "code", "execution_count": 2, "id": "stuffed-quantity", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "