Launch the interactive walkthrough to discover each component, including the 3D Q-Sphere Lab & Python in Colab.
Synthesize Module 8: integrate a Quantum Circuit as a PyTorch layer inside a Deep Convolutional Neural Network (Hybrid Quantum Transfer Learning).
torch.nn.Module with analytical parameter-shift gradient integration.Interactive 3D state vector exploration, unitary transformation gates, and Born rule collapse for Topic 8.10
| Symbol / Term | Meaning | Beginner Interpretation |
|---|---|---|
| Classical neural network weights | Convolutional filter weights or linear layer parameters | |
| Quantum circuit rotation parameters | Angles driven by classical features | |
| Quantum measurement expectation | Output scalar passed from QPU to classical output layer | |
| Quantum parameter-shift gradient | Evaluated using two circuit executions on QPU |
Tracing end-to-end backpropagation through a hybrid PyTorch-Qiskit model: Loss -> Quantum Layer -> Classical Dense Layer:
Result: The classical weight receives an exact end-to-end gradient update of -0.7143, updating classical and quantum parameters simultaneously.
ResNet/CNN processes raw input image and outputs compact feature vector x (e.g. 4 numbers).
Angle encoding loads x into 4 qubits; variational ansatz rotates state.
Z-measurement yields continuous output scalar.
PyTorch autograd computes classical gradients and calls parameter-shift for quantum gradients, updating all weights in a single step.
Problem: Classifying pneumonia vs COVID-19 in small clinical sample sizes.
Solution: Hybrid ResNet-QNN models achieved higher sample efficiency on small datasets than purely classical deep networks.
Interactive activity component
Construct a hybrid neural network connecting PyTorch Linear layers with an EstimatorQNN quantum layer via TorchConnector, and train end-to-end on the make_moons classification dataset.
For Google Colab or Jupyter notebooks, run this shell command to install the required dependencies:
!pip install qiskit qiskit-machine-learning torch scikit-learn numpy1 import torch 2 import torch.nn as nn 3 import torch.optim as optim 4 from sklearn.datasets import make_moons 5 from sklearn.model_selection import train_test_split 6 from sklearn.preprocessing import StandardScaler 7 from qiskit.primitives import StatevectorEstimator 8 from qiskit.circuit.library import RealAmplitudes 9 from qiskit_machine_learning.neural_networks import EstimatorQNN 10 from qiskit_machine_learning.connectors import TorchConnector
import torch → PyTorch deep learning framework
import torch.nn as nn → PyTorch neural network modules
import torch.optim as optim → Adam optimization solver
from sklearn.datasets import make_moons → Non-linear synthetic moon dataset
from sklearn.model_selection import train_test_split → Dataset split utility
from sklearn.preprocessing import StandardScaler → Feature standardization
from qiskit.primitives import StatevectorEstimator → Statevector expectation estimator
from qiskit.circuit.library import RealAmplitudes → Parameterized quantum circuit ansatz
from qiskit_machine_learning.neural_networks import EstimatorQNN → Differentiable Quantum Neural Network
from qiskit_machine_learning.connectors import TorchConnector → PyTorch layer wrapper for QNN
1 # Step 1: Generate and Preprocess Moons Dataset 2 X, y = make_moons(n_samples=100, noise=0.1, random_state=42) 3 scaler = StandardScaler() 4 X_scaled = scaler.fit_transform(X) 5 X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42) 6 X_train_torch = torch.tensor(X_train, dtype=torch.float32) 7 X_test_torch = torch.tensor(X_test, dtype=torch.float32) 8 y_train_torch = torch.tensor(y_train, dtype=torch.long) 9 y_test_torch = torch.tensor(y_test, dtype=torch.long) 10 11 # Step 2: Define Parameterized Quantum Circuit (RealAmplitudes) 12 num_qubits = 2 13 quantum_circuit = RealAmplitudes(num_qubits, reps=3) 14 15 # Step 3: Wrap Quantum Circuit into EstimatorQNN and TorchConnector 16 estimator = StatevectorEstimator() 17 qnn = EstimatorQNN( 18 circuit=quantum_circuit, 19 estimator=estimator, 20 input_params=quantum_circuit.parameters[:2], 21 weight_params=quantum_circuit.parameters[2:] 22 ) 23 quantum_layer = TorchConnector(qnn) # Differentiable PyTorch layer 24 25 # Step 4: Define Hybrid Classical-Quantum PyTorch Architecture 26 class HybridQuantumNN(nn.Module): 27 def __init__(self): 28 super(HybridQuantumNN, self).__init__() 29 self.fc1 = nn.Linear(2, 2) 30 self.quantum = quantum_layer 31 self.fc2 = nn.Linear(1, 2) 32 def forward(self, x): 33 x = torch.tanh(self.fc1(x)) 34 x = self.quantum(x) 35 x = self.fc2(x) 36 return x 37 38 # Step 5: Train Hybrid Model with CrossEntropyLoss and Adam 39 model = HybridQuantumNN() 40 criterion = nn.CrossEntropyLoss() 41 optimizer = optim.Adam(model.parameters(), lr=0.01) 42 for epoch in range(20): 43 optimizer.zero_grad() 44 outputs = model(X_train_torch) 45 loss = criterion(outputs, y_train_torch) 46 loss.backward() 47 optimizer.step() 48 49 # Step 6: Evaluate Test Accuracy 50 with torch.no_grad(): 51 y_pred = model(X_test_torch).argmax(dim=1) 52 accuracy = (y_pred == y_test_torch).float().mean() 53 print(f"Test Accuracy: {accuracy * 100:.2f}%")
# Step 1: Generate and Preprocess Moons Dataset
Data loading
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
Non-linear 2D moon data
scaler = StandardScaler()
Instantiate scaler
X_scaled = scaler.fit_transform(X)
Scale features
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
80/20 train/test split
X_train_torch = torch.tensor(X_train, dtype=torch.float32)
PyTorch train tensor
X_test_torch = torch.tensor(X_test, dtype=torch.float32)
PyTorch test tensor
y_train_torch = torch.tensor(y_train, dtype=torch.long)
Train labels tensor
y_test_torch = torch.tensor(y_test, dtype=torch.long)
Test labels tensor
# Step 2: Define Parameterized Quantum Circuit (RealAmplitudes)
Quantum circuit
num_qubits = 2
2 qubits
quantum_circuit = RealAmplitudes(num_qubits, reps=3)
RealAmplitudes ansatz with 3 layers
# Step 3: Wrap Quantum Circuit into EstimatorQNN and TorchConnector
QNN wrapping
estimator = StatevectorEstimator()
StatevectorEstimator primitive
qnn = EstimatorQNN(
EstimatorQNN
circuit=quantum_circuit,
Variational circuit
estimator=estimator,
Estimator primitive
input_params=quantum_circuit.parameters[:2],
First 2 params as data inputs
weight_params=quantum_circuit.parameters[2:]
Remaining params as trainable weights
)
Instantiate QNN
quantum_layer = TorchConnector(qnn) # Differentiable PyTorch layer
PyTorch connector layer
# Step 4: Define Hybrid Classical-Quantum PyTorch Architecture
Hybrid model
class HybridQuantumNN(nn.Module):
Subclass nn.Module
def __init__(self):
Constructor
super(HybridQuantumNN, self).__init__()
Base init
self.fc1 = nn.Linear(2, 2)
Classical input layer
self.quantum = quantum_layer
Quantum layer co-processor
self.fc2 = nn.Linear(1, 2)
Classical classification head
def forward(self, x):
Forward computation
x = torch.tanh(self.fc1(x))
Classical feature transformation
x = self.quantum(x)
Quantum expectation pass
x = self.fc2(x)
Final class logits
return x
Return output
# Step 5: Train Hybrid Model with CrossEntropyLoss and Adam
Training loop
model = HybridQuantumNN()
Instantiate hybrid network
criterion = nn.CrossEntropyLoss()
Loss function
optimizer = optim.Adam(model.parameters(), lr=0.01)
Adam optimizer
for epoch in range(20):
Train for 20 epochs
optimizer.zero_grad()
Clear gradients
outputs = model(X_train_torch)
Forward pass
loss = criterion(outputs, y_train_torch)
Compute loss
loss.backward()
End-to-end backprop
optimizer.step()
Update classical + quantum weights
# Step 6: Evaluate Test Accuracy
Inference & test
with torch.no_grad():
Inference mode
y_pred = model(X_test_torch).argmax(dim=1)
Predicted test classes
accuracy = (y_pred == y_test_torch).float().mean()
Calculate accuracy
print(f"Test Accuracy: {accuracy * 100:.2f}%")
Display final accuracy
Click "Copy for Colab", open Google Colab, paste into a single cell, and run.
1 # ========================================================= 2 # Hybrid Quantum-Classical Neural Network with PyTorch & EstimatorQNN 3 # Prepared for Google Colab (Run with Shift + Enter) 4 # ========================================================= 5 6 # Step 1: Install required packages 7 !pip install qiskit qiskit-machine-learning torch scikit-learn numpy 8 9 # Step 2: Import libraries 10 import torch 11 import torch.nn as nn 12 import torch.optim as optim 13 from sklearn.datasets import make_moons 14 from sklearn.model_selection import train_test_split 15 from sklearn.preprocessing import StandardScaler 16 from qiskit.primitives import StatevectorEstimator 17 from qiskit.circuit.library import RealAmplitudes 18 from qiskit_machine_learning.neural_networks import EstimatorQNN 19 from qiskit_machine_learning.connectors import TorchConnector 20 21 # Step 3: Run Demonstration 22 # Step 1: Generate and Preprocess Moons Dataset 23 X, y = make_moons(n_samples=100, noise=0.1, random_state=42) 24 scaler = StandardScaler() 25 X_scaled = scaler.fit_transform(X) 26 X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42) 27 X_train_torch = torch.tensor(X_train, dtype=torch.float32) 28 X_test_torch = torch.tensor(X_test, dtype=torch.float32) 29 y_train_torch = torch.tensor(y_train, dtype=torch.long) 30 y_test_torch = torch.tensor(y_test, dtype=torch.long) 31 32 # Step 2: Define Parameterized Quantum Circuit (RealAmplitudes) 33 num_qubits = 2 34 quantum_circuit = RealAmplitudes(num_qubits, reps=3) 35 36 # Step 3: Wrap Quantum Circuit into EstimatorQNN and TorchConnector 37 estimator = StatevectorEstimator() 38 qnn = EstimatorQNN( 39 circuit=quantum_circuit, 40 estimator=estimator, 41 input_params=quantum_circuit.parameters[:2], 42 weight_params=quantum_circuit.parameters[2:] 43 ) 44 quantum_layer = TorchConnector(qnn) # Differentiable PyTorch layer 45 46 # Step 4: Define Hybrid Classical-Quantum PyTorch Architecture 47 class HybridQuantumNN(nn.Module): 48 def __init__(self): 49 super(HybridQuantumNN, self).__init__() 50 self.fc1 = nn.Linear(2, 2) 51 self.quantum = quantum_layer 52 self.fc2 = nn.Linear(1, 2) 53 def forward(self, x): 54 x = torch.tanh(self.fc1(x)) 55 x = self.quantum(x) 56 x = self.fc2(x) 57 return x 58 59 # Step 5: Train Hybrid Model with CrossEntropyLoss and Adam 60 model = HybridQuantumNN() 61 criterion = nn.CrossEntropyLoss() 62 optimizer = optim.Adam(model.parameters(), lr=0.01) 63 for epoch in range(20): 64 optimizer.zero_grad() 65 outputs = model(X_train_torch) 66 loss = criterion(outputs, y_train_torch) 67 loss.backward() 68 optimizer.step() 69 70 # Step 6: Evaluate Test Accuracy 71 with torch.no_grad(): 72 y_pred = model(X_test_torch).argmax(dim=1) 73 accuracy = (y_pred == y_test_torch).float().mean() 74 print(f"Test Accuracy: {accuracy * 100:.2f}%")
Wraps Qiskit EstimatorQNN into an autograd-compatible PyTorch layer executing the Parameter Shift Rule during backpropagation.
Classical input features pass through fc1 (Tanh), enter the 2-qubit RealAmplitudes circuit, and output expectation values into fc2.
PyTorch's Adam optimizer simultaneously updates both the classical weight matrices and the quantum gate rotation angles.
100 2D make_moons samples split into 80 train and 20 test tensors
Epoch 10, Loss: 0.4820 Epoch 20, Loss: 0.2941 Test Accuracy: 95.00%
The hybrid quantum-classical neural network successfully demonstrates end-to-end backpropagation through quantum circuits using TorchConnector, achieving high non-linear classification accuracy on complex datasets.
EstimatorQNN, TorchConnector, and hybrid PyTorch deep neural network training pipelines.
Test your understanding with these questions. Remember, this is for learning, not examination!