Quantum AI for Psychiatric Diagnosis: Enhancing Dementia Classification with Quantum Machine Learning

📥 Download Project ZIP

Aap neeche diye gaye button par click kar ke poora code ZIP file format mein download kar sakte hain:

🧠 Dementia Classification with Quantum + Knowledge Distillation


# -------------------------------
# SETTINGS & PATHS
# -------------------------------
IMG_SIZE = (28, 28)
ROI_SIZE = (14, 14)
TEST_SPLIT = 0.2
N_WIRES = 2
N_LAYERS = 1

os.makedirs(OUTPUT_DIR, exist_ok=True)

# -------------------------------
# DEVICE SETUP
# -------------------------------
print("TensorFlow GPU devices:", tf.config.list_physical_devices('GPU'))

quantum_device = qml.device("default.qubit", wires=N_WIRES)
rand_params = np.random.uniform(high=2*np.pi, size=(N_LAYERS, N_WIRES))

# -------------------------------
# LOAD DATASET
# -------------------------------
def load_images_from_folder(folder_path):
    images, labels = [], []
    class_names = sorted([c for c in os.listdir(folder_path) if os.path.isdir(os.path.join(folder_path, c))])
    class_map = {c: i for i, c in enumerate(class_names)}
    for class_name in class_names:
        class_dir = os.path.join(folder_path, class_name)
        for img_name in os.listdir(class_dir):
            img_path = os.path.join(class_dir, img_name)
            if os.path.isfile(img_path) and img_path.lower().endswith(('.png','.jpg','.jpeg')):
                img = load_img(img_path, target_size=IMG_SIZE, color_mode="grayscale")
                img_array = img_to_array(img)/255.0
                images.append(img_array)
                labels.append(class_map[class_name])
    return np.array(images), np.array(labels), class_names

# -------------------------------
# QUANTUM CIRCUIT
# -------------------------------
@qml.qnode(quantum_device)
def quantum_circuit(inputs):
    for j in range(N_WIRES):
        qml.RY(np.pi*inputs[j % len(inputs)], wires=j)
    RandomLayers(rand_params, wires=list(range(N_WIRES)))
    return [qml.expval(qml.PauliZ(j)) for j in range(N_WIRES)]

def quantum_convolution(patch):
    out_h, out_w = ROI_SIZE[0]//2, ROI_SIZE[1]//2
    out = np.zeros((out_h, out_w, N_WIRES))
    for i in range(0, ROI_SIZE[0], 2):
        for j in range(0, ROI_SIZE[1], 2):
            patch_vals = [
                patch[i, j, 0],
                patch[i, j+1, 0],
                patch[i+1, j, 0],
                patch[i+1, j+1, 0]
            ]
            out[i//2, j//2, :] = quantum_circuit(patch_vals)
    return out

def quantum_on_roi(image):
    start = (IMG_SIZE[0]-ROI_SIZE[0])//2
    end = start + ROI_SIZE[0]
    roi = image[start:end, start:end, :]
    return quantum_convolution(roi)

# -------------------------------
# MODELS
# -------------------------------
def make_teacher(num_classes):
    return tf.keras.Sequential([
        tf.keras.layers.Conv2D(128, (3,3), padding='same', input_shape=(ROI_SIZE[0]//2, ROI_SIZE[1]//2, N_WIRES)),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.ReLU(),
        tf.keras.layers.MaxPooling2D((2,2), padding='same'),

        tf.keras.layers.Conv2D(256, (3,3), padding='same'),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.ReLU(),
        tf.keras.layers.GlobalAveragePooling2D(),

        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(512, activation='relu'),
        tf.keras.layers.Dropout(0.3),
        tf.keras.layers.Dense(num_classes, activation='softmax')
    ])

def make_student(num_classes):
    return tf.keras.Sequential([
        tf.keras.layers.Conv2D(64, (3,3), padding='same', input_shape=(ROI_SIZE[0]//2, ROI_SIZE[1]//2, N_WIRES)),
        tf.keras.layers.ReLU(),
        tf.keras.layers.MaxPooling2D((2,2), padding='same'),

        tf.keras.layers.Conv2D(128, (3,3), padding='same'),
        tf.keras.layers.ReLU(),
        tf.keras.layers.GlobalAveragePooling2D(),

        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dense(num_classes, activation='softmax')
    ])

# -------------------------------
# Distillation wrapper
# -------------------------------
class Distiller(tf.keras.Model):
    def __init__(self, student, teacher, alpha=0.5, temperature=5):
        super().__init__()
        self.student = student
        self.teacher = teacher
        self.alpha = alpha
        self.temperature = temperature

    def compile(self, optimizer, metrics, student_loss_fn, distillation_loss_fn):
        super().compile(optimizer=optimizer, metrics=metrics)
        self.student_loss_fn = student_loss_fn
        self.distillation_loss_fn = distillation_loss_fn

    def train_step(self, data):
        x, y = data
        teacher_preds = self.teacher(x, training=False)
        with tf.GradientTape() as tape:
            student_preds = self.student(x, training=True)
            student_loss = self.student_loss_fn(y, student_preds)
            distill_loss = self.distillation_loss_fn(
                tf.nn.softmax(teacher_preds/self.temperature, axis=1),
                tf.nn.softmax(student_preds/self.temperature, axis=1)
            )
            loss = self.alpha * student_loss + (1 - self.alpha) * distill_loss
        grads = tape.gradient(loss, self.student.trainable_variables)
        self.optimizer.apply_gradients(zip(grads, self.student.trainable_variables))
        self.compiled_metrics.update_state(y, student_preds)
        results = {m.name: m.result() for m in self.metrics}
        results.update({"loss": loss})
        return results

    def test_step(self, data):
        x, y = data
        student_preds = self.student(x, training=False)
        student_loss = self.student_loss_fn(y, student_preds)
        self.compiled_metrics.update_state(y, student_preds)
        results = {m.name: m.result() for m in self.metrics}
        results.update({"loss": student_loss})
        return results

# -------------------------------
# TRAINING + EVAL
# -------------------------------
for dataset_path in DATASET_DIRS:
    dataset_name = os.path.basename(dataset_path)
    save_dir = os.path.join(OUTPUT_DIR, dataset_name)
    os.makedirs(save_dir, exist_ok=True)

    print(f"\n Loading dataset: {dataset_name}")
    images, labels, class_names = load_images_from_folder(dataset_path)
    num_classes = len(class_names)

    train_images, test_images, train_labels, test_labels = train_test_split(
        images, labels, test_size=TEST_SPLIT, stratify=labels, random_state=42
    )
    train_images = train_images.reshape(-1, IMG_SIZE[0], IMG_SIZE[1], 1)
    test_images = test_images.reshape(-1, IMG_SIZE[0], IMG_SIZE[1], 1)

    print(" Applying quantum convolution on ROI...")
    q_train_images = np.array([quantum_on_roi(img) for img in train_images])
    q_test_images = np.array([quantum_on_roi(img) for img in test_images])

    # Train teacher
    teacher = make_teacher(num_classes)
    teacher.compile(optimizer=tf.keras.optimizers.Adam(1e-4),
                    loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    teacher.fit(q_train_images, train_labels,
                validation_data=(q_test_images, test_labels),
                epochs=100, batch_size=32, verbose=2)
    teacher.save(os.path.join(save_dir, "teacher.h5"))

    # Train student with KD
    student = make_student(num_classes)
    distiller = Distiller(student, teacher, alpha=0.5, temperature=5)
    distiller.compile(
        optimizer=tf.keras.optimizers.Adam(1e-4),
        metrics=["accuracy"],
        student_loss_fn=tf.keras.losses.SparseCategoricalCrossentropy(),
        distillation_loss_fn=tf.keras.losses.KLDivergence()
    )
    history = distiller.fit(q_train_images, train_labels,
                            validation_data=(q_test_images, test_labels),
                            epochs=100, batch_size=32, verbose=2)
    student.save(os.path.join(save_dir, "student_kd.h5"))

    # ---------------- Predictions ----------------
    y_prob = student.predict(q_test_images)
    y_pred = np.argmax(y_prob, axis=1)

    # Confusion Matrix, Classification Report, ROC, Training Plots ...
    # (same as your given code)

🧠 Dementia Classification with Quantum without Knowledge Distillation


import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import img_to_array, load_img
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
import matplotlib.pyplot as plt
import seaborn as sns
import pennylane as qml
from pennylane.templates import RandomLayers

# -------------------------------
# SETTINGS & PATHS
# -------------------------------
IMG_SIZE = (28, 28)
ROI_SIZE = (14, 14)
TEST_SPLIT = 0.2
N_WIRES = 2
N_LAYERS = 1
OUTPUT_DIR = r"E:/javeria/output"
DATA_PATH = r"E:/ADNI1/ADNI-1"

os.makedirs(OUTPUT_DIR, exist_ok=True)

# -------------------------------
# DEVICE SETUP
# -------------------------------
print("TensorFlow GPU devices:", tf.config.list_physical_devices('GPU'))

# Quantum CPU backend
quantum_device = qml.device("default.qubit", wires=N_WIRES)
rand_params = np.random.uniform(high=2*np.pi, size=(N_LAYERS, N_WIRES))

# -------------------------------
# LOAD DATASET
# -------------------------------
def load_images_from_folder(folder_path):
    images, labels = [], []
    class_names = sorted(os.listdir(folder_path))
    class_map = {c: i for i, c in enumerate(class_names)}
    for class_name in class_names:
        class_dir = os.path.join(folder_path, class_name)
        if not os.path.isdir(class_dir):
            continue
        for img_name in os.listdir(class_dir):
            img_path = os.path.join(class_dir, img_name)
            if os.path.isfile(img_path) and img_path.lower().endswith(('.png','.jpg','.jpeg')):
                img = load_img(img_path, target_size=IMG_SIZE, color_mode="grayscale")
                img_array = img_to_array(img)/255.0
                images.append(img_array)
                labels.append(class_map[class_name])
    return np.array(images), np.array(labels), class_names

# -------------------------------
# QUANTUM CIRCUIT
# -------------------------------
@qml.qnode(quantum_device)
def quantum_circuit(inputs):
    for j in range(N_WIRES):
        qml.RY(np.pi*inputs[j], wires=j)
    RandomLayers(rand_params, wires=list(range(N_WIRES)))
    return [qml.expval(qml.PauliZ(j)) for j in range(N_WIRES)]

def quantum_convolution(patch):
    out_h, out_w = ROI_SIZE[0]//2, ROI_SIZE[1]//2
    out = np.zeros((out_h, out_w, N_WIRES))
    for i in range(0, ROI_SIZE[0], 2):
        for j in range(0, ROI_SIZE[1], 2):
            patch_vals = [
                patch[i, j, 0],
                patch[i, j+1, 0],
                patch[i+1, j, 0],
                patch[i+1, j+1, 0]
            ]
            out[i//2, j//2, :] = quantum_circuit(patch_vals)
    return out

def quantum_on_roi(image):
    start = (IMG_SIZE[0]-ROI_SIZE[0])//2
    end = start + ROI_SIZE[0]
    roi = image[start:end, start:end, :]
    return quantum_convolution(roi)

def plot_images(original, quantum, index=0):
    fig, axes = plt.subplots(1, 2, figsize=(8,4))
    axes[0].imshow(original[index].reshape(28,28), cmap="gray")
    axes[0].set_title("Original")
    axes[0].axis("off")
    axes[1].imshow(quantum[index].reshape(ROI_SIZE[0]//2, ROI_SIZE[1]//2, N_WIRES).mean(axis=-1), cmap="inferno")
    axes[1].set_title("Quantum Processed")
    axes[1].axis("off")
    plt.show()

# -------------------------------
# MAIN
# -------------------------------
if __name__ == "__main__":
    print("Loading dataset...")
    images, labels, class_names = load_images_from_folder(DATA_PATH)
    num_classes = len(class_names)
    print(f"Loaded {len(images)} images from {num_classes} classes.")

    train_images, test_images, train_labels, test_labels = train_test_split(
        images, labels, test_size=TEST_SPLIT, stratify=labels, random_state=42
    )
    train_images = train_images.reshape(-1, IMG_SIZE[0], IMG_SIZE[1], 1)
    test_images = test_images.reshape(-1, IMG_SIZE[0], IMG_SIZE[1], 1)

    print("Applying quantum convolution on ROI...")
    q_train_images = np.array([quantum_on_roi(img) for img in train_images])
    q_test_images = np.array([quantum_on_roi(img) for img in test_images])

    # Sample plot
    plot_images(train_images, q_train_images, index=0)

    # -------------------------------
    # CNN MODEL
    # -------------------------------
    model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(32, (3,3), activation='relu', padding='same',
                               input_shape=(ROI_SIZE[0]//2, ROI_SIZE[1]//2, N_WIRES)),
        tf.keras.layers.MaxPooling2D((2,2), padding='same'),
        tf.keras.layers.Conv2D(64, (3,3), activation='relu', padding='same'),
        tf.keras.layers.MaxPooling2D((2,2), padding='same'),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dense(num_classes, activation='softmax')
    ])

    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True, verbose=1)
    history = model.fit(q_train_images, train_labels,
                        validation_data=(q_test_images, test_labels),
                        epochs=50, batch_size=32,
                        callbacks=[early_stopping],
                        verbose=2)

    # Save model
    model.save(os.path.join(OUTPUT_DIR, "quantum_cpu_cnn_gpu.h5"))
    print("Model saved!")

    # -------------------------------
    # Confusion matrix & classification report
    # -------------------------------
    y_pred = np.argmax(model.predict(q_test_images), axis=1)
    conf_matrix = confusion_matrix(test_labels, y_pred)
    plt.figure(figsize=(8,6))
    sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=class_names, yticklabels=class_names)
    plt.xlabel("Predicted")
    plt.ylabel("Actual")
    plt.title("Confusion Matrix")
    plt.savefig(os.path.join(OUTPUT_DIR,"confusion_matrix.png"), bbox_inches="tight", dpi=300)
    plt.close()
    print("Confusion matrix saved!")

    report = classification_report(test_labels, y_pred, target_names=class_names, output_dict=True)
    import json
    with open(os.path.join(OUTPUT_DIR,"classification_report.json"), "w") as f:
        json.dump(report, f, indent=4)
    print("Classification report saved!")

0 Comments