{ "cells": [ { "cell_type": "markdown", "id": "7cb6709b", "metadata": {}, "source": [ "# 17 - Quantum Machine Learning\n", "\n", "Build a simple parameterized quantum circuit for binary classification.\n", "\n", "**Concepts:** Data encoding, parameterized gates, measurement-based prediction" ] }, { "cell_type": "code", "execution_count": null, "id": "6cc319be", "metadata": {}, "outputs": [], "source": [ "import quantsdk as qs\n", "import math\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "7a9fd613", "metadata": {}, "source": [ "## Quantum Classifier\n", "\n", "1. **Encode** classical data as rotation angles\n", "2. **Process** with parameterized layers\n", "3. **Measure** to get a classification" ] }, { "cell_type": "code", "execution_count": null, "id": "5dde4fe2", "metadata": {}, "outputs": [], "source": [ "def quantum_classifier(x: list, weights: list) -> qs.Circuit:\n", " \"\"\"2-qubit quantum classifier.\n", " \n", " Args:\n", " x: Input features [x0, x1].\n", " weights: Trainable parameters [w0, w1, w2, w3].\n", " \"\"\"\n", " circuit = qs.Circuit(2, name=\"classifier\")\n", " \n", " # Data encoding layer\n", " circuit.ry(0, x[0] * math.pi)\n", " circuit.ry(1, x[1] * math.pi)\n", " \n", " # Variational layer 1\n", " circuit.ry(0, weights[0])\n", " circuit.ry(1, weights[1])\n", " circuit.cx(0, 1)\n", " \n", " # Variational layer 2\n", " circuit.ry(0, weights[2])\n", " circuit.ry(1, weights[3])\n", " circuit.cx(1, 0)\n", " \n", " circuit.measure(0) # Classification qubit\n", " return circuit\n", "\n", "def predict(x: list, weights: list, shots: int = 1000) -> float:\n", " \"\"\"Return P(class=1) for input x.\"\"\"\n", " circuit = quantum_classifier(x, weights)\n", " result = qs.run(circuit, shots=shots, seed=42)\n", " p1 = 0\n", " for bs, count in result.counts.items():\n", " if bs[0] == '1':\n", " p1 += count\n", " return p1 / shots" ] }, { "cell_type": "code", "execution_count": null, "id": "626bff8e", "metadata": {}, "outputs": [], "source": [ "# Simple XOR-like dataset\n", "data = [\n", " ([0.0, 0.0], 0),\n", " ([0.0, 1.0], 1),\n", " ([1.0, 0.0], 1),\n", " ([1.0, 1.0], 0),\n", "]\n", "\n", "# Random initial weights\n", "np.random.seed(42)\n", "weights = list(np.random.uniform(0, 2 * math.pi, 4))\n", "\n", "print(\"Before training:\")\n", "for x, label in data:\n", " p = predict(x, weights)\n", " pred = 1 if p > 0.5 else 0\n", " print(f\" x={x}, label={label}, P(1)={p:.3f}, pred={pred} {'OK' if pred == label else 'WRONG'}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "c3809e67", "metadata": {}, "outputs": [], "source": [ "# Simple parameter sweep to improve\n", "def loss(weights: list) -> float:\n", " \"\"\"Mean squared error.\"\"\"\n", " total = 0.0\n", " for x, label in data:\n", " p = predict(x, weights)\n", " total += (p - label) ** 2\n", " return total / len(data)\n", "\n", "# Coordinate descent\n", "best_w = list(weights)\n", "best_loss = loss(best_w)\n", "\n", "for iteration in range(3):\n", " for i in range(4):\n", " for delta in np.linspace(-0.5, 0.5, 11):\n", " trial = list(best_w)\n", " trial[i] += delta\n", " l = loss(trial)\n", " if l < best_loss:\n", " best_loss = l\n", " best_w = trial\n", "\n", "print(f\"Optimized loss: {best_loss:.4f}\")\n", "print(f\"\\nAfter training:\")\n", "correct = 0\n", "for x, label in data:\n", " p = predict(x, best_w)\n", " pred = 1 if p > 0.5 else 0\n", " if pred == label: correct += 1\n", " print(f\" x={x}, label={label}, P(1)={p:.3f}, pred={pred} {'OK' if pred == label else 'WRONG'}\")\n", "print(f\"Accuracy: {correct}/{len(data)}\")" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }