Salut, j’ai essayé de créer un réseau Unet , mais au moment de l’entraîner sur des photos de tailles 768,1024 avec un batch de 32 j’avais des problèmes de connexion GPU ou mémoire qui était toujours limitante. j’ai suivi les recommandations de chat gpt, réduit le batch à 1, j’ai fait un resize de mes images de moitié 384 et 512 et j’ai utilisé le CPU à la place du GPU, et mon kernel meurt. Je ne sais pas quoi faire la version de tensorflow que j’utilise est la 2.6.2. Je travaille dans un environnement créé par des pros. et ne l’étant pas, j’ai pris la dernière version de tf, puis une qui correspond à peu près à la date de création de leur environnement en me disant que depuis (02/2023) il y avait peut être des incompatibilités.
Mon code ci-dessous (si déjà au niveau du unet il n y a pas d 'erreurs tant mieux) et j’ai mis une sorte de fonction pour essayer de recycler l’outil du cours qui déforme les images
import des librairies
`import tensorflow
import cv2
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
import os
import shutil
import re
import time
import datetime
import sys
import pickle
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
import numpy as np
from tensorflow.keras.preprocessing.image import img_to_array, load_img
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, Dropout
from tensorflow.keras.layers import BatchNormalization, Activation, MaxPool2D, Conv2DTranspose, Concatenate
#Préliminaires
Chemins
path = ‘/home/data/results/odo_unet’
origine = path+‘/’+‘origine’
mask = path+‘/’+‘mask’
image_folder = origine
mask_folder = mask
Liste des noms de fichiers dans les dossiers
image_files = os.listdir(image_folder)
mask_files = os.listdir(mask_folder)
Nombre total d’images dans le dataset
num_images = len(image_files)
Indice pour diviser le dataset entre entraînement et validation (par exemple, 80% pour l’entraînement)
train_val_split = int(0.8 * num_images)
train_indices = np.arange(train_val_split)
val_indices = np.arange(train_val_split, num_images)
Définition du générateur de données avec augmentation
def custom_image_generator(indices, batch_size, image_folder, mask_folder)):
# Configurer l’augmentation de données
data_gen_args = dict(
rescale=1/255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=40,
width_shift_range=0.5,
height_shift_range=0.5,
horizontal_flip=True,
vertical_flip=True,
fill_mode=‘nearest’
)
image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)
while True:
# Mélange aléatoire des indices à chaque époque
np.random.shuffle(indices)
for start in range(0, len(indices), batch_size):
end = min(start + batch_size, len(indices))
batch_indices = indices[start:end]
# Initialisation des listes pour les images et les masques
input_images = []
output_images = []
for i in batch_indices:
# Chargement de l'image
input_array = cv2.imread(os.path.join(image_folder, image_files[i]))
input_array = cv2.resize(input_array, (1024//2, 768//2))
# Augmentation de l'image
img_augmented = image_datagen.random_transform(input_array)
input_images.append(img_augmented / 255.0)
# Chargement du masque
mask_array = cv2.imread(os.path.join(mask_folder, mask_files[i]))
mask_array = cv2.resize(mask_array, (1024//2, 768//2))
# Augmentation du masque
mask_augmented = mask_datagen.random_transform(mask_array)
output_images.append(mask_augmented / 255.0)
yield (np.array(input_images), np.array(output_images))
Taille du batch
batch_size = 32
Générateurs pour les ensembles d’entraînement et de validation
train_generator = custom_image_generator(train_indices, batch_size, image_folder, mask_folder)
val_generator = custom_image_generator(val_indices, batch_size, image_folder, mask_folder)
Reseau Unet
def conv_block(input, num_filters):
x = Conv2D(num_filters, 3, padding=“same”)(input)
x = BatchNormalization()(x)
x = Activation(“relu”)(x)
x = Conv2D(num_filters, 3, padding="same")(x)
x = BatchNormalization()(x)
x = Activation("relu")(x)
return x
def encoder_block(input, num_filters):
x = conv_block(input, num_filters)
p = MaxPool2D((2, 2))(x)
return x, p
def decoder_block(input, skip_features, num_filters):
x = Conv2DTranspose(num_filters, (2, 2), strides=2, padding=“same”)(input)
x = Concatenate()([x, skip_features])
x = conv_block(x, num_filters)
return x
def build_unet(input_shape):
inputs = Input(input_shape)
s1, p1 = encoder_block(inputs, 64)
s2, p2 = encoder_block(p1, 128)
s3, p3 = encoder_block(p2, 256)
s4, p4 = encoder_block(p3, 512)
b1 = conv_block(p4, 1024)
d1 = decoder_block(b1, s4, 512)
d2 = decoder_block(d1, s3, 256)
d3 = decoder_block(d2, s2, 128)
d4 = decoder_block(d3, s1, 64)
num_classes = 7
# outputs = Conv2D(num_classes, 1, padding="same", activation="sigmoid")(d4)
outputs = Conv2D(num_classes, 1, padding="same", activation="softmax")(d4)
model = Model(inputs, outputs, name="U-Net")
return model
unet = build_unet((768//2,1024//2, 3))
print(unet.summary())
model_checkpoint = ModelCheckpoint(‘best_model.h5’, save_best_only=True, save_weights_only=True, monitor=‘val_loss’, mode=‘min’, verbose=1)
early_stopping = EarlyStopping(monitor=‘val_loss’, patience=5, mode=‘min’, verbose=1)
reduce_lr = ReduceLROnPlateau(monitor=‘val_loss’, factor=0.2, patience=3, min_lr=1e-6, mode=‘min’, verbose=1)
Compile the model with a specific initial learning rate
initial_learning_rate = 0.0001
optimizer = Adam(learning_rate=initial_learning_rate)
Compile the model
unet.compile(optimizer=optimizer, loss=‘categorical_crossentropy’, metrics=[‘accuracy’])
print(“modèle compilé”)
epochs = 10
Taille du batch
batch_size = 1
Fit
history = unet.fit(
train_generator,
steps_per_epoch=len(train_indices) // batch_size,
epochs=epochs,
validation_data=val_generator,
validation_steps=len(val_indices) // batch_size,
callbacks=[ early_stopping, reduce_lr]
)
print(‘ok’)
import time
time.sleep(10)
`
voilà si qq1 voit qqchose de suspect… Qu’il n’hésite pas.
Cordialement ,