QGAN_Project / vGe0.1 /Foptimize_quantum_kernel.py
1bnjmn3's picture
Add files using upload-large-folder tool
0f755ec verified
import numpy as np
import os
import time
# --- M1 OPTIMIZATIONS ---
os.environ["OMP_NUM_THREADS"] = "4"
os.environ["QISKIT_IN_PARALLEL"] = "TRUE"
from sklearn.svm import SVC
from sklearn.metrics import roc_auc_score
from qiskit.circuit import ParameterVector
from qiskit.circuit.library import ZZFeatureMap, RealAmplitudes
from qiskit_machine_learning.kernels import TrainableFidelityQuantumKernel
from qiskit_machine_learning.utils.loss_functions import SVCLoss
from qiskit_algorithms.optimizers import COBYLA
from qiskit_aer import AerSimulator
# --- CONFIGURATION ---
N_QUBITS = 8
TRAIN_SIZE = 150 # Smaller subset for alignment (speed) now 150 for even faster
TEST_SIZE = 300
MAX_ITERS = 50 # Optimization steps
OUTPUT_DIR = "optimized_kernel_results"
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
def main():
print(f"πŸš€ Starting Quantum Kernel Optimization (QKA)...")
print(" Goal: Calculate optimal kernel geometry instead of guessing.")
# 1. LOAD DATA
possible_paths = ['vG.0.1/qgan_data_optimized.npz', 'qgan_data_optimized.npz']
data_path = next((p for p in possible_paths if os.path.exists(p)), None)
if not data_path:
print("❌ Error: qgan_data_optimized.npz not found.")
return
data = np.load(data_path)
X_train_full = data['X_train']
y_train_full = data['y_train']
X_test_full = data['X_test']
y_test_full = data['y_test']
# 2. SUBSAMPLE (Balanced)
pos_idx = np.where(y_train_full == 1)[0]
neg_idx = np.where(y_train_full == 0)[0]
train_idx = np.concatenate([
np.random.choice(pos_idx, TRAIN_SIZE // 2, replace=False),
np.random.choice(neg_idx, TRAIN_SIZE // 2, replace=False)
])
np.random.shuffle(train_idx)
X_train = X_train_full[train_idx]
y_train = y_train_full[train_idx]
X_test = X_test_full[:TEST_SIZE]
y_test = y_test_full[:TEST_SIZE]
print(f" πŸ“Š Training Alignment on {len(X_train)} samples...")
# 3. DEFINE TRAINABLE FEATURE MAP
# Circuit = Data Encoding (ZZ) + Trainable Rotation (RealAmplitudes)
# This acts as a "Quantum Lens" that the optimizer focuses.
print(" βš›οΈ Initializing Trainable Kernel...")
fm = ZZFeatureMap(N_QUBITS, reps=2, entanglement='linear')
ansatz = RealAmplitudes(N_QUBITS, reps=1)
combined_circuit = fm.compose(ansatz)
# FIX: Only pass the training_parameters.
# The class automatically infers that the other params (fm.parameters) are data inputs.
quant_kernel = TrainableFidelityQuantumKernel(
feature_map=combined_circuit,
training_parameters=ansatz.parameters
)
# 4. OPTIMIZE KERNEL (ALIGNMENT)
print(" 🧠 Optimizing Kernel Geometry (COBYLA)...")
# SVCLoss minimizes the classification error of the kernel
loss_func = SVCLoss(C=1.0, gamma='auto')
optimizer = COBYLA(maxiter=MAX_ITERS)
from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer
trainer = QuantumKernelTrainer(
quantum_kernel=quant_kernel,
loss=loss_func,
optimizer=optimizer,
initial_point=[0.1] * len(ansatz.parameters)
)
start_time = time.time()
# Train the Kernel parameters
results = trainer.fit(X_train, y_train)
print(f" βœ… Optimization Complete in {time.time() - start_time:.1f}s")
print(f" 🎯 Final Loss: {results.optimal_value:.4f}")
# 5. RUN FINAL SVC WITH OPTIMIZED KERNEL
print(" πŸ† Training Final SVM with Optimized Kernel...")
optimized_kernel = results.quantum_kernel
# We use the optimized kernel to fit the full SVM
qsvc = SVC(kernel=optimized_kernel.evaluate, probability=True)
qsvc.fit(X_train, y_train)
# Evaluate
test_probs = qsvc.predict_proba(X_test)[:, 1]
test_auc = roc_auc_score(y_test, test_probs)
print("\n" + "="*40)
print("πŸš€ OPTIMIZED QUANTUM KERNEL RESULTS")
print("="*40)
print(f"βœ… Test AUC: {test_auc:.4f}")
print(f"πŸ“‰ Linear Base: 0.7500")
print("="*40)
# Check if we beat the baseline
if test_auc > 0.75:
print("πŸŽ‰ SUCCESS: Optimization found a better topology than brute force.")
np.save(f"{OUTPUT_DIR}/optimized_weights.npy", results.optimal_point)
else:
print("πŸ”Έ Result: Optimization matched or slightly underperformed baseline.")
if __name__ == "__main__":
main()