{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":39272,"databundleVersionId":4629629,"sourceType":"competition"},{"sourceId":9673918,"sourceType":"datasetVersion","datasetId":5912073},{"sourceId":9685609,"sourceType":"datasetVersion","datasetId":5920767},{"sourceId":9686541,"sourceType":"datasetVersion","datasetId":5921498},{"sourceId":9692914,"sourceType":"datasetVersion","datasetId":5926094}],"dockerImageVersionId":30775,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-10-23T14:33:35.434127Z","iopub.execute_input":"2024-10-23T14:33:35.434519Z","iopub.status.idle":"2024-10-23T14:33:35.439715Z","shell.execute_reply.started":"2024-10-23T14:33:35.434482Z","shell.execute_reply":"2024-10-23T14:33:35.438705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Installation des dépendances (uniquement dans Kaggle)\n!pip install gdcm pylibjpeg pylibjpeg-libjpeg\nimport numpy as np # linear algebra\nimport os\nimport pandas as pd\nimport pydicom\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\n\n\n!pip show gdcm pylibjpeg pylibjpeg-libjpeg","metadata":{"execution":{"iopub.status.busy":"2024-10-24T00:19:00.486005Z","iopub.execute_input":"2024-10-24T00:19:00.486731Z","iopub.status.idle":"2024-10-24T00:19:30.513592Z","shell.execute_reply.started":"2024-10-24T00:19:00.486693Z","shell.execute_reply":"2024-10-24T00:19:30.512319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport seaborn as sns\ndata = pd.read_csv('/kaggle/input/rsna-breast-cancer-detection/train.csv')","metadata":{"execution":{"iopub.status.busy":"2024-10-24T00:19:30.515624Z","iopub.execute_input":"2024-10-24T00:19:30.51632Z","iopub.status.idle":"2024-10-24T00:19:30.969819Z","shell.execute_reply.started":"2024-10-24T00:19:30.516283Z","shell.execute_reply":"2024-10-24T00:19:30.968839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(data.shape)\ndata.head","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.221145Z","iopub.execute_input":"2024-10-23T14:33:41.221474Z","iopub.status.idle":"2024-10-23T14:33:41.237211Z","shell.execute_reply.started":"2024-10-23T14:33:41.221439Z","shell.execute_reply":"2024-10-23T14:33:41.236471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.info","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.239644Z","iopub.execute_input":"2024-10-23T14:33:41.239932Z","iopub.status.idle":"2024-10-23T14:33:41.25154Z","shell.execute_reply.started":"2024-10-23T14:33:41.2399Z","shell.execute_reply":"2024-10-23T14:33:41.250671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.describe","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.2528Z","iopub.execute_input":"2024-10-23T14:33:41.253152Z","iopub.status.idle":"2024-10-23T14:33:41.266797Z","shell.execute_reply.started":"2024-10-23T14:33:41.253109Z","shell.execute_reply":"2024-10-23T14:33:41.265805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in data.columns:\n    print(f\"Valeurs uniques pour '{col}':\")\n    print(data[col].unique())\n    print(data[col].value_counts())\n    print()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.267807Z","iopub.execute_input":"2024-10-23T14:33:41.268066Z","iopub.status.idle":"2024-10-23T14:33:41.342496Z","shell.execute_reply.started":"2024-10-23T14:33:41.268032Z","shell.execute_reply":"2024-10-23T14:33:41.341557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"views = ['CC', 'MLO', 'ML', 'LM', 'AT', 'LMO']\ndf_filtre = data[data['view'].isin(views)].drop_duplicates(subset='view')\n\n# Afficher une image pour chaque type de vue\nfor index, row in df_filtre.iterrows():\n    img_path = row['image_path']  # Chemin vers l'image\n    img = Image.open(img_path)  # Ouvrir l'image\n    plt.imshow(img)  # Afficher l'image\n    plt.title(f\"Vue: {row['view']}\")  # Titre de l'image basé sur la vue\n    plt.axis('off')  # Pas d'axes\n    plt.show()  # Afficher l'image dans une nouvelle fenêtre","metadata":{"execution":{"iopub.status.busy":"2024-10-23T21:25:38.621328Z","iopub.execute_input":"2024-10-23T21:25:38.621679Z","iopub.status.idle":"2024-10-23T21:25:40.222146Z","shell.execute_reply.started":"2024-10-23T21:25:38.621642Z","shell.execute_reply":"2024-10-23T21:25:40.220458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_filtre = data[data['patient_id'] == 52868]\n\n# Afficher les lignes filtrées\nprint(df_filtre)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:46:54.792807Z","iopub.execute_input":"2024-10-23T22:46:54.793652Z","iopub.status.idle":"2024-10-23T22:46:54.805687Z","shell.execute_reply.started":"2024-10-23T22:46:54.793608Z","shell.execute_reply":"2024-10-23T22:46:54.804763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dcm_path = '/kaggle/input/rsna-breast-cancer-detection/train_images/10006/1459541791.dcm'\nimg_1 = pydicom.dcmread(dcm_path)\nprint(img_1)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:46:56.941936Z","iopub.execute_input":"2024-10-23T22:46:56.942641Z","iopub.status.idle":"2024-10-23T22:46:56.952153Z","shell.execute_reply.started":"2024-10-23T22:46:56.942601Z","shell.execute_reply":"2024-10-23T22:46:56.951382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nplt.imshow(img_1.pixel_array)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:46:59.316876Z","iopub.execute_input":"2024-10-23T22:46:59.317234Z","iopub.status.idle":"2024-10-23T22:47:02.290068Z","shell.execute_reply.started":"2024-10-23T22:46:59.317196Z","shell.execute_reply":"2024-10-23T22:47:02.289126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"code pour inverser les couleur d'une image","metadata":{}},{"cell_type":"code","source":"from PIL import Image\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n\n# Accéder aux données de l'image (pixels)\npixel_array = img_1.pixel_array\n\nplt.imshow(pixel_array, cmap=\"gray\")\nplt.show()\n\n# Inverser les valeurs des pixels (pour des images 8 bits, on inverse par rapport à 255)\ninverted_image = np.max(pixel_array) - pixel_array\n\nplt.imshow(inverted_image, cmap=\"gray\")\nplt.show()\n\n\n#inverted_image = Image.eval(img_1, lambda x: 255 - x)\n\n#plt.imshow(inverted_image.pixel_array)\n#plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:49:01.514323Z","iopub.execute_input":"2024-10-23T22:49:01.514691Z","iopub.status.idle":"2024-10-23T22:49:04.385754Z","shell.execute_reply.started":"2024-10-23T22:49:01.514653Z","shell.execute_reply":"2024-10-23T22:49:04.384827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.columns","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.485577Z","iopub.status.idle":"2024-10-23T14:33:41.485954Z","shell.execute_reply.started":"2024-10-23T14:33:41.485747Z","shell.execute_reply":"2024-10-23T14:33:41.485765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\n\n# Obtenir les valeurs uniques d'une colonne spécifique\nvaleurs_machine = data['machine_id'].unique()\nvaleur_patient = data['patient_id']\n\n# Afficher les valeurs uniques\nprint(valeurs_machine)\n\n#selectionner \npremiers_image_ids = data.drop_duplicates(subset='machine_id')[['machine_id', 'image_id']]\n\nfor image in premiers_image_ids:\n    dcm_path = '/kaggle/input/rsna-breast-cancer-detection/train_images/10006/1459541791.dcm'\n    img = pydicom.dcmread(dcm_path)\n    img_array = img.pixel_array\n    print(img_array)\n    plt.imshow(image.pixel_array)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:46:40.44748Z","iopub.execute_input":"2024-10-23T22:46:40.448297Z","iopub.status.idle":"2024-10-23T22:46:41.83544Z","shell.execute_reply.started":"2024-10-23T22:46:40.448241Z","shell.execute_reply":"2024-10-23T22:46:41.834363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\nimport matplotlib.pyplot as plt\n\n# Parcourir chaque 'image_id' et 'patient_id' dans la liste des premiers 'image_id'\nfor index, row in premiers_image_ids.iterrows():\n    image_id = row['image_id']  # Extraire l'image_id\n    patient_id = data['patient_id']  # Extraire le patient_id\n    \n    # Construire le chemin vers le fichier DICOM en remplaçant XX par patient_id et image_id\n    dcm_path = f'/kaggle/input/rsna-breast-cancer-detection/train_images/{patient_id}/{image_id}.dcm'\n    \n    try:\n        # Lire et afficher l'image DICOM\n        img = pydicom.dcmread(dcm_path)\n        \n        # Afficher l'image avec matplotlib\n        plt.imshow(img.pixel_array, cmap=plt.cm.gray)\n        plt.title(f'Patient ID: {patient_id}, Image ID: {image_id}')\n        plt.axis('off')\n        plt.show()\n\n    except FileNotFoundError:\n        print(f\"Fichier DICOM non trouvé pour Patient ID: {patient_id}, Image ID: {image_id}\")\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.490218Z","iopub.status.idle":"2024-10-23T14:33:41.49078Z","shell.execute_reply.started":"2024-10-23T14:33:41.490506Z","shell.execute_reply":"2024-10-23T14:33:41.490533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# On suppose que ton dataframe s'appelle data\n# Exemple: df = data\n\n# Boucle sur chaque colonne pour générer un graphique approprié\nfor column in data.columns:\n    plt.figure(figsize=(6, 4))  # Taille de chaque graphique\n\n    if pd.api.types.is_numeric_dtype(data[column]):\n        # Si la colonne contient des données numériques, on utilise un histogramme\n        sns.histplot(data[column], bins=20, color='skyblue')\n        plt.title(f\"Histogramme de {column}\")\n        plt.xlabel(column)\n        plt.ylabel(\"Fréquence\")\n    \n    elif pd.api.types.is_categorical_dtype(data[column]) or data[column].dtype == 'object':\n        # Si la colonne contient des données catégorielles, on utilise un diagramme en barres\n        sns.countplot(x=data[column], palette=\"Set2\")\n        plt.title(f\"Répartition des catégories pour {column}\")\n        plt.xlabel(column)\n        plt.ylabel(\"Fréquence\")\n    \n    elif data[column].nunique() == 2:\n        # Si la colonne contient des données binaires (0 ou 1), on utilise un diagramme en barres\n        counts = data[column].value_counts()\n        sns.barplot(x=counts.index, y=counts.values, palette=\"Blues_d\")\n        plt.title(f\"Répartition des valeurs binaires pour {column}\")\n        plt.xlabel(column)\n        plt.ylabel(\"Fréquence\")\n    \n    else:\n        print(f\"Type de colonne non supporté pour : {column}\")\n    \n    plt.tight_layout()  # Pour ajuster l'affichage des titres\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.492396Z","iopub.status.idle":"2024-10-23T14:33:41.492893Z","shell.execute_reply.started":"2024-10-23T14:33:41.49263Z","shell.execute_reply":"2024-10-23T14:33:41.492657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for category, columns in data[column]:\n    plt.figure(figsize=(6, 4))\n    \n    # On somme les 1 de chaque colonne pour voir la distribution des catégories\n    sums = df[columns].sum()\n    \n    # Diagramme en barres pour les catégories\n    sns.barplot(x=sums.index, y=sums.values)\n    plt.title(f\"Distribution des catégories pour {category}\")\n    plt.ylabel(\"Nombre d'occurrences\")\n    plt.xlabel(f\"Catégories de {category}\")\n    \n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.494448Z","iopub.status.idle":"2024-10-23T14:33:41.494965Z","shell.execute_reply.started":"2024-10-23T14:33:41.494693Z","shell.execute_reply":"2024-10-23T14:33:41.494721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport pandas as pd\nimport pydicom\nimport matplotlib.pyplot as plt\n\n\n# Supprimer les doublons pour ne garder que la première ligne de chaque machine_id\npremieres_lignes = data.drop_duplicates(subset='machine_id')\n\n# Parcourir chaque 'machine_id', 'patient_id', et 'image_id' dans les premières lignes\nfor index, row in premieres_lignes.iterrows():\n    patient_id = row['patient_id']  # Extraire le patient_id\n    image_id = row['image_id']  # Extraire l'image_id\n    \n    # Construire le chemin vers le fichier DICOM en utilisant patient_id et image_id\n    dcm_path = f'/kaggle/input/rsna-breast-cancer-detection/train_images/{patient_id}/{image_id}.dcm'\n    print(dcm_path)\n    \n    img_1 = pydicom.dcmread(dcm_path)\n    print(img_1)\n    plt.imshow(img_1.pixel_array)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.496427Z","iopub.status.idle":"2024-10-23T14:33:41.496817Z","shell.execute_reply.started":"2024-10-23T14:33:41.496623Z","shell.execute_reply":"2024-10-23T14:33:41.496644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for image in premiers_image_ids:\n    dcm_path = '/kaggle/input/rsna-breast-cancer-detection/train_images/10011/220375232.dcm'\n    img = pydicom.dcmread(dcm_path)\n    plt.imshow(image)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.498051Z","iopub.status.idle":"2024-10-23T14:33:41.498462Z","shell.execute_reply.started":"2024-10-23T14:33:41.498241Z","shell.execute_reply":"2024-10-23T14:33:41.498277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train, Test","metadata":{}},{"cell_type":"code","source":"def split_csv(csv_file, train_size=1000, test_size=1000):\n    \"\"\"\n    Sépare un fichier CSV en deux parties : train et test, avec 1000 images chacune.\n\n    :param csv_file: Chemin vers le fichier CSV original contenant les images.\n    :param train_size: Nombre d'images à inclure dans l'ensemble d'entraînement.\n    :param test_size: Nombre d'images à inclure dans l'ensemble de test.\n    \"\"\"\n    # Charger le CSV\n    data = pd.read_csv(csv_file)\n\n    total_size = train_size + test_size\n    if len(data) < total_size:\n        raise ValueError(f\"Le fichier CSV doit contenir au moins {total_size} lignes.\")\n\n    train_data, test_data = train_test_split(data, train_size=train_size, test_size=test_size, random_state=42)\n\n    # Sauvegarder les deux ensembles dans des fichiers séparés\n    #train_data.to_csv('train.csv', index=False)\n    #test_data.to_csv('test.csv', index=False)\n\n    print(f\"Fichier train.csv contenant {train_size} images créé avec succès.\")\n    print(f\"Fichier test.csv contenant {test_size} images créé avec succès.\")\n    \n    return train_data, test_data\n\n# Exécution de la fonction avec le fichier CSV source\ncsv_file = '/kaggle/input/dataset-encoded/data_train_encoded.csv'  # Remplacer par le chemin de votre fichier CSV\ntrain_data, test_data = split_csv(csv_file)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.49992Z","iopub.status.idle":"2024-10-23T14:33:41.500295Z","shell.execute_reply.started":"2024-10-23T14:33:41.500096Z","shell.execute_reply":"2024-10-23T14:33:41.500115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport pydicom\nimport os\nfrom skimage import io\nimport matplotlib.pyplot as plt\nfrom skimage.util import random_noise\nimport random\nfrom PIL import Image\nfrom PIL import ImageEnhance\n\n# Fonction pour appliquer les augmentations\ndef flip_horizontal(image):\n    return np.fliplr(image)\n\ndef flip_vertical(image):\n    return np.flipud(image)\n\ndef change_brightness(image, factor=1.0):\n    \"\"\"\n    Change la luminosité de l'image en multipliant les valeurs de pixels par un facteur.\n    Un facteur > 1.0 augmente la luminosité, un facteur < 1.0 la réduit.\n    \"\"\"\n   # Modifier la luminosité en multipliant directement les valeurs des pixels\n    bright_image = image * factor\n    \n    # S'assurer que les valeurs restent dans les limites autorisées par le format DICOM\n    bright_image = np.clip(bright_image, image.min(), image.max())\n    \n    return bright_image\n\ndef add_noise(image, var=0.01):\n    return random_noise(image, var=var)\n\ndef normalize_image(image):\n    # Normaliser l'image entre 0 et 1\n    normalized_image = (image - np.min(image)) / (np.max(image) - np.min(image))\n    # Convertir en échelle de 0 à 255\n    normalized_image = (normalized_image * 255).astype(np.uint8)\n    return normalized_image\n\ndef rotate_image(image, max_angle=30):\n    angle = random.uniform(-max_angle, max_angle)  # Angle de rotation aléatoire\n    return image.rotate(angle, resample=Image.BICUBIC, expand=True)\n\ndef augmenter_images(df, image_folder, image_folder_output):\n    new_rows = []\n    for idx, row in df.iterrows():\n        patient_id = row['patient_id']\n        image_id = row['image_id']\n        \n        # Charger l'image DICOM\n        dcm_path = os.path.join(image_folder, f'{patient_id}/{image_id}.dcm')\n        \n        try:\n            dcm = pydicom.dcmread(dcm_path)\n            image = dcm.pixel_array\n            \n            # Normaliser l'image\n            image = normalize_image(image)\n\n            # Appliquer les augmentations\n            aug_images = [\n                flip_horizontal(image),\n                flip_vertical(image),\n                change_brightness(image, factor=random.uniform(0.9, 1.1)),  # Changer la luminosité\n            ]\n\n            # Créer de nouvelles lignes pour chaque image augmentée\n            for i, aug_image in enumerate(aug_images):\n                new_image_id = f\"{image_id}aug{i}\"\n                \n                patient_output_dir = os.path.join(image_folder_output, str(patient_id))\n                if not os.path.exists(patient_output_dir):\n                    os.makedirs(patient_output_dir)\n                \n                new_image_path = os.path.join(image_folder_output, f'{patient_id}/{new_image_id}.jpeg')\n                \n                # Convertir en image PIL (en mode 'L' pour les images en niveaux de gris)\n                image_pil = Image.fromarray(aug_image).convert('L')\n\n                # Enregistrer l'image dans le dossier du patient au format JPEG\n                image_pil.save(new_image_path, \"JPEG\")\n\n                # Ajouter une nouvelle ligne dans le DataFrame\n                new_row = {'patient_id': patient_id, 'image_id': new_image_id}\n                new_rows.append(new_row)\n\n        except Exception as e:\n            print(f\"Erreur lors de la lecture du fichier DICOM : {dcm_path}. Détails : {e}\")\n\n    # Ajouter les nouvelles lignes au DataFrame existant\n    df_augmented = pd.concat([df, pd.DataFrame(new_rows)], ignore_index=True)\n    \n    return df_augmented\n\n\n# Exécution du code\n# Assure-toi que le chemin vers les images est correct\nimage_folder = '/kaggle/input/rsna-breast-cancer-detection/train_images'\nimage_folder_output = 'images_augmente'\ndf = pd.read_csv('/kaggle/input/data-train-50/data_train_1000.csv')\n\nos.makedirs(image_folder_output)\n\n# Appliquer les augmentations et mettre à jour le DataFrame\ndf_augmented = augmenter_images(df, image_folder,image_folder_output)\n\n# Afficher le DataFrame mis à jour\nprint(df_augmented)\n\n#df_augmented.to_csv('data_train_5000.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-24T00:19:30.971184Z","iopub.execute_input":"2024-10-24T00:19:30.971563Z","iopub.status.idle":"2024-10-24T00:42:05.311609Z","shell.execute_reply.started":"2024-10-24T00:19:30.971525Z","shell.execute_reply":"2024-10-24T00:42:05.31054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Afficher une image augmentée\ndef afficher_image(image_path):\n    # Charger l'image\n    image = Image.open(image_path)\n    \n    # Afficher l'image avec matplotlib\n    plt.imshow(image, cmap='gray')\n    plt.axis('off')  # Masquer les axes\n    plt.show()\n\n# Exemple d'affichage d'une image augmentée\n# Vous pouvez changer 'patient_id' et 'image_id' pour afficher une autre image\npatient_id = 54575  # Prendre le premier patient\nnew_image_id = 1347764706  # Prendre la première image augmentée\n\n# Construire le chemin vers l'image augmentée\nimage_path_to_display = f\"/kaggle/working/images_augmente/{patient_id}/{new_image_id}aug3.jpeg\"\n\n# Afficher l'image\nafficher_image(image_path_to_display)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-24T00:42:38.28689Z","iopub.execute_input":"2024-10-24T00:42:38.287687Z","iopub.status.idle":"2024-10-24T00:42:39.130636Z","shell.execute_reply.started":"2024-10-24T00:42:38.287646Z","shell.execute_reply":"2024-10-24T00:42:39.129227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_csv = '/kaggle/input/data-test50/data_train-test_1000.csv'\n\n# Lecture des fichiers CSV\ntrain_data = df_augmented\ntest_data = pd.read_csv(test_csv)\n\n# Afficher les premières lignes pour vérifier\nprint(\"Train Data :\")\nprint(train_data.head())\n\nprint(\"\\nTest Data :\")\nprint(test_data.head())","metadata":{"execution":{"iopub.status.busy":"2024-10-24T00:43:07.029547Z","iopub.execute_input":"2024-10-24T00:43:07.030293Z","iopub.status.idle":"2024-10-24T00:43:07.07442Z","shell.execute_reply.started":"2024-10-24T00:43:07.030238Z","shell.execute_reply":"2024-10-24T00:43:07.073294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv = '/kaggle/input/data-train-50/data_train_1000.csv'\ntest_csv = '/kaggle/input/data-test50/data_train-test_1000.csv'\n\n# Lecture des fichiers CSV\ntrain_data = pd.read_csv(train_csv)\ntest_data = pd.read_csv(test_csv)\n\n# Afficher les premières lignes pour vérifier\nprint(\"Train Data :\")\nprint(train_data.head())\n\nprint(\"\\nTest Data :\")\nprint(test_data.head())","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.5059Z","iopub.status.idle":"2024-10-23T14:33:41.506321Z","shell.execute_reply.started":"2024-10-23T14:33:41.506094Z","shell.execute_reply":"2024-10-23T14:33:41.506115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Crop","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport pydicom\nimport os\nfrom PIL import Image\n\n# Fonction pour découper une image en fonction de la moyenne des colonnes\ndef découper_image_par_colonne(image, image_array, seuil=50, largeur_min=500):\n    largeur, hauteur = image.size\n    moyennes_colonnes = np.mean(image_array, axis=0)\n    colonnes_significatives = np.where(moyennes_colonnes > seuil)[0]\n\n    if len(colonnes_significatives) == 0:\n        return None\n\n    première_colonne = colonnes_significatives[0]\n    dernière_colonne = colonnes_significatives[-1]\n    sous_image = image.crop((première_colonne, 0, dernière_colonne + 1, hauteur))\n    if sous_image.width > largeur_min:\n        return sous_image\n    return None\n\n# Fonction principale pour traiter et découper les images DICOM\ndef traiter_images(data, folder_1, folder_2, output_folder):\n    \n    for index, row in data.iterrows():\n        patient_id = row['patient_id']\n        image_id = row['image_id']\n        \n        dcm_path_1 = os.path.join(folder_1, f'{patient_id}/{image_id}.dcm')\n        dcm_path_2 = os.path.join(folder_2, f'{patient_id}/{image_id}.jpeg')\n\n        if os.path.exists(dcm_path_1):\n            dcm_path = dcm_path_1\n        else os.path.exists(dcm_path_2):\n            dcm_path = dcm_path_2\n\n        print(f\"Traitement de : {dcm_path}\")\n\n        try:\n            dicom = pydicom.dcmread(dcm_path)\n            image_array = dicom.pixel_array\n            image = Image.fromarray(image_array)\n            \n            sous_image = découper_image_par_colonne(image, image_array)\n            \n            if sous_image:\n                new_image_id = f\"{patient_id}_{image_id}_cropped.jpeg\"\n\n                patient_output_dir = os.path.join(output_folder, str(patient_id))\n                if not os.path.exists(patient_output_dir):\n                    os.makedirs(patient_output_dir)\n                \n                new_image_path = os.path.join(output_folder, f'{patient_id}/{new_image_id}.jpeg')\n                #io.imsave(new_image_path, aug_image)\n                \n                \n                # Convertir en image PIL (en mode 'L' pour les images en niveaux de gris)\n                image_pil = Image.fromarray(sous_image).convert('L')\n\n                # Enregistrer l'image dans le dossier du patient au format JPEG\n                image_pil.save(new_image_path, \"JPEG\")\n\n        except Exception as e:\n            print(f\"Erreur lors de la lecture du fichier DICOM : {dcm_path}. Détails : {e}\")\n\n\n\n\n\n# Exécution du code\n\nfolder_1 = '/kaggle/input/rsna-breast-cancer-detection/train_images'\nfolder_2 = '/kaggle/working/images_augmente'\noutput_folder = '/kaggle/working/clean_images'\nos.makedirs(output_folder)\n\ntraiter_images(train_data, folder_1, folder_2, output_folder)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T21:58:47.353418Z","iopub.execute_input":"2024-10-23T21:58:47.354088Z","iopub.status.idle":"2024-10-23T21:58:47.370389Z","shell.execute_reply.started":"2024-10-23T21:58:47.354039Z","shell.execute_reply":"2024-10-23T21:58:47.368997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport pydicom\nimport os\nfrom PIL import Image\n\n# Fonction pour normaliser l'image\ndef normalize_image(image):\n    \"\"\"Normalise l'image entre 0 et 255.\"\"\"\n    normalized_image = (image - np.min(image)) / (np.max(image) - np.min(image)) * 255\n    return normalized_image.astype(np.uint8)\n\n# Fonction pour découper une image en fonction de la moyenne des colonnes\ndef découper_image_par_colonne(image, image_array, seuil=50, largeur_min=500):\n    largeur, hauteur = image.size\n    moyennes_colonnes = np.mean(image_array, axis=0)\n    colonnes_significatives = np.where(moyennes_colonnes > seuil)[0]\n\n    if len(colonnes_significatives) == 0:\n        print(\"Aucune colonne significative trouvée\")\n        return None\n\n    première_colonne = colonnes_significatives[0]\n    dernière_colonne = colonnes_significatives[-1]\n    sous_image = image.crop((première_colonne, 0, dernière_colonne + 1, hauteur))\n    \n    return sous_image  # Retourner toujours la sous-image, même si elle est petite\n\n# Fonction pour redimensionner une image\ndef redimensionner_image(image, taille=(128, 128)):\n    return image.resize(taille)\n\n# Fonction principale pour traiter et découper les images DICOM et JPEG\ndef traiter_images(data, folder_1, folder_2, output_folder, taille_standard=(128, 128)):\n    \n    for index, row in data.iterrows():\n        patient_id = row['patient_id']\n        image_id = row['image_id']\n        \n        # Chemin du fichier DICOM ou JPEG\n        dcm_path_1 = os.path.join(folder_1, f'{patient_id}/{image_id}.dcm')\n        jpeg_path_2 = os.path.join(folder_2, f'{patient_id}/{image_id}.jpeg')\n\n        # Choisir le bon fichier à charger\n        if os.path.exists(dcm_path_1):\n            image_path = dcm_path_1\n            is_dicom = True\n        elif os.path.exists(jpeg_path_2):\n            image_path = jpeg_path_2\n            is_dicom = False\n        else:\n            print(f\"Image non trouvée pour le patient {patient_id} et l'image {image_id}\")\n            continue\n\n        print(f\"Traitement de : {image_path}\")\n\n        try:\n            if is_dicom:\n                # Lecture du fichier DICOM\n                dicom = pydicom.dcmread(image_path)\n                image_array = dicom.pixel_array\n            else:\n                # Lecture du fichier JPEG\n                image = Image.open(image_path).convert('L')\n                image_array = np.array(image)\n\n            # Normaliser l'image\n            image_array = normalize_image(image_array)\n\n            # Convertir l'image normalisée en format PIL\n            image = Image.fromarray(image_array)\n\n            # Appliquer le découpage\n            sous_image = découper_image_par_colonne(image, image_array)\n            \n            if sous_image:\n                # Redimensionner l'image à la taille standard\n                sous_image_redimensionnée = redimensionner_image(sous_image, taille_standard)\n\n                # Vérifier si la largeur de la sous-image est inférieure au seuil\n                if sous_image.width < 500:\n                    print(f\"Avertissement : Sous-image trop petite (largeur {sous_image.width}), mais sera quand même enregistrée.\")\n\n                # Créer un nouvel ID d'image\n                new_image_id = f\"{patient_id}_{image_id}_cropped.jpeg\"\n\n                # Créer le dossier de sortie si nécessaire\n                patient_output_dir = os.path.join(output_folder, str(patient_id))\n                if not os.path.exists(patient_output_dir):\n                    os.makedirs(patient_output_dir)\n                \n                new_image_path = os.path.join(patient_output_dir, new_image_id)\n\n                # Enregistrer l'image redimensionnée au format JPEG\n                sous_image_redimensionnée.save(new_image_path, \"JPEG\")\n                print(f\"Image enregistrée sous : {new_image_path}\")\n            else:\n                print(f\"Pas de sous-image enregistrée pour {image_path}\")\n                \n        except Exception as e:\n            print(f\"Erreur lors de la lecture du fichier : {image_path}. Détails : {e}\")\n\n# Exécution du code\nfolder_1 = '/kaggle/input/rsna-breast-cancer-detection/train_images'\nfolder_2 = '/kaggle/working/images_augmente'\noutput_folder = '/kaggle/working/clean_images'\n\nos.makedirs(output_folder, exist_ok=True)\n\n# Taille standard pour redimensionner les images (peut être ajustée selon les besoins)\ntaille_standard = (128, 128)\n\n# Appliquer le traitement\ntraiter_images(train_data, folder_1, folder_2, output_folder, taille_standard)","metadata":{"execution":{"iopub.status.busy":"2024-10-24T01:23:04.852825Z","iopub.execute_input":"2024-10-24T01:23:04.853492Z","iopub.status.idle":"2024-10-24T01:46:51.575451Z","shell.execute_reply.started":"2024-10-24T01:23:04.853451Z","shell.execute_reply":"2024-10-24T01:46:51.574492Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folder_1 = '/kaggle/input/rsna-breast-cancer-detection/train_images'\nfolder_2 = '/kaggle/working/images_augmente'\noutput_folder = '/kaggle/working/clean_images'\n\nos.makedirs(output_folder, exist_ok=True)\n\n# Taille standard pour redimensionner les images (peut être ajustée selon les besoins)\ntaille_standard = (128, 128)\n\ntraiter_images(test_data, folder_1, folder_2, output_folder, taille_standard)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T22:31:16.809218Z","iopub.execute_input":"2024-10-23T22:31:16.809623Z","iopub.status.idle":"2024-10-23T22:45:24.488809Z","shell.execute_reply.started":"2024-10-23T22:31:16.809582Z","shell.execute_reply":"2024-10-23T22:45:24.487788Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pydicom\nfrom PIL import Image\nimport matplotlib.pyplot as plt\n\ndef afficher_images(patient_id, image_id, folder_1, folder_2, output_folder):\n    # Chemins d'accès aux fichiers\n    dcm_path = os.path.join(folder_1, f\"{patient_id}/{image_id}.dcm\")\n    jpeg_path = os.path.join(folder_2, f\"{patient_id}/{image_id}.jpeg\")\n    \n    # Initialiser les variables\n    image_originale = None\n    is_dicom = False\n\n    # Vérifier si l'image DICOM existe\n    if os.path.exists(dcm_path):\n        is_dicom = True\n        # Lire le fichier DICOM\n        dicom = pydicom.dcmread(dcm_path)\n        image_array = dicom.pixel_array\n        image_originale = Image.fromarray(image_array)\n    # Vérifier si l'image JPEG existe\n    elif os.path.exists(jpeg_path):\n        image_originale = Image.open(jpeg_path).convert('L')\n    else:\n        print(f\"Image d'origine non trouvée pour le patient {patient_id} et l'image {image_id}\")\n        return\n\n    # Afficher l'image d'origine\n    plt.figure(figsize=(12, 6))\n    plt.subplot(1, 2, 1)\n    plt.imshow(image_originale, cmap='gray')\n    plt.title(f\"Image d'origine pour le patient {patient_id} (ID: {image_id})\")\n    plt.axis('off')  # Masquer les axes\n\n    # Afficher l'image croppée\n    new_image_id = f\"{patient_id}_{image_id}_cropped.jpeg\"\n    cropped_image_path = os.path.join(output_folder, str(patient_id), new_image_id)\n\n    if os.path.exists(cropped_image_path):\n        image_cropped = Image.open(cropped_image_path)\n        plt.subplot(1, 2, 2)\n        plt.imshow(image_cropped, cmap='gray')\n        plt.title(f\"Image croppée pour le patient {patient_id} (ID: {image_id})\")\n        plt.axis('off')  # Masquer les axes\n    else:\n        print(f\"Image croppée non trouvée pour le patient {patient_id} et l'image {image_id}\")\n\n    plt.tight_layout()\n    plt.show()\n\n# Exemple d'utilisation\npatient_id = 65222  # Remplacer par l'ID de votre choix\nimage_id = 11055050  # Remplacer par l'ID de votre choix\nfolder_1 = '/kaggle/input/rsna-breast-cancer-detection/train_images'\nfolder_2 = '/kaggle/working/images_augmente'\noutput_folder = '/kaggle/working/clean_images'\n\nafficher_images(patient_id, image_id, folder_1, folder_2, output_folder)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pydicom\nfrom PIL import Image\nimport matplotlib.pyplot as plt\n\ndef afficher_images(patient_id, image_id, folder_1, folder_2, output_folder):\n    # Chemins d'accès aux fichiers\n    dcm_path = os.path.join(folder_1, f\"{patient_id}/{image_id}.dcm\")\n    jpeg_path = os.path.join(folder_2, f\"{patient_id}/{image_id}aug2.jpeg\")\n    \n    # Initialiser les variables\n    image_originale = None\n    is_dicom = False\n\n    # Vérifier si l'image DICOM existe\n    if os.path.exists(dcm_path):\n        is_dicom = True\n        # Lire le fichier DICOM\n        dicom = pydicom.dcmread(dcm_path)\n        image_array = dicom.pixel_array\n        image_originale = Image.fromarray(image_array)\n    # Vérifier si l'image JPEG existe\n    elif os.path.exists(jpeg_path):\n        image_originale = Image.open(jpeg_path).convert('L')\n    else:\n        print(f\"Image d'origine non trouvée pour le patient {patient_id} et l'image {image_id}\")\n        return\n\n    # Afficher l'image d'origine\n    plt.figure(figsize=(12, 6))\n    plt.subplot(1, 2, 1)\n    plt.imshow(image_originale, cmap='gray')\n    plt.title(f\"Image d'origine pour le patient {patient_id} (ID: {image_id})\")\n    plt.axis('off')  # Masquer les axes\n\n    # Afficher l'image croppée\n    new_image_id = f\"{patient_id}_{image_id}aug2_cropped.jpeg\"\n    cropped_image_path = os.path.join(output_folder, str(patient_id), new_image_id)\n\n    if os.path.exists(cropped_image_path):\n        image_cropped = Image.open(cropped_image_path)\n        plt.subplot(1, 2, 2)\n        plt.imshow(image_cropped, cmap='gray')\n        plt.title(f\"Image croppée pour le patient {patient_id} (ID: {image_id})\")\n        plt.axis('off')  # Masquer les axes\n    else:\n        print(f\"Image croppée non trouvée pour le patient {patient_id} et l'image {image_id}\")\n\n    plt.tight_layout()\n    plt.show()\n\n# Exemple d'utilisation\npatient_id = 14964  # Remplacer par l'ID de votre choix\nimage_id = 784564640  # Remplacer par l'ID de votre choix\nfolder_1 = '/kaggle/working/images_augmente'\nfolder_2 = '/kaggle/working/images_augmente'\noutput_folder = '/kaggle/working/clean_images'\n\nafficher_images(patient_id, image_id, folder_1, folder_2, output_folder)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modèle","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\nimport os\nimport pandas as pd\nimport pydicom\nimport random\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom multiprocessing import Pool,cpu_count\nimport PIL\nimport tqdm\nimport cv2\nfrom sklearn.model_selection import train_test_split\nimport keras\nfrom sklearn.metrics import confusion_matrix","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.507441Z","iopub.status.idle":"2024-10-23T14:33:41.507796Z","shell.execute_reply.started":"2024-10-23T14:33:41.507616Z","shell.execute_reply":"2024-10-23T14:33:41.507635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_data  = \"/kaggle/input/rsna-breast-cancer-detection\"\n\nprint(train_data)\nprint(test_data)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.509216Z","iopub.status.idle":"2024-10-23T14:33:41.509795Z","shell.execute_reply.started":"2024-10-23T14:33:41.509567Z","shell.execute_reply":"2024-10-23T14:33:41.509593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"GPU","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\ngpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    print(f\"Number of GPUs available: {len(gpus)}\")\nelse:\n    print(\"No GPUs available\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.51079Z","iopub.status.idle":"2024-10-23T14:33:41.511141Z","shell.execute_reply.started":"2024-10-23T14:33:41.510962Z","shell.execute_reply":"2024-10-23T14:33:41.51098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras\nimport numpy as np\nimport time\nfrom PIL import Image\nfrom concurrent.futures import ThreadPoolExecutor\n\n# Fonction pour traiter une seule image PNG (déjà normalisée et redimensionnée)\ndef process_single_image(image_id, patient_id, label_data, img_size=(1920, 480)):\n    # Chemin vers l'image PNG\n    img_path = f\"/kaggle/input/train-clean/{patient_id}_{image_id}.png\"\n    \n    # Charger l'image en tant que tableau NumPy\n    img_array = np.array(Image.open(img_path))\n\n    # Vérifier si l'image a la bonne taille\n    if img_array.shape != img_size:\n        raise ValueError(f\"L'image {image_id}.png n'a pas la dimension attendue {img_size}.\")\n\n    # Récupérer le label\n    label = label_data[label_data['image_id'] == int(image_id)]['cancer'].values[0]\n    \n    return img_array, label\n\n# Fonction pour charger et traiter les images en parallèle\ndef load_images_parallel(image_ids, patient_ids, label_data, img_size=(1920, 480), num_workers=4):\n    images = []\n    labels = []\n\n    # Mesurer le temps de chargement des images\n    start_time = time.time()\n\n    # Utiliser ThreadPoolExecutor pour paralléliser le traitement\n    with ThreadPoolExecutor(max_workers=num_workers) as executor:\n        results = list(executor.map(process_single_image, image_ids, patient_ids, [label_data]*len(image_ids), [img_size]*len(image_ids)))\n\n    # Récupérer les résultats des threads\n    for img, lbl in results:\n        images.append(img)\n        labels.append(lbl)\n\n    # Calculer et afficher le temps d'exécution\n    end_time = time.time()\n    print(f\"Temps de chargement et traitement des images: {end_time - start_time:.2f} secondes\")\n    \n    return np.array(images), np.array(labels)\n\n# Appliquer le prétraitement aux données\ndef preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2):\n    # Ici, les images sont déjà normalisées donc pas besoin de les traiter\n    # One-hot encoding des labels\n    train_labels = keras.utils.to_categorical(train_labels, num_classes)\n    test_labels = keras.utils.to_categorical(test_labels, num_classes)\n    \n    return train_images, train_labels, test_images, test_labels\n\n# Mesurer le temps total de traitement\nstart_time_total = time.time()\n\n# Charger les images de train et test en parallèle\ntrain_images, train_labels = load_images_parallel(\n    train_data['image_id'].astype(str), \n    train_data['patient_id'].astype(str), \n    train_data,\n    img_size=(1920, 480),\n    num_workers=8\n)\n\ntest_images, test_labels = load_images_parallel(\n    test_data['image_id'].astype(str), \n    test_data['patient_id'].astype(str), \n    test_data,\n    img_size=(1920, 480),\n    num_workers=8\n)\n\n# Appliquer le prétraitement\ntrain_images, train_labels, test_images, test_labels = preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2)\n\n# Calculer et afficher le temps total de traitement\nend_time_total = time.time()\nprint(f\"Temps total de traitement : {end_time_total - start_time_total:.2f} secondes\")\n\n# Afficher les formes des tableaux résultants\nprint(f'Taille des images de train : {train_images.shape}')\nprint(f'Taille des labels de train : {train_labels.shape}')\nprint(f'Taille des images de test : {test_images.shape}')\nprint(f'Taille des labels de test : {test_labels.shape}')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.512319Z","iopub.status.idle":"2024-10-23T14:33:41.512701Z","shell.execute_reply.started":"2024-10-23T14:33:41.512505Z","shell.execute_reply":"2024-10-23T14:33:41.512524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras\nimport pydicom\nimport time\nimport numpy as np\nfrom skimage.transform import resize\nfrom skimage.io import imread\nfrom concurrent.futures import ThreadPoolExecutor\nimport os\n\n# Fonction pour traiter une seule image\ndef process_single_image(image_id, patient_id, label_data, img_size=(128, 128)):\n    dicom_path = f\"/kaggle/input/rsna-breast-cancer-detection/train_images/{patient_id}/{image_id}.dcm\"\n    jpeg_path = f\"/kaggle/working/images_augmente/{patient_id}/{image_id}.jpeg\"  # Chemin de secours pour les images JPEG\n    \n    try:\n        # Essayer de lire l'image DICOM\n        read_dcm = pydicom.dcmread(dicom_path)\n        img_array = read_dcm.pixel_array\n        #print(f\"Image DICOM trouvée : {dicom_path}\")\n    except Exception as e:\n        #print(f\"Image DICOM non trouvée ou erreur de lecture à {dicom_path}, erreur: {e}. Tentative de lecture JPEG.\")\n        try:\n            # Si l'image DICOM n'est pas trouvée, essayer de lire la version JPEG\n            img_array = imread(jpeg_path, as_gray=True)\n            #print(f\"Image JPEG trouvée : {jpeg_path}\")\n        except Exception as e:\n            #print(f\"Image JPEG non trouvée à {jpeg_path}, erreur: {e}\")\n            return None, None\n\n    # Redimensionner l'image\n    img_array_resized = resize(img_array, img_size, anti_aliasing=True)\n\n    # Normalisation des images avec les valeurs min et max spécifiques à chaque image\n    img_array_normalized = (img_array_resized - np.min(img_array_resized)) / (np.max(img_array_resized) - np.min(img_array_resized) + 1e-6)\n\n    numeric_image_id = image_id.split('aug')[0]\n    print(numeric_image_id)\n    \n    # Récupérer le label\n    label = label_data[label_data['image_id'] == int(numeric_image_id)]['cancer'].values[0]\n    \n    return img_array_normalized, label\n\n# Fonction pour charger et traiter les images en parallèle\ndef load_images_parallel(image_ids, patient_ids, label_data, img_size=(128, 128), num_workers=4):\n    images = []\n    labels = []\n\n    # Mesurer le temps de chargement des images\n    start_time = time.time()\n\n    # Utiliser ThreadPoolExecutor pour paralléliser le traitement\n    with ThreadPoolExecutor(max_workers=num_workers) as executor:\n        results = list(executor.map(process_single_image, image_ids, patient_ids, [label_data]*len(image_ids), [img_size]*len(image_ids)))\n\n    # Récupérer les résultats des threads\n    for img, lbl in results:\n        if img is not None and lbl is not None:  # Ajouter seulement si l'image et le label sont valides\n            images.append(img)\n            labels.append(lbl)\n\n    # Calculer et afficher le temps d'exécution\n    end_time = time.time()\n    print(f\"Temps de chargement et traitement des images: {end_time - start_time:.2f} secondes\")\n    \n    return np.array(images), np.array(labels)\n\n# Appliquer le prétraitement aux données\ndef preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2):\n    # Normalisation des images est déjà faite dans process_single_image\n    \n    # One-hot encoding des labels\n    train_labels = keras.utils.to_categorical(train_labels, num_classes)\n    test_labels = keras.utils.to_categorical(test_labels, num_classes)\n    \n    return train_images, train_labels, test_images, test_labels\n\n# Mesurer le temps total de traitement\nstart_time_total = time.time()\n\n# Charger les images de train et test en parallèle\ntrain_images, train_labels = load_images_parallel(\n    train_data['image_id'].astype(str), \n    train_data['patient_id'].astype(str), \n    train_data,\n    img_size=(128, 128),\n    num_workers=8\n)\n\ntest_images, test_labels = load_images_parallel(\n    test_data['image_id'].astype(str), \n    test_data['patient_id'].astype(str), \n    test_data,\n    img_size=(128, 128),\n    num_workers=8\n)\n\n# Appliquer le prétraitement\ntrain_images, train_labels, test_images, test_labels = preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2)\n\n# Calculer et afficher le temps total de traitement\nend_time_total = time.time()\nprint(f\"Temps total de traitement : {end_time_total - start_time_total:.2f} secondes\")\n\n# Afficher les formes des tableaux résultants\nprint(f'Taille des images de train : {train_images.shape}')\nprint(f'Taille des labels de train : {train_labels.shape}')\nprint(f'Taille des images de test : {test_images.shape}')\nprint(f'Taille des labels de test : {test_labels.shape}')\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.514692Z","iopub.status.idle":"2024-10-23T14:33:41.515053Z","shell.execute_reply.started":"2024-10-23T14:33:41.51487Z","shell.execute_reply":"2024-10-23T14:33:41.514889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"fonctionne","metadata":{}},{"cell_type":"code","source":"import keras\nimport pydicom\nimport time\nfrom skimage.transform import resize\nfrom concurrent.futures import ThreadPoolExecutor\n\n# Fonction pour traiter une seule image\ndef process_single_image(image_id, patient_id, label_data, img_size=(128, 128)):\n    dicom_path = f\"/kaggle/input/rsna-breast-cancer-detection/train_images/{patient_id}/{image_id}.dcm\"\n    read_dcm = pydicom.dcmread(dicom_path)\n    img_array = read_dcm.pixel_array\n\n    # Redimensionner l'image\n    img_array_resized = resize(img_array, img_size, anti_aliasing=True)\n\n    # Normalisation des images avec les valeurs min et max spécifiques à chaque image\n    img_array_normalized = (img_array_resized - np.min(img_array_resized)) / (np.max(img_array_resized) - np.min(img_array_resized) + 1e-6)\n\n    # Récupérer le label\n    label = label_data[label_data['image_id'] == int(image_id)]['cancer'].values[0]\n    \n    return img_array_normalized, label\n\n# Fonction pour charger et traiter les images en parallèle\ndef load_images_parallel(image_ids, patient_ids, label_data, img_size=(128, 128), num_workers=4):\n    images = []\n    labels = []\n\n    # Mesurer le temps de chargement des images\n    start_time = time.time()\n\n    # Utiliser ThreadPoolExecutor pour paralléliser le traitement\n    with ThreadPoolExecutor(max_workers=num_workers) as executor:\n        results = list(executor.map(process_single_image, image_ids, patient_ids, [label_data]*len(image_ids), [img_size]*len(image_ids)))\n\n    # Récupérer les résultats des threads\n    for img, lbl in results:\n        images.append(img)\n        labels.append(lbl)\n\n    # Calculer et afficher le temps d'exécution\n    end_time = time.time()\n    print(f\"Temps de chargement et traitement des images: {end_time - start_time:.2f} secondes\")\n    \n    return np.array(images), np.array(labels)\n\n# Appliquer le prétraitement aux données\ndef preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2):\n    # Normalisation des images est déjà faite dans process_single_image\n    \n    # One-hot encoding des labels\n    train_labels = keras.utils.to_categorical(train_labels, num_classes)\n    test_labels = keras.utils.to_categorical(test_labels, num_classes)\n    \n    return train_images, train_labels, test_images, test_labels\n\n# Mesurer le temps total de traitement\nstart_time_total = time.time()\n\n# Charger les images de train et test en parallèle\ntrain_images, train_labels = load_images_parallel(\n    train_data['image_id'].astype(str), \n    train_data['patient_id'].astype(str), \n    train_data,\n    img_size=(128, 128),\n    num_workers=8\n)\n\ntest_images, test_labels = load_images_parallel(\n    test_data['image_id'].astype(str), \n    test_data['patient_id'].astype(str), \n    test_data,\n    img_size=(128, 128),\n    num_workers=8\n)\n\n# Appliquer le prétraitement\ntrain_images, train_labels, test_images, test_labels = preprocess_images_and_labels(train_images, train_labels, test_images, test_labels, num_classes=2)\n\n# Calculer et afficher le temps total de traitement\nend_time_total = time.time()\nprint(f\"Temps total de traitement : {end_time_total - start_time_total:.2f} secondes\")\n\n# Afficher les formes des tableaux résultants\nprint(f'Taille des images de train : {train_images.shape}')\nprint(f'Taille des labels de train : {train_labels.shape}')\nprint(f'Taille des images de test : {test_images.shape}')\nprint(f'Taille des labels de test : {test_labels.shape}')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:34:17.029353Z","iopub.execute_input":"2024-10-23T14:34:17.030018Z","iopub.status.idle":"2024-10-23T14:36:08.372596Z","shell.execute_reply.started":"2024-10-23T14:34:17.029979Z","shell.execute_reply":"2024-10-23T14:36:08.370747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_images.shape)\nprint(test_images.shape)\nprint(train_labels.shape)\nprint(test_labels.shape)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:36:17.32344Z","iopub.execute_input":"2024-10-23T14:36:17.324243Z","iopub.status.idle":"2024-10-23T14:36:17.329132Z","shell.execute_reply.started":"2024-10-23T14:36:17.324202Z","shell.execute_reply":"2024-10-23T14:36:17.328203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_labels)\n\ntrain_labels_decoded = np.argmax(train_labels, axis=1)\n\nunique, counts = np.unique(train_labels_decoded, return_counts=True)\nfor label, count in zip(unique, counts):\n    print(f\"Label {label}: {count} occurrences\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:36:20.333298Z","iopub.execute_input":"2024-10-23T14:36:20.333669Z","iopub.status.idle":"2024-10-23T14:36:20.341207Z","shell.execute_reply.started":"2024-10-23T14:36:20.333635Z","shell.execute_reply":"2024-10-23T14:36:20.340102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MLP","metadata":{}},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\n\n# Créer le modèle\nmodel = Sequential()\n\n# Aplatir l'image 128x128 en un vecteur 1D\nmodel.add(Flatten(input_shape=(128, 128, 1)))\n\n# Première couche dense avec un certain nombre de neurones\nmodel.add(Dense(256, kernel_initializer='normal', activation='relu'))\nmodel.add(Dropout(0.5))\n\n# Couche de sortie avec un nombre de neurones égal au nombre de classes\nmodel.add(Dense(2, kernel_initializer='normal', activation='softmax'))\n\n# Compiler le modèle\nmodel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n\n# Afficher le résumé du modèle\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.525017Z","iopub.status.idle":"2024-10-23T14:33:41.525425Z","shell.execute_reply.started":"2024-10-23T14:33:41.525198Z","shell.execute_reply":"2024-10-23T14:33:41.525218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_images, train_labels, epochs=30, batch_size=64, validation_data=(test_images, test_labels))","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.526536Z","iopub.status.idle":"2024-10-23T14:33:41.526888Z","shell.execute_reply.started":"2024-10-23T14:33:41.526709Z","shell.execute_reply":"2024-10-23T14:33:41.526727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = model.evaluate(test_images, test_labels)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.528156Z","iopub.status.idle":"2024-10-23T14:33:41.529011Z","shell.execute_reply.started":"2024-10-23T14:33:41.528804Z","shell.execute_reply":"2024-10-23T14:33:41.528826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['accuracy'], label='train_accuracy')\nplt.plot(history.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history.history['loss'], label='train_loss')\nplt.plot(history.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.530436Z","iopub.status.idle":"2024-10-23T14:33:41.53097Z","shell.execute_reply.started":"2024-10-23T14:33:41.530683Z","shell.execute_reply":"2024-10-23T14:33:41.530711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = model.predict(test_images)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_1d, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_1d, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.53285Z","iopub.status.idle":"2024-10-23T14:33:41.533392Z","shell.execute_reply.started":"2024-10-23T14:33:41.533084Z","shell.execute_reply":"2024-10-23T14:33:41.533112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## CNN","metadata":{}},{"cell_type":"code","source":"from keras import layers\nfrom keras import Sequential\nfrom keras.optimizers import Adam\n#import tensorflow_addons as tfa\nimport tensorflow as tf\n\n\n# Initialisation du modèle\nmodel_cnn = Sequential()\n\n# First convolution layer\nmodel_cnn.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(128, 128, 1)))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_cnn.add(layers.Dropout(0.3))\n\n# Second convolution layer\nmodel_cnn.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_cnn.add(layers.Dropout(0.3))\n\n# Third convolution layer\nmodel_cnn.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_cnn.add(layers.Dropout(0.3))\n\n# Flatten and add dense layer\nmodel_cnn.add(layers.Flatten())\nmodel_cnn.add(layers.Dense(128, activation='relu'))\nmodel_cnn.add(layers.BatchNormalization())\nmodel_cnn.add(layers.Dropout(0.3))\nmodel_cnn.add(layers.Dense(2, activation='softmax'))\n\nmetrics = [\n            tf.keras.metrics.TruePositives(name='tp'),\n            tf.keras.metrics.FalsePositives(name='fp'),\n            tf.keras.metrics.TrueNegatives(name='tn'),\n            tf.keras.metrics.FalseNegatives(name='fn'),\n            #tfa.metrics.F1Score(num_classes=1, threshold=0.50),\n            tf.keras.metrics.Precision(),\n            tf.keras.metrics.Recall(),\n            tf.keras.metrics.AUC(),\n            tf.keras.metrics.BinaryAccuracy(),\n            tf.keras.metrics.Accuracy()\n        ]\n\nmodel_cnn.compile(optimizer='adam', loss='categorical_crossentropy', metrics=metrics)\n\nmodel_cnn.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:59:56.369009Z","iopub.execute_input":"2024-10-23T14:59:56.369506Z","iopub.status.idle":"2024-10-23T14:59:56.742157Z","shell.execute_reply.started":"2024-10-23T14:59:56.369465Z","shell.execute_reply":"2024-10-23T14:59:56.741306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten, BatchNormalization\nfrom tensorflow.keras.regularizers import l2\n\nmodel = Sequential()\n\n# Première couche de convolution\nmodel.add(Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 1), kernel_regularizer=l2(0.001)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n# Deuxième couche de convolution\nmodel.add(Conv2D(32, (3, 3), activation='relu', kernel_regularizer=l2(0.001)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n# Troisième couche de convolution\nmodel.add(Conv2D(64, (3, 3), activation='relu', kernel_regularizer=l2(0.001)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n# Quatrième couche de convolution\nmodel.add(Conv2D(64, (3, 3), activation='relu', kernel_regularizer=l2(0.001)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n# Couche de Flatten pour passer en Dense\nmodel.add(Flatten())\n\n# Couche Dense avec Dropout\nmodel.add(Dense(32, activation='relu', kernel_regularizer=l2(0.001)))\nmodel.add(Dropout(0.5))\n\n# Couche de sortie\nmodel.add(Dense(1, activation='sigmoid'))\n\n# Compilation du modèle\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.536346Z","iopub.status.idle":"2024-10-23T14:33:41.536857Z","shell.execute_reply.started":"2024-10-23T14:33:41.536585Z","shell.execute_reply":"2024-10-23T14:33:41.536613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_cnn = model_cnn.fit(train_images, train_labels, \n                            epochs=50, \n                            batch_size=64, \n                            validation_split=0.2)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.540164Z","iopub.status.idle":"2024-10-23T14:33:41.540601Z","shell.execute_reply.started":"2024-10-23T14:33:41.540398Z","shell.execute_reply":"2024-10-23T14:33:41.54042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_cnn = model_cnn.fit(train_images, train_labels, epochs=100, batch_size=64, validation_data=(test_images, test_labels))","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:00:03.984439Z","iopub.execute_input":"2024-10-23T15:00:03.984828Z","iopub.status.idle":"2024-10-23T15:12:32.572315Z","shell.execute_reply.started":"2024-10-23T15:00:03.984791Z","shell.execute_reply":"2024-10-23T15:12:32.5715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = model_cnn.evaluate(test_images, test_labels)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:12:43.023687Z","iopub.execute_input":"2024-10-23T15:12:43.024094Z","iopub.status.idle":"2024-10-23T15:12:46.517462Z","shell.execute_reply.started":"2024-10-23T15:12:43.024056Z","shell.execute_reply":"2024-10-23T15:12:46.516017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(history_cnn.history.keys())\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:16:58.339025Z","iopub.execute_input":"2024-10-23T15:16:58.339898Z","iopub.status.idle":"2024-10-23T15:16:58.344747Z","shell.execute_reply.started":"2024-10-23T15:16:58.339857Z","shell.execute_reply":"2024-10-23T15:16:58.3438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metrics = [\n            tf.keras.metrics.TruePositives(name='tp'),\n            tf.keras.metrics.FalsePositives(name='fp'),\n            tf.keras.metrics.TrueNegatives(name='tn'),\n            tf.keras.metrics.FalseNegatives(name='fn'),\n            tf.keras.metrics.Precision(),\n            tf.keras.metrics.Recall(),\n            tf.keras.metrics.AUC(),\n            tf.keras.metrics.BinaryAccuracy(),\n        ]\n\n        model = tf.keras.models.Model(inputs=image, outputs=outputs)\n\n        model.compile(optimizer=optimizer, loss=loss, metrics=metrics)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:13:00.903611Z","iopub.execute_input":"2024-10-23T15:13:00.904001Z","iopub.status.idle":"2024-10-23T15:13:00.91223Z","shell.execute_reply.started":"2024-10-23T15:13:00.903963Z","shell.execute_reply":"2024-10-23T15:13:00.910976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fonction pour tracer les métriques\ndef plot_metrics(history_cnn):\n    metrics = ['tp', 'fp', 'tn', 'fn', 'precision_1', 'recall_1', 'auc_1', 'binary_accuracy']\n    for metric in metrics:\n        plt.plot(history_cnn.history[metric], label=f'Train {metric}')\n        plt.plot(history_cnn.history[f'val_{metric}'], label=f'Val {metric}')\n        plt.title(f'{metric.capitalize()} over epochs')\n        plt.xlabel('Epochs')\n        plt.ylabel(metric.capitalize())\n        plt.legend()\n        plt.show()\n\n# Tracer les métriques\nplot_metrics(history_cnn)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:21:41.08895Z","iopub.execute_input":"2024-10-23T15:21:41.089525Z","iopub.status.idle":"2024-10-23T15:21:43.286847Z","shell.execute_reply.started":"2024-10-23T15:21:41.089466Z","shell.execute_reply":"2024-10-23T15:21:43.285839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_cnn.history['accuracy'], label='train_accuracy')\nplt.plot(history_cnn.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history_cnn.history['loss'], label='train_loss')\nplt.plot(history_cnn.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:22:02.278053Z","iopub.execute_input":"2024-10-23T15:22:02.278911Z","iopub.status.idle":"2024-10-23T15:22:02.776907Z","shell.execute_reply.started":"2024-10-23T15:22:02.278868Z","shell.execute_reply":"2024-10-23T15:22:02.775935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = model_cnn.predict(test_images)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_1d, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_1d, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:22:06.938595Z","iopub.execute_input":"2024-10-23T15:22:06.938984Z","iopub.status.idle":"2024-10-23T15:22:08.796297Z","shell.execute_reply.started":"2024-10-23T15:22:06.938949Z","shell.execute_reply":"2024-10-23T15:22:08.795325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_cnn.save_weights('model_cnn.weights.h5')\n\n#model_cnn.load_weights('model_cnn.weights.h5')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.551013Z","iopub.status.idle":"2024-10-23T14:33:41.551423Z","shell.execute_reply.started":"2024-10-23T14:33:41.551195Z","shell.execute_reply":"2024-10-23T14:33:41.551214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_model_cnn = Sequential()\n\n# Première couche convolutionnelle\nnew_model_cnn.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(128, 128, 1)))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nnew_model_cnn.add(layers.Dropout(0.3))\n\n# Deuxième couche convolutionnelle\nnew_model_cnn.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nnew_model_cnn.add(layers.Dropout(0.3))\n\n# Troisième couche convolutionnelle\nnew_model_cnn.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.MaxPooling2D(pool_size=(2, 2)))\nnew_model_cnn.add(layers.Dropout(0.3))\n\n# Aplatir et ajouter des couches denses\nnew_model_cnn.add(layers.Flatten())\nnew_model_cnn.add(layers.Dense(128, activation='relu'))\nnew_model_cnn.add(layers.BatchNormalization())\nnew_model_cnn.add(layers.Dropout(0.3))\nnew_model_cnn.add(layers.Dense(2, activation='softmax'))  # 2 classes pour classification binaire\n\n# Initialisation de l'optimiseur Adam avec un taux d'apprentissage personnalisé\nlearning_rate = 0.0001  # Exemple de learning rate\noptimizer = Adam(learning_rate=learning_rate)\n\n# Compilation du modèle avec l'optimiseur Adam et un learning rate défini\nnew_model_cnn.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Afficher le résumé du modèle\nnew_model_cnn.summary()\n\nnew_model_cnn.load_weights('model_cnn.weights.h5')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.553389Z","iopub.status.idle":"2024-10-23T14:33:41.553763Z","shell.execute_reply.started":"2024-10-23T14:33:41.553574Z","shell.execute_reply":"2024-10-23T14:33:41.553593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_history_cnn = new_model_cnn.fit(train_images, train_labels, epochs=50, batch_size=64, validation_data=(test_images, test_labels))","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.554761Z","iopub.status.idle":"2024-10-23T14:33:41.555147Z","shell.execute_reply.started":"2024-10-23T14:33:41.554951Z","shell.execute_reply":"2024-10-23T14:33:41.554972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = new_model_cnn.evaluate(test_images, test_labels)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.55725Z","iopub.status.idle":"2024-10-23T14:33:41.557689Z","shell.execute_reply.started":"2024-10-23T14:33:41.557484Z","shell.execute_reply":"2024-10-23T14:33:41.557506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(new_history_cnn.history['accuracy'], label='train_accuracy')\nplt.plot(new_history_cnn.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(new_history_cnn.history['loss'], label='train_loss')\nplt.plot(new_history_cnn.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.559568Z","iopub.status.idle":"2024-10-23T14:33:41.560102Z","shell.execute_reply.started":"2024-10-23T14:33:41.559821Z","shell.execute_reply":"2024-10-23T14:33:41.55985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = new_model_cnn.predict(test_images)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_1d, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_1d, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T14:33:41.561305Z","iopub.status.idle":"2024-10-23T14:33:41.561839Z","shell.execute_reply.started":"2024-10-23T14:33:41.561563Z","shell.execute_reply":"2024-10-23T14:33:41.561592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ANIMA","metadata":{}},{"cell_type":"code","source":"from keras import layers\nfrom keras import models\n\n# Initialisation du modèle\nmodel_anima = models.Sequential()\n\n# Première couche convolutionnelle\nmodel_anima.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(128, 128, 1)))\nmodel_anima.add(layers.BatchNormalization())\nmodel_anima.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_anima.add(layers.Dropout(0.3))\n\n# Deuxième couche convolutionnelle\nmodel_anima.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))\nmodel_anima.add(layers.BatchNormalization())\nmodel_anima.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_anima.add(layers.Dropout(0.3))\n\n# Troisième couche convolutionnelle\nmodel_anima.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))\nmodel_anima.add(layers.BatchNormalization())\nmodel_anima.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_anima.add(layers.Dropout(0.3))\n\n# Quatrième couche convolutionnelle\nmodel_anima.add(layers.Conv2D(256, (3, 3), padding='same', activation='relu'))\nmodel_anima.add(layers.BatchNormalization())\nmodel_anima.add(layers.MaxPooling2D(pool_size=(2, 2)))\nmodel_anima.add(layers.Dropout(0.3))\n\n# Aplatir et ajouter des couches denses\nmodel_anima.add(layers.Flatten())\nmodel_anima.add(layers.Dense(512, activation='relu'))\nmodel_anima.add(layers.BatchNormalization())\nmodel_anima.add(layers.Dropout(0.5))\nmodel_anima.add(layers.Dense(2, activation='softmax'))  # 2 classes pour classification binaire\n\n# Compilation du modèle avec un taux d'apprentissage adaptatif\nmodel_anima.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Afficher le résumé du modèle\nmodel_anima.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:36:15.429921Z","iopub.execute_input":"2024-10-23T15:36:15.43067Z","iopub.status.idle":"2024-10-23T15:36:15.731471Z","shell.execute_reply.started":"2024-10-23T15:36:15.430626Z","shell.execute_reply":"2024-10-23T15:36:15.730555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_anima = model_anima.fit(train_images, train_labels, epochs=40, batch_size=64, validation_data=(test_images, test_labels))","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:36:19.489763Z","iopub.execute_input":"2024-10-23T15:36:19.490701Z","iopub.status.idle":"2024-10-23T15:38:49.153061Z","shell.execute_reply.started":"2024-10-23T15:36:19.490658Z","shell.execute_reply":"2024-10-23T15:38:49.152203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = model_anima.evaluate(test_images, test_labels)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:38:49.154822Z","iopub.execute_input":"2024-10-23T15:38:49.155142Z","iopub.status.idle":"2024-10-23T15:38:50.03913Z","shell.execute_reply.started":"2024-10-23T15:38:49.155107Z","shell.execute_reply":"2024-10-23T15:38:50.038302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_anima.history['accuracy'], label='train_accuracy')\nplt.plot(history_anima.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history_anima.history['loss'], label='train_loss')\nplt.plot(history_anima.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:38:50.040458Z","iopub.execute_input":"2024-10-23T15:38:50.040873Z","iopub.status.idle":"2024-10-23T15:38:50.45664Z","shell.execute_reply.started":"2024-10-23T15:38:50.040826Z","shell.execute_reply":"2024-10-23T15:38:50.455688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = model_anima.predict(test_images)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_1d, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_1d, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()\n\naccuracy = np.trace(conf_matrix) / np.sum(conf_matrix)\naccuracy_percentage = accuracy * 100\nprint(f'Exactitude : {accuracy_percentage:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T15:38:50.458538Z","iopub.execute_input":"2024-10-23T15:38:50.458896Z","iopub.status.idle":"2024-10-23T15:38:51.766237Z","shell.execute_reply.started":"2024-10-23T15:38:50.458862Z","shell.execute_reply":"2024-10-23T15:38:51.765392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EfficientNet","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.utils import to_categorical\n\n# Supposons que train_images et test_images soient des tableaux NumPy de forme (num_samples, 128, 128)\ntrain_images_expanded = np.expand_dims(train_images, axis=-1)  # Ajouter une dimension de canal\ntest_images_expanded = np.expand_dims(test_images, axis=-1)\n\n# Convertir en tenseur TensorFlow\ntrain_images_tensor = tf.convert_to_tensor(train_images_expanded, dtype=tf.float32)\ntest_images_tensor = tf.convert_to_tensor(test_images_expanded, dtype=tf.float32)\n\n# Appliquer la conversion en RGB\ntrain_images_rgb = tf.image.grayscale_to_rgb(train_images_tensor)  # Conversion en RGB\ntest_images_rgb = tf.image.grayscale_to_rgb(test_images_tensor)\n\ntrain_labels_binary = np.argmax(train_labels, axis=1)  # Convertir les labels one-hot en labels binaires\ntest_labels_binary = np.argmax(test_labels, axis=1)\n\nprint(train_images_rgb.shape)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:53:12.677205Z","iopub.execute_input":"2024-10-23T17:53:12.677935Z","iopub.status.idle":"2024-10-23T17:53:14.749304Z","shell.execute_reply.started":"2024-10-23T17:53:12.677891Z","shell.execute_reply":"2024-10-23T17:53:14.748243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!pip install git+https://github.com/leondgarse/keras_cv_attention_models","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:23:40.303071Z","iopub.execute_input":"2024-10-23T17:23:40.303426Z","iopub.status.idle":"2024-10-23T17:23:58.53294Z","shell.execute_reply.started":"2024-10-23T17:23:40.30339Z","shell.execute_reply":"2024-10-23T17:23:58.531712Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dropout, Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import LearningRateScheduler\n\n# Charger le modèle EfficientNetB2 pré-entraîné sur ImageNet\nbase_model = tf.keras.applications.EfficientNetB2(\n    input_shape=(128, 128, 3),  \n    include_top=False,  \n    weights='imagenet'  \n)\n\n# Geler les poids du modèle pré-entraîné\nbase_model.trainable = False\n\n# Construire le modèle\ninputs = tf.keras.Input(shape=(128, 128, 3))\nx = base_model(inputs)\nx = GlobalAveragePooling2D()(x)\nx = Dropout(0.2)(x)\noutputs = Dense(2, activation='sigmoid')(x)  \n\n# Créer le modèle final\nmodel_effnet = Model(inputs, outputs)\n\n# Définir un learning rate plus bas\nlearning_rate = 1e-4 \n\n# Compiler le modèle\nmodel_effnet.compile(optimizer=Adam(learning_rate=learning_rate), \n                     loss='categorical_crossentropy',  \n                     metrics=['accuracy'])\n\n# Résumé du modèle\nmodel_effnet.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:06:13.747821Z","iopub.execute_input":"2024-10-23T18:06:13.748238Z","iopub.status.idle":"2024-10-23T18:06:15.368168Z","shell.execute_reply.started":"2024-10-23T18:06:13.748198Z","shell.execute_reply":"2024-10-23T18:06:15.367206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_effnet = model_effnet.fit(train_images_rgb, train_labels, \n                    validation_data=(test_images_rgb, test_labels), \n                    epochs=50, \n                    batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:06:19.227348Z","iopub.execute_input":"2024-10-23T18:06:19.227989Z","iopub.status.idle":"2024-10-23T18:09:23.133317Z","shell.execute_reply.started":"2024-10-23T18:06:19.227947Z","shell.execute_reply":"2024-10-23T18:09:23.131896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = model_effnet.evaluate(test_images_rgb, test_labels_binary)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T16:21:12.625824Z","iopub.execute_input":"2024-10-23T16:21:12.626208Z","iopub.status.idle":"2024-10-23T16:21:18.077246Z","shell.execute_reply.started":"2024-10-23T16:21:12.62617Z","shell.execute_reply":"2024-10-23T16:21:18.076347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_effnet.history['accuracy'], label='train_accuracy')\nplt.plot(history_effnet.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history_effnet.history['loss'], label='train_loss')\nplt.plot(history_effnet.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T16:21:29.385758Z","iopub.execute_input":"2024-10-23T16:21:29.386675Z","iopub.status.idle":"2024-10-23T16:21:29.884721Z","shell.execute_reply.started":"2024-10-23T16:21:29.386629Z","shell.execute_reply":"2024-10-23T16:21:29.883748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = model_effnet.predict(test_images_rgb)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_binary, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_binary, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()\n\naccuracy = np.trace(conf_matrix) / np.sum(conf_matrix)\naccuracy_percentage = accuracy * 100\nprint(f'Exactitude : {accuracy_percentage:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T16:21:43.506274Z","iopub.execute_input":"2024-10-23T16:21:43.507167Z","iopub.status.idle":"2024-10-23T16:21:53.126117Z","shell.execute_reply.started":"2024-10-23T16:21:43.507126Z","shell.execute_reply":"2024-10-23T16:21:53.125109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Convnext","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dropout, Dense\nfrom tensorflow.keras.models import Model\n\n# Charger le modèle ConvNeXt pré-entraîné sans les couches du haut\nbase_model = tf.keras.applications.ConvNeXtTiny(\n    include_top=False,  # On retire la dernière couche pour ajouter les nôtres\n    input_shape=(128, 128, 3),  # Taille de l'image d'entrée\n    weights='imagenet'  # Poids pré-entraînés sur ImageNet\n)\n\n# Geler les poids du modèle pré-entraîné\nbase_model.trainable = False\n\n# Construire le modèle\ninputs = tf.keras.Input(shape=(128, 128, 3))\nx = base_model(inputs, training=False)  # Mode inference pour éviter d'entraîner les poids pré-entraînés\nx = GlobalAveragePooling2D()(x)  # Réduire les dimensions spatiales\nx = Dropout(0.2)(x)  # Ajouter un Dropout pour éviter le surapprentissage\noutputs = Dense(1, activation='sigmoid')(x)  # Dernière couche pour la classification binaire (Cancer ou Non-Cancer)\n\n# Créer le modèle final\nmodel = Model(inputs, outputs)\n\n# Compiler le modèle\nmodel.compile(optimizer='adam', \n              loss='binary_crossentropy', \n              metrics=['accuracy'])\n\n# Résumé du modèle\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:08:16.898295Z","iopub.execute_input":"2024-10-23T17:08:16.899229Z","iopub.status.idle":"2024-10-23T17:08:18.008146Z","shell.execute_reply.started":"2024-10-23T17:08:16.899185Z","shell.execute_reply":"2024-10-23T17:08:18.007205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_images_rgb, train_labels_binary, \n                    validation_data=(test_images_rgb, test_labels_binary), \n                    epochs=50, \n                    batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:08:25.607409Z","iopub.execute_input":"2024-10-23T17:08:25.607767Z","iopub.status.idle":"2024-10-23T17:15:13.744943Z","shell.execute_reply.started":"2024-10-23T17:08:25.607734Z","shell.execute_reply":"2024-10-23T17:15:13.744087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = model.evaluate(test_images_rgb, test_labels_binary)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:15:17.784019Z","iopub.execute_input":"2024-10-23T17:15:17.784717Z","iopub.status.idle":"2024-10-23T17:15:19.21754Z","shell.execute_reply.started":"2024-10-23T17:15:17.784675Z","shell.execute_reply":"2024-10-23T17:15:19.216525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['accuracy'], label='train_accuracy')\nplt.plot(history.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history.history['loss'], label='train_loss')\nplt.plot(history.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:15:21.818036Z","iopub.execute_input":"2024-10-23T17:15:21.818717Z","iopub.status.idle":"2024-10-23T17:15:22.395033Z","shell.execute_reply.started":"2024-10-23T17:15:21.818663Z","shell.execute_reply":"2024-10-23T17:15:22.394086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = model.predict(test_images_rgb)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_binary, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_binary, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()\n\naccuracy = np.trace(conf_matrix) / np.sum(conf_matrix)\naccuracy_percentage = accuracy * 100\nprint(f'Exactitude : {accuracy_percentage:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T17:15:26.852082Z","iopub.execute_input":"2024-10-23T17:15:26.852887Z","iopub.status.idle":"2024-10-23T17:15:33.291742Z","shell.execute_reply.started":"2024-10-23T17:15:26.852845Z","shell.execute_reply":"2024-10-23T17:15:33.290727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Resnet","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\n\ndef residual_block(x, filters):\n    # Save the original input for the residual connection\n    shortcut = x\n\n    # First convolution layer\n    x = layers.Conv2D(filters, (3, 3), padding='same', activation='relu')(x)\n    x = layers.BatchNormalization()(x)\n\n    # Second convolution layer\n    x = layers.Conv2D(filters, (3, 3), padding='same')(x)\n    x = layers.BatchNormalization()(x)\n\n    # Shortcut connection (add the original input to the output)\n    x = layers.add([x, shortcut])\n    x = layers.Activation('relu')(x)\n\n    return x\n\n# Define the input shape (128, 128, 3) for your images\ninput = layers.Input(shape=(128, 128, 3))\n\n# First convolution layer (without residual block)\nx = layers.Conv2D(32, (3, 3), padding='same', activation='relu')(input)\nx = layers.BatchNormalization()(x)\n\n# Add a residual block\nx = residual_block(x, 32)\nx = layers.MaxPooling2D(pool_size=(2, 2))(x)\nx = layers.Dropout(0.5)(x)\n\n# Second convolution block with a residual block\nx = layers.Conv2D(64, (3, 3), padding='same', activation='relu')(x)\nx = layers.BatchNormalization()(x)\nx = residual_block(x, 64)\nx = layers.MaxPooling2D(pool_size=(2, 2))(x)\nx = layers.Dropout(0.5)(x)\n\n# Third convolution block with a residual block\nx = layers.Conv2D(128, (3, 3), padding='same', activation='relu')(x)\nx = layers.BatchNormalization()(x)\nx = residual_block(x, 128)\nx = layers.MaxPooling2D(pool_size=(2, 2))(x)\nx = layers.Dropout(0.5)(x)\n\n# Flatten and add fully connected layers\nx = layers.Flatten()(x)\nx = layers.Dense(128, activation='relu')(x)\nx = layers.BatchNormalization()(x)\nx = layers.Dropout(0.5)(x)\n\n# Output layer (2 classes for binary classification or 10 for multi-class)\noutput = layers.Dense(2, activation='softmax')(x)  # Change to 10 if needed\n\n# Create the ResNet model\nresnet_model = models.Model(inputs=input, outputs=output)\n\n# Compile the model\nresnet_model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Summary of the model\nresnet_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:47:10.757951Z","iopub.execute_input":"2024-10-23T18:47:10.758344Z","iopub.status.idle":"2024-10-23T18:47:11.01522Z","shell.execute_reply.started":"2024-10-23T18:47:10.758304Z","shell.execute_reply":"2024-10-23T18:47:11.014118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Assurez-vous que train_images_rgb et train_labels sont déjà préparés\nhistory_resnet = resnet_model.fit(train_images_rgb, train_labels, \n                                    validation_data=(test_images_rgb, test_labels), \n                                    epochs=50, \n                                    batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:47:15.417904Z","iopub.execute_input":"2024-10-23T18:47:15.418747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loss, test_acc = resnet_model.evaluate(test_images_rgb, test_labels)\nprint(f\"Test accuracy: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:23:28.056183Z","iopub.execute_input":"2024-10-23T18:23:28.05693Z","iopub.status.idle":"2024-10-23T18:23:30.578671Z","shell.execute_reply.started":"2024-10-23T18:23:28.056887Z","shell.execute_reply":"2024-10-23T18:23:30.577696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_resnet.history['accuracy'], label='train_accuracy')\nplt.plot(history_resnet.history['val_accuracy'], label='val_accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(history_resnet.history['loss'], label='train_loss')\nplt.plot(history_resnet.history['val_loss'], label='val_loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:23:50.362675Z","iopub.execute_input":"2024-10-23T18:23:50.363364Z","iopub.status.idle":"2024-10-23T18:23:50.84519Z","shell.execute_reply.started":"2024-10-23T18:23:50.363316Z","shell.execute_reply":"2024-10-23T18:23:50.844316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prédictions du modèle\ny_pred = resnet_model.predict(test_images_rgb)\n\n# Convertir les prédictions en labels (classe avec la plus grande probabilité)\ny_pred_labels = np.argmax(y_pred, axis=1)\n\n# Convertir les labels réels en 1D (retirer l'encodage one-hot)\ntest_labels_1d = np.argmax(test_labels, axis=1)\n\n# Comparer les vraies valeurs avec les valeurs prédites\ncomparison = pd.DataFrame({'Actual': test_labels_1d, 'Predicted': y_pred_labels})\nprint(comparison.head())\n\n# Matrice de confusion\nconf_matrix = confusion_matrix(test_labels_1d, y_pred_labels)\n\n# Visualisation de la matrice de confusion\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Non-Cancer', 'Cancer'], \n            yticklabels=['Non-Cancer', 'Cancer'])\nplt.ylabel('Vrai label')\nplt.xlabel('Label prédit')\nplt.show()\n\naccuracy = np.trace(conf_matrix) / np.sum(conf_matrix)\naccuracy_percentage = accuracy * 100\nprint(f'Exactitude : {accuracy_percentage:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2024-10-23T18:25:00.799874Z","iopub.execute_input":"2024-10-23T18:25:00.800649Z","iopub.status.idle":"2024-10-23T18:25:01.732479Z","shell.execute_reply.started":"2024-10-23T18:25:00.800601Z","shell.execute_reply":"2024-10-23T18:25:01.731516Z"},"trusted":true},"execution_count":null,"outputs":[]}]}