From 030682c4be20b9cdd92855caba47b47136132415 Mon Sep 17 00:00:00 2001 From: "maxamed.nuurmaxa" <maxamed.nuurmaxamed@master.hes-so.ch> Date: Fri, 4 Apr 2025 20:08:03 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20mod=C3=A8le=20de=20segmentation=20?= =?UTF-8?q?U-Net=20pour=20la=20segmentation=20d'images.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Model_siamois_finale.py" | 131 +++++++++++------- 1 file changed, 79 insertions(+), 52 deletions(-) diff --git "a/R\303\251seau_siamois/Model_siamois_finale.py" "b/R\303\251seau_siamois/Model_siamois_finale.py" index f95deeb..3d95556 100644 --- "a/R\303\251seau_siamois/Model_siamois_finale.py" +++ "b/R\303\251seau_siamois/Model_siamois_finale.py" @@ -517,62 +517,89 @@ plt.show() #%% Fonction qui créer le modèle et une fonction qui calcul la distance -def build_siamese_model(inputShape, embeddingDim=48): - # spécifie les entrées pour le réseau extracteur de caractéristiques - # applique les couches partagées aux entrées de chaque branche - l0a = Input(inputShape, name="l0a") # Entrée A - - l1a = Conv2D(64, (2, 2), padding="valid", activation="relu", name='l1a')(l0a) # Couche de convolution partagée 1 - l1a_mp = MaxPooling2D(pool_size=(2, 2), name='l1a_mp')(l1a) # Couche de pooling partagée 1 - l1a_dp = Dropout(0.3)(l1a_mp) # Couche de dropout partagée - # l1a_bm = BatchNormalization()(l1a_dp) - - l2a = Conv2D(64, (2, 2), padding="valid", activation="relu", name='l2a')(l1a_dp) # Couche de convolution partagée 2 - l2a_mp = MaxPooling2D(pool_size=(2,2), name='l2a_mp')(l2a) # Couche de pooling partagée 2 - l2a_dp = Dropout(0.3)(l2a_mp) # Couche de dropout partagée - # l2a_bm = BatchNormalization()(l2a_dp) - - # l3a = Conv2D(8, (2, 2), padding="same", activation="relu", name='l3a')(l2a_dp) # Couche de convolution partagée 3 - # l3a_dp = Dropout(0.3)(l3a) # Couche de dropout partagée - # l3a_mp = MaxPooling2D(pool_size=(2,2), name='l3a_mp')(l3a_dp) # Couche de pooling partagée 2 - - - # l4a = Conv2D(8, (2, 2), padding="same", activation="relu", name='l4a')(l3a_mp) # Couche de convolution partagée 3 - # l4a_dp = Dropout(0.3)(l4a) # Couche de dropout partagée - # l4a_mp = MaxPooling2D(pool_size=2, name='l4a_mp')(l4a_dp) # Couche de pooling partagée 2 - +from tensorflow.keras.layers import Conv2D, Conv2DTranspose, MaxPooling2D, UpSampling2D, BatchNormalization, Dropout +from tensorflow.keras.models import Model +from tensorflow.keras.layers import Input - pooledOutputX = GlobalAveragePooling2D()(l2a_dp) # Pooling global pour la sortie X - outputsX = Dense(embeddingDim)(pooledOutputX) # Couche dense pour la sortie X +# Fonction pour créer un modèle de segmentation (comme U-Net) +def build_segmentation_model(input_shape): + inputs = Input(input_shape) + + # Encodeur (Contracting path) + c1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs) + c1 = BatchNormalization()(c1) + c1 = Conv2D(64, (3, 3), activation='relu', padding='same')(c1) + c1 = BatchNormalization()(c1) + p1 = MaxPooling2D((2, 2))(c1) + p1 = Dropout(0.2)(p1) + + c2 = Conv2D(128, (3, 3), activation='relu', padding='same')(p1) + c2 = BatchNormalization()(c2) + c2 = Conv2D(128, (3, 3), activation='relu', padding='same')(c2) + c2 = BatchNormalization()(c2) + p2 = MaxPooling2D((2, 2))(c2) + p2 = Dropout(0.3)(p2) + + c3 = Conv2D(256, (3, 3), activation='relu', padding='same')(p2) + c3 = BatchNormalization()(c3) + c3 = Conv2D(256, (3, 3), activation='relu', padding='same')(c3) + c3 = BatchNormalization()(c3) + p3 = MaxPooling2D((2, 2))(c3) + p3 = Dropout(0.4)(p3) + + c4 = Conv2D(512, (3, 3), activation='relu', padding='same')(p3) + c4 = BatchNormalization()(c4) + c4 = Conv2D(512, (3, 3), activation='relu', padding='same')(c4) + c4 = BatchNormalization()(c4) + p4 = MaxPooling2D((2, 2))(c4) + p4 = Dropout(0.5)(p4) + + # Bouteille de goulot (bottleneck) + c5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(p4) + c5 = BatchNormalization()(c5) + c5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(c5) + c5 = BatchNormalization()(c5) + + # Décodeur (Expanding path) + u6 = Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(c5) + u6 = Dropout(0.5)(u6) + u6 = Conv2D(512, (3, 3), activation='relu', padding='same')(u6) + u6 = BatchNormalization()(u6) + u6 = Conv2D(512, (3, 3), activation='relu', padding='same')(u6) + u6 = BatchNormalization()(u6) + + u7 = Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(u6) + u7 = Dropout(0.4)(u7) + u7 = Conv2D(256, (3, 3), activation='relu', padding='same')(u7) + u7 = BatchNormalization()(u7) + u7 = Conv2D(256, (3, 3), activation='relu', padding='same')(u7) + u7 = BatchNormalization()(u7) + + u8 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(u7) + u8 = Dropout(0.3)(u8) + u8 = Conv2D(128, (3, 3), activation='relu', padding='same')(u8) + u8 = BatchNormalization()(u8) + u8 = Conv2D(128, (3, 3), activation='relu', padding='same')(u8) + u8 = BatchNormalization()(u8) + + u9 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(u8) + u9 = Dropout(0.2)(u9) + u9 = Conv2D(64, (3, 3), activation='relu', padding='same')(u9) + u9 = BatchNormalization()(u9) + u9 = Conv2D(64, (3, 3), activation='relu', padding='same')(u9) + u9 = BatchNormalization()(u9) + + # Sortie + outputs = Conv2D(1, (1, 1), activation='sigmoid')(u9) # Pour segmentation binaire (0 ou 1) + + # Créer le modèle + model = Model(inputs=inputs, outputs=outputs) - # crée le modèle - model = Model(inputs=l0a, outputs=outputsX) - return model -def euclidean_distance(vectors): - # décompose les vecteurs en listes distinctes - (featsA, featsB) = vectors # Vecteurs A et B - # calcule la somme des distances au carré entre les vecteurs - sumSquared = K.sum(K.square(featsA - featsB), axis=1, keepdims=True) # Somme des distances au carré - # retourne la distance euclidienne entre les vecteurs - return K.sqrt(K.maximum(sumSquared, K.epsilon())) # Distance euclidienne - -#%% Creation du modele - -input_shape=(target_size[1], target_size[0], 1) - -img_empty = Input(shape=input_shape) -img_full = Input(shape=input_shape) - -featureExtractor = build_siamese_model(input_shape) -featsA = featureExtractor(img_empty) -featsB = featureExtractor(img_full) - -distance = Layer(trainable=False)(euclidean_distance)([featsA, featsB]) - -outputs = Dense(1, activation="sigmoid")(distance) -model = Model(inputs=[img_empty, img_full], outputs=outputs) +# Créer le modèle de segmentation +input_shape = (150, 200, 1) # La taille d'entrée que vous avez (150x200 avec un seul canal) +model = build_segmentation_model(input_shape) model.summary() -- GitLab