CARIA.2.1

Update for the final presentation
huge change with previous version
This commit is contained in:
ccunatbrule
2024-09-03 12:08:48 +02:00
parent 194398cebc
commit 3e6785fec2
207 changed files with 57229 additions and 409 deletions

View File

@@ -0,0 +1,59 @@
import cv2
import os
import numpy as np
import pickle
from pathlib import Path
# Définir les chemins
IMAGE_DIR = Path(r"W:/CARIA/images/avatars")
LABELS_FILE = Path("server-ia/data/modeles/CV2/labels.pickle")
TRAINER_FILE = Path("server-ia/data/modeles/CV2/trainner.yml")
# Initialiser les variables
current_id = 0
label_ids = {}
x_train = []
y_labels = []
def process_images(image_dir):
global current_id, label_ids, x_train, y_labels
print("Début du traitement des images...")
for root, _, files in os.walk(image_dir):
if files:
label = Path(root).name
for file in files:
if file.lower().endswith(".jpg"):
path = Path(root) / file
if label not in label_ids:
label_ids[label] = current_id
current_id += 1
id_ = label_ids[label]
image = cv2.imread(str(path), cv2.IMREAD_GRAYSCALE)
if image is not None:
x_train.append(image)
y_labels.append(id_)
print(f"Traitement terminé. {len(x_train)} images chargées.")
def save_data():
print("Sauvegarde des étiquettes...")
with open(LABELS_FILE, "wb") as f:
pickle.dump(label_ids, f)
print(f"Étiquettes sauvegardées dans {LABELS_FILE}.")
def train_recognizer():
print("Entraînement du reconnaisseur...")
x_train_np = np.array(x_train)
y_labels_np = np.array(y_labels)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(x_train_np, y_labels_np)
recognizer.save(str(TRAINER_FILE))
print(f"Modèle entraîné et sauvegardé dans {TRAINER_FILE}.")
def main():
process_images(IMAGE_DIR)
save_data()
train_recognizer()
print("Traitement complet. Les modèles ont été sauvegardés.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,99 @@
import os
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import AveragePooling2D, Dropout, Flatten, Dense, Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import numpy as np
# Définir les chemins des données d'entraînement et de validation
train_data_dir = "server-trainer/images/road_sign_trainers/train_full"
valid_data_dir = "server-trainer/images/road_sign_trainers/test_full"
# Initialiser les hyperparamètres
INIT_LR = 1e-4
EPOCHS = 1
BS = 32
# Charger et prétraiter les images
train_datagen = ImageDataGenerator(
rescale=1.0 / 255,
rotation_range=20,
zoom_range=0.15,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.15,
horizontal_flip=True,
fill_mode="nearest"
)
valid_datagen = ImageDataGenerator(rescale=1.0 / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(224, 224),
batch_size=BS,
class_mode='categorical'
)
valid_generator = valid_datagen.flow_from_directory(
valid_data_dir,
target_size=(224, 224),
batch_size=BS,
class_mode='categorical'
)
# Générer le fichier class_names.txt
class_names_file = os.path.join("server-ia/data/modeles/MobileNetV2", "class_names.txt")
with open(class_names_file, "w") as f:
# Utiliser le générateur class_indices pour récupérer les noms de classe et les écrire dans le fichier
for class_name, class_index in train_generator.class_indices.items():
f.write(f"{class_name}\n")
# Charger le modèle pré-entraîné MobileNetV2 sans la couche supérieure
base_model = MobileNetV2(
weights="imagenet",
include_top=False,
input_tensor=Input(shape=(224, 224, 3))
)
# Construire le modèle de tête qui sera placé au-dessus du modèle de base
head_model = base_model.output
head_model = AveragePooling2D(pool_size=(7, 7))(head_model)
head_model = Flatten(name="flatten")(head_model)
head_model = Dense(128, activation="relu")(head_model)
head_model = Dropout(0.5)(head_model)
head_model = Dense(len(train_generator.class_indices), activation="softmax")(head_model)
# Combiner le modèle de base avec le modèle de tête
model = Model(inputs=base_model.input, outputs=head_model)
# Geler les couches du modèle de base
for layer in base_model.layers:
layer.trainable = False
# Compiler le modèle
opt = Adam(learning_rate=INIT_LR)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
# Entraîner le modèle
history = model.fit(
train_generator,
steps_per_epoch=len(train_generator),
validation_data=valid_generator,
validation_steps=len(valid_generator),
epochs=EPOCHS
)
# Sauvegarder le modèle
model.save("server-ia/data/modeles/MobileNetV2/modele_signaux_routiers.keras")
# Évaluer le modèle
print("[INFO] Évaluation du modèle...")
predictions = model.predict(valid_generator, steps=len(valid_generator), verbose=1)
predictions = np.argmax(predictions, axis=1)
print(classification_report(valid_generator.classes, predictions, target_names=valid_generator.class_indices.keys()))

View File

@@ -0,0 +1,220 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import os
import time
from tqdm import tqdm
# Fonction pour charger les labels depuis un fichier CSV
def load_labels_from_csv(filepath):
filenames, labels = [], []
with open(filepath, 'r') as file:
next(file) # Skip header
for line in file:
parts = line.strip().split(',')
if len(parts) == 2:
filenames.append(parts[0])
labels.append(parts[1])
return filenames, labels
# Chargement des fichiers CSV des labels
panneaux_filenames, panneaux_labels = load_labels_from_csv('server-trainer/images/vitesse_panneaux_labels.csv')
autres_filenames, autres_labels = load_labels_from_csv('server-trainer/images/autres_panneaux_labels.csv')
sans_filenames, sans_labels = load_labels_from_csv('server-trainer/images/genere_sans_panneaux_labels.csv')
# Création d'un dictionnaire pour les labels
def create_label_dict(filenames, labels):
label_dict = {i: label for i, label in enumerate(labels)}
return label_dict
# Dictionnaires de labels
panneaux_labels_dict = create_label_dict(panneaux_filenames, panneaux_labels)
autres_labels_dict = create_label_dict(autres_filenames, autres_labels)
sans_labels_dict = {0: "Sans panneau"}
# Configuration
size = 60
dir_images_panneaux = "server-trainer/images/vitesse_panneaux"
dir_images_autres_panneaux = "server-trainer/images/autres_panneaux"
dir_images_genere_sans_panneaux = "server-trainer/images/genere_sans_panneaux"
batch_size = 128
nbr_entrainement = 1 # Nombre d'époques d'entraînement
print(f"Configuration : taille des images = {size}, taille du batch = {batch_size}, nombre d'époques = {nbr_entrainement}")
# Définition du modèle
def panneau_model(nbr_classes):
print(f"Création du modèle avec {nbr_classes} classes.")
model = tf.keras.Sequential([
layers.Input(shape=(size, size, 3)),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.Dropout(0.2),
layers.BatchNormalization(),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.Dropout(0.2),
layers.BatchNormalization(),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.Dropout(0.3),
layers.BatchNormalization(),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.Dropout(0.4),
layers.BatchNormalization(),
layers.MaxPool2D(pool_size=2),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.BatchNormalization(),
layers.Dense(nbr_classes, activation='sigmoid')
])
print("Modèle créé.")
return model
# Chargement des images depuis un répertoire
def load_images_from_directory(directory, size):
if not os.path.exists(directory):
raise FileNotFoundError(f"Le répertoire d'images n'existe pas : {directory}")
files = [f for f in sorted(os.listdir(directory)) if f.endswith(".png")]
if not files:
raise FileNotFoundError(f"Le répertoire d'images est vide : {directory}")
images = []
for file in files:
path = os.path.join(directory, file)
image = cv2.imread(path)
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
images.append(image)
return images
# Préparation des données
def prepare_data(panneaux_images, autres_images, sans_panneaux_images, panneau_labels_dict):
print("Préparation des données pour les images de panneaux...")
tab_images = np.array([])
tab_labels = np.array([])
# Images de panneaux
for i, image in enumerate(panneaux_images):
lot = np.array([image for _ in range(120)])
if tab_images.size == 0:
tab_images = lot
else:
tab_images = np.concatenate((tab_images, lot), axis=0)
labels = np.eye(len(panneaux_labels_dict))[i]
labels = np.repeat([labels], len(lot), axis=0)
if tab_labels.size == 0:
tab_labels = labels
else:
tab_labels = np.concatenate([tab_labels, labels], axis=0)
print(f"Nombre d'images après ajout des panneaux : {len(tab_images)}")
print(f"Nombre de labels après ajout des panneaux : {len(tab_labels)}")
# Images des autres panneaux
print("Traitement des autres panneaux...")
for image in autres_images:
lot = np.array([image for _ in range(700)])
if tab_images.size == 0:
tab_images = lot
else:
tab_images = np.concatenate([tab_images, lot], axis=0)
labels = np.zeros((len(lot), len(panneaux_labels_dict)))
if tab_labels.size == 0:
tab_labels = labels
else:
tab_labels = np.concatenate([tab_labels, labels], axis=0)
print(f"Nombre d'images après ajout des autres panneaux : {len(tab_images)}")
print(f"Nombre de labels après ajout des autres panneaux : {len(tab_labels)}")
# Images générées sans panneaux
print("Traitement des images générées sans panneaux...")
sans_panneaux_images = [cv2.resize(img, (size, size)) for img in sans_panneaux_images]
tab_images = np.concatenate([tab_images, np.array(sans_panneaux_images)], axis=0)
tab_labels = np.concatenate([tab_labels, np.zeros((len(sans_panneaux_images), len(panneaux_labels_dict)))], axis=0)
print(f"Nombre d'images après ajout des images sans panneaux : {len(tab_images)}")
print(f"Nombre de labels après ajout des images sans panneaux : {len(tab_labels)}")
# Normalisation
tab_images = tab_images.astype(np.float32) / 255
tab_labels = tab_labels.astype(np.float32)
return tab_images, tab_labels
# Chargement des images
panneaux_images = load_images_from_directory(dir_images_panneaux, size)
autres_images = load_images_from_directory(dir_images_autres_panneaux, size)
sans_panneaux_images = load_images_from_directory(dir_images_genere_sans_panneaux, size)
# Préparation des données
tab_images, tab_labels = prepare_data(panneaux_images, autres_images, sans_panneaux_images, panneaux_labels_dict)
# Division du jeu de données
train_images, test_images, train_labels, test_labels = train_test_split(tab_images, tab_labels, test_size=0.10, random_state=42)
print(f"Nombre d'images d'entraînement : {len(train_images)}, Nombre d'images de test : {len(test_images)}")
train_ds = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(batch_size)
# Compilation du modèle
model_panneau = panneau_model(len(panneaux_labels_dict))
model_panneau.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
print("Modèle compilé.")
# Entraînement du modèle avec barre de progression pour chaque époque
def train(model, train_ds, test_ds, nbr_entrainement):
for epoch in range(nbr_entrainement):
print(f"Début de l'entraînement {epoch + 1}...")
start = time.time()
# Nombre de batches dans une époque
num_batches = len(train_ds)
# Initialiser tqdm pour les batches
with tqdm(total=num_batches, desc=f"Époque {epoch + 1}", unit='batch') as pbar:
for batch_images, batch_labels in train_ds:
history = model.train_on_batch(batch_images, batch_labels)
pbar.update(1) # Mise à jour de la barre de progression
# Afficher les résultats après l'époque
train_loss, train_accuracy = history
print(f'Entraînement {epoch + 1:04d} : perte : {train_loss:6.4f}, précision : {train_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
test(model, test_ds)
def test(model, test_ds):
print("Début du test...")
start = time.time()
test_loss, test_accuracy = model.evaluate(test_ds, verbose=0)
print(f' >>> Test : perte : {test_loss:6.4f}, précision : {test_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
print("Début de l'entraînement du modèle.")
train(model_panneau, train_ds, test_ds, nbr_entrainement)
model_panneau.save("server-ia/data/modeles/tensorflow/tf_modele_AllRoadSign.keras")
print(f"Modèle sauvegardé à : {os.path.abspath(model_panneau)}")
# Évaluation des prédictions
print("Évaluation des prédictions sur les images de test.")
for i in range(len(test_images)):
prediction = model_panneau.predict(np.array([test_images[i]]))
predicted_index = np.argmax(prediction[0])
confidence = np.max(prediction[0])
# Affichage du label correspondant
if confidence < 0.6:
print("Ce n'est pas un panneau")
else:
print(f"C'est un panneau : {panneaux_labels_dict.get(predicted_index, 'Inconnu')}")
# Affichage de l'image
cv2.imshow("image", test_images[i])
if cv2.waitKey() & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

View File

@@ -0,0 +1,167 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import pandas as pd
import os
import time
from tqdm import tqdm
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
import matplotlib.pyplot as plt
# Configuration
size = 60
csv_file = "server-trainer/images/autres_panneaux_labels.csv"
image_dir = "server-trainer/images/autres_panneaux/"
batch_size = 128
nbr_entrainement = 10 # Nombre d'époques d'entraînement
print(f"Configuration : taille des images = {size}, taille du batch = {batch_size}, nombre d'époques = {nbr_entrainement}")
# Définition du modèle
def panneau_model(nbr_classes):
print(f"Création du modèle avec {nbr_classes} classes.")
model = tf.keras.Sequential([
layers.Input(shape=(size, size, 3)),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.Dense(nbr_classes, activation='softmax')
])
print("Modèle créé.")
return model
# Chargement des images et des labels depuis le CSV
def load_data_from_csv(csv_file, image_dir, size):
df = pd.read_csv(csv_file)
# Afficher les noms des colonnes pour débogage
print("Colonnes dans le CSV :", df.columns)
# Créer un dictionnaire pour mapper les labels alphanumériques à des indices
labels_mapping = {label: idx for idx, label in enumerate(df['label'].unique())}
print(f"Mapping des labels : {labels_mapping}")
images = []
labels = []
for _, row in df.iterrows():
# Assurer que les colonnes existent
if 'filename' not in row or 'label' not in row:
raise ValueError("Les colonnes 'filename' ou 'label' sont manquantes dans le CSV")
filename = row['filename']
label = row['label']
image_path = os.path.join(image_dir, filename)
# Charger et redimensionner l'image
image = cv2.imread(image_path)
if image is None:
print(f"Erreur de chargement de l'image : {image_path}")
continue
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
images.append(image)
labels.append(labels_mapping[label])
images = np.array(images, dtype=np.float32)
labels = np.array(labels, dtype=np.int32)
# Normalisation
images /= 255.0
return images, labels, labels_mapping, len(labels_mapping)
# Chargement des données
tab_images, tab_labels, labels_mapping, num_classes = load_data_from_csv(csv_file, image_dir, size)
# Créer un mappage inverse des labels
reverse_labels_mapping = {idx: label for label, idx in labels_mapping.items()}
# Division du jeu de données
train_images, test_images, train_labels, test_labels = train_test_split(tab_images, tab_labels, test_size=0.10, random_state=42)
print(f"Nombre d'images d'entraînement : {len(train_images)}, Nombre d'images de test : {len(test_images)}")
# Création des datasets TensorFlow
train_ds = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(batch_size)
# Compilation du modèle
model_panneau = panneau_model(num_classes)
model_panneau.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
print("Modèle compilé.")
# Entraînement du modèle avec barre de progression pour chaque époque
def train(model, train_ds, test_ds, nbr_entrainement):
for epoch in range(nbr_entrainement):
print(f"Début de l'entraînement {epoch + 1}...")
start = time.time()
# Nombre de batches dans une époque
num_batches = len(train_ds)
# Initialiser tqdm pour les batches
with tqdm(total=num_batches, desc=f"Époque {epoch + 1}", unit='batch') as pbar:
for batch_images, batch_labels in train_ds:
history = model.train_on_batch(batch_images, batch_labels)
pbar.update(1) # Mise à jour de la barre de progression
# Afficher les résultats après l'époque
train_loss, train_accuracy = history
print(f'Entraînement {epoch + 1:04d} : perte : {train_loss:6.4f}, précision : {train_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
test(model, test_ds)
def test(model, test_ds):
print("Début du test...")
start = time.time()
test_loss, test_accuracy = model.evaluate(test_ds, verbose=0)
print(f' >>> Test : perte : {test_loss:6.4f}, précision : {test_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
# Fonction d'évaluation
def evaluate_model(model, test_images, test_labels, labels_mapping):
# Obtenir les prédictions du modèle
predictions = model.predict(test_images)
predicted_labels = np.argmax(predictions, axis=1)
# Afficher la matrice de confusion
cm = confusion_matrix(test_labels, predicted_labels)
plt.figure(figsize=(10, 7))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=labels_mapping.keys(), yticklabels=labels_mapping.keys())
plt.xlabel('Prédiction')
plt.ylabel('Réel')
plt.title('Matrice de Confusion')
plt.show()
# Afficher le rapport de classification
print('Rapport de Classification:')
print(classification_report(test_labels, predicted_labels, target_names=labels_mapping.keys()))
print("Début de l'entraînement du modèle.")
train(model_panneau, train_ds, test_ds, nbr_entrainement)
model_panneau.save("server-ia/data/modeles/tensorflow/tf_modele_AutresRoadSign.keras")
print("Modèle sauvegardé.")
# Évaluation des prédictions
print("Évaluation des prédictions sur les images de test.")
for i in range(len(test_images)):
prediction = model_panneau.predict(np.array([test_images[i]]))
predicted_label_index = np.argmax(prediction[0])
predicted_label = reverse_labels_mapping[predicted_label_index]
actual_label = reverse_labels_mapping[test_labels[i]]
print(f"Image {i} - Prédiction : {predicted_label}, Label réel : {actual_label}")
# Affichage de l'image
cv2.imshow("image", test_images[i])
if cv2.waitKey() & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

View File

@@ -0,0 +1,166 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import pandas as pd
import os
import time
from tqdm import tqdm
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
import matplotlib.pyplot as plt
# Configuration
size = 60
csv_file = "server-trainer/images/vitesse_panneaux_labels.csv"
image_dir = "server-trainer/images/vitesse_panneaux/"
batch_size = 128
nbr_entrainement = 10 # Nombre d'époques d'entraînement
print(f"Configuration : taille des images = {size}, taille du batch = {batch_size}, nombre d'époques = {nbr_entrainement}")
# Définition du modèle
def panneau_model(nbr_classes):
print(f"Création du modèle avec {nbr_classes} classes.")
model = tf.keras.Sequential([
layers.Input(shape=(size, size, 3)),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.Dense(nbr_classes, activation='softmax')
])
print("Modèle créé.")
return model
# Chargement des images et des labels depuis le CSV
def load_data_from_csv(csv_file, image_dir, size):
df = pd.read_csv(csv_file)
# Afficher les noms des colonnes pour débogage
print("Colonnes dans le CSV :", df.columns)
# Créer un dictionnaire pour mapper les labels alphanumériques à des indices
labels_mapping = {label: idx for idx, label in enumerate(df['label'].unique())}
print(f"Mapping des labels : {labels_mapping}")
images = []
labels = []
for _, row in df.iterrows():
# Assurer que les colonnes existent
if 'filename' not in row or 'label' not in row:
raise ValueError("Les colonnes 'filename' ou 'label' sont manquantes dans le CSV")
filename = row['filename']
label = row['label']
image_path = os.path.join(image_dir, filename)
# Charger et redimensionner l'image
image = cv2.imread(image_path)
if image is None:
print(f"Erreur de chargement de l'image : {image_path}")
continue
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
images.append(image)
labels.append(labels_mapping[label])
images = np.array(images, dtype=np.float32)
labels = np.array(labels, dtype=np.int32)
# Normalisation
images /= 255.0
return images, labels, labels_mapping, len(labels_mapping)
# Chargement des données
tab_images, tab_labels, labels_mapping, num_classes = load_data_from_csv(csv_file, image_dir, size)
# Division du jeu de données
train_images, test_images, train_labels, test_labels = train_test_split(tab_images, tab_labels, test_size=0.10, random_state=42)
print(f"Nombre d'images d'entraînement : {len(train_images)}, Nombre d'images de test : {len(test_images)}")
# Création des datasets TensorFlow
train_ds = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(batch_size)
# Compilation du modèle
model_panneau = panneau_model(num_classes)
model_panneau.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
print("Modèle compilé.")
# Entraînement du modèle avec barre de progression pour chaque époque
def train(model, train_ds, test_ds, nbr_entrainement):
for epoch in range(nbr_entrainement):
print(f"Début de l'entraînement {epoch + 1}...")
start = time.time()
# Nombre de batches dans une époque
num_batches = len(train_ds)
# Initialiser tqdm pour les batches
with tqdm(total=num_batches, desc=f"Époque {epoch + 1}", unit='batch') as pbar:
for batch_images, batch_labels in train_ds:
history = model.train_on_batch(batch_images, batch_labels)
pbar.update(1) # Mise à jour de la barre de progression
# Afficher les résultats après l'époque
train_loss, train_accuracy = history
print(f'Entraînement {epoch + 1:04d} : perte : {train_loss:6.4f}, précision : {train_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
test(model, test_ds)
def test(model, test_ds):
print("Début du test...")
start = time.time()
test_loss, test_accuracy = model.evaluate(test_ds, verbose=0)
print(f' >>> Test : perte : {test_loss:6.4f}, précision : {test_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
# Fonction d'évaluation
def evaluate_model(model, test_images, test_labels, labels_mapping):
# Obtenir les prédictions du modèle
predictions = model.predict(test_images)
predicted_labels = np.argmax(predictions, axis=1)
# Afficher la matrice de confusion
cm = confusion_matrix(test_labels, predicted_labels)
plt.figure(figsize=(10, 7))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=labels_mapping.keys(), yticklabels=labels_mapping.keys())
plt.xlabel('Prédiction')
plt.ylabel('Réel')
plt.title('Matrice de Confusion')
plt.show()
# Afficher le rapport de classification
print('Rapport de Classification:')
print(classification_report(test_labels, predicted_labels, target_names=labels_mapping.keys()))
print("Début de l'entraînement du modèle.")
train(model_panneau, train_ds, test_ds, nbr_entrainement)
# Chemin de sauvegarde du modèle
model_save_path = "server-ia/data/modeles/tensorflow/tf_modele_VitesseRoadSign.keras"
model_panneau.save(model_save_path)
print(f"Modèle sauvegardé à l'emplacement : {model_save_path}")
# Évaluation des prédictions
print("Évaluation des prédictions sur les images de test.")
evaluate_model(model_panneau, test_images, test_labels, labels_mapping)
# Visualisation des images de test avec prédictions
print("Visualisation des prédictions sur les images de test.")
for i in range(len(test_images)):
prediction = model_panneau.predict(np.array([test_images[i]]))
predicted_label = np.argmax(prediction[0])
actual_label = test_labels[i]
print(f"Image {i} - Réel : {actual_label}, Prédiction : {predicted_label}")
cv2.imshow(f"Image {i} - Réel : {actual_label}, Prédiction : {predicted_label}", test_images[i])
if cv2.waitKey() & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

View File

@@ -0,0 +1,142 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import pandas as pd
import os
import time
from tqdm import tqdm
# Configuration
size = 60
csv_file = "server-trainer/images/vitesse_panneaux_labels.csv"
image_dir = "server-trainer/images/vitesse_panneaux/"
batch_size = 128
nbr_entrainement = 10 # Nombre d'époques d'entraînement
print(f"Configuration : taille des images = {size}, taille du batch = {batch_size}, nombre d'époques = {nbr_entrainement}")
# Définition du modèle
def panneau_model(nbr_classes):
print(f"Création du modèle avec {nbr_classes} classes.")
model = tf.keras.Sequential([
layers.Input(shape=(size, size, 3)),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.Dense(nbr_classes, activation='softmax')
])
print("Modèle créé.")
return model
# Chargement des images et des labels depuis le CSV
def load_data_from_csv(csv_file, image_dir, size):
df = pd.read_csv(csv_file)
# Afficher les noms des colonnes pour débogage
print("Colonnes dans le CSV :", df.columns)
# Créer un dictionnaire pour mapper les labels alphanumériques à des indices
labels_mapping = {label: idx for idx, label in enumerate(df['label'].unique())}
reverse_labels_mapping = {idx: label for label, idx in labels_mapping.items()} # Inverse du mapping pour affichage
print(f"Mapping des labels : {labels_mapping}")
images = []
labels = []
for _, row in df.iterrows():
# Assurer que les colonnes existent
if 'filename' not in row or 'label' not in row:
raise ValueError("Les colonnes 'filename' ou 'label' sont manquantes dans le CSV")
filename = row['filename']
label = row['label']
image_path = os.path.join(image_dir, filename)
# Charger et redimensionner l'image
image = cv2.imread(image_path)
if image is None:
print(f"Erreur de chargement de l'image : {image_path}")
continue
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
images.append(image)
labels.append(labels_mapping[label])
images = np.array(images, dtype=np.float32)
labels = np.array(labels, dtype=np.int32)
# Normalisation
images /= 255.0
return images, labels, len(labels_mapping), reverse_labels_mapping
# Chargement des données
tab_images, tab_labels, num_classes, reverse_labels_mapping = load_data_from_csv(csv_file, image_dir, size)
# Division du jeu de données
train_images, test_images, train_labels, test_labels = train_test_split(tab_images, tab_labels, test_size=0.10, random_state=42)
print(f"Nombre d'images d'entraînement : {len(train_images)}, Nombre d'images de test : {len(test_images)}")
# Création des datasets TensorFlow
train_ds = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(batch_size)
# Compilation du modèle
model_panneau = panneau_model(num_classes)
model_panneau.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
print("Modèle compilé.")
# Entraînement du modèle avec barre de progression pour chaque époque
def train(model, train_ds, test_ds, nbr_entrainement):
for epoch in range(nbr_entrainement):
print(f"Début de l'entraînement {epoch + 1}...")
start = time.time()
# Nombre de batches dans une époque
num_batches = len(train_ds)
# Initialiser tqdm pour les batches
with tqdm(total=num_batches, desc=f"Époque {epoch + 1}", unit='batch') as pbar:
for batch_images, batch_labels in train_ds:
history = model.train_on_batch(batch_images, batch_labels)
pbar.update(1) # Mise à jour de la barre de progression
# Afficher les résultats après l'époque
train_loss, train_accuracy = history
print(f'Entraînement {epoch + 1:04d} : perte : {train_loss:6.4f}, précision : {train_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
test(model, test_ds)
def test(model, test_ds):
print("Début du test...")
start = time.time()
test_loss, test_accuracy = model.evaluate(test_ds, verbose=0)
print(f' >>> Test : perte : {test_loss:6.4f}, précision : {test_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
print("Début de l'entraînement du modèle.")
train(model_panneau, train_ds, test_ds, nbr_entrainement)
# Chemin de sauvegarde du modèle
model_save_path = "server-ia/data/modeles/tensorflow/tf_modele_speed_panneau.keras"
model_panneau.save(model_save_path)
print(f"Modèle sauvegardé à l'emplacement : {model_save_path}")
# Évaluation des prédictions
print("Évaluation des prédictions sur les images de test.")
for i in range(len(test_images)):
prediction = model_panneau.predict(np.array([test_images[i]]))
predicted_label_index = np.argmax(prediction[0])
predicted_label = reverse_labels_mapping[predicted_label_index]
actual_label = reverse_labels_mapping[test_labels[i]]
print(f"Image {i}: Prédiction = {predicted_label}, Label réel = {actual_label}")
cv2.imshow("image", test_images[i])
if cv2.waitKey() & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

View File

@@ -0,0 +1,156 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
import pandas as pd
import os
import time
from tqdm import tqdm
# Configuration
size = 60
csv_file = "server-trainer/images/genere_vitesse_panneaux_labels.csv"
image_dir = "server-trainer/images/genere_vitesse_panneaux/"
batch_size = 128
nbr_entrainement = 10 # Nombre d'époques d'entraînement
output_csv = "server-ia/data/modeles/tensorflow/train_labels.csv"
print(f"Configuration : taille des images = {size}, taille du batch = {batch_size}, nombre d'époques = {nbr_entrainement}")
# Définition du modèle
def panneau_model(nbr_classes):
print(f"Création du modèle avec {nbr_classes} classes.")
model = tf.keras.Sequential([
layers.Input(shape=(size, size, 3)),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Conv2D(256, 3, padding='same', activation='relu'),
layers.MaxPool2D(pool_size=2),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.Dense(nbr_classes, activation='softmax')
])
print("Modèle créé.")
return model
# Chargement des images et des labels depuis le CSV
def load_data_from_csv(csv_file, image_dir, size):
df = pd.read_csv(csv_file)
# Afficher les noms des colonnes pour débogage
print("Colonnes dans le CSV :", df.columns)
# Créer un dictionnaire pour mapper les labels alphanumériques à des indices
labels_mapping = {label: idx for idx, label in enumerate(df['label'].unique())}
reverse_labels_mapping = {idx: label for label, idx in labels_mapping.items()} # Inverse du mapping pour affichage
print(f"Mapping des labels : {labels_mapping}")
images = []
labels = []
for _, row in df.iterrows():
# Assurer que les colonnes existent
if 'filename' not in row or 'label' not in row:
raise ValueError("Les colonnes 'filename' ou 'label' sont manquantes dans le CSV")
filename = row['filename']
label = row['label']
image_path = os.path.join(image_dir, filename)
# Charger et redimensionner l'image
image = cv2.imread(image_path)
if image is None:
print(f"Erreur de chargement de l'image : {image_path}")
continue
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
images.append(image)
labels.append(labels_mapping[label])
images = np.array(images, dtype=np.float32)
labels = np.array(labels, dtype=np.int32)
# Normalisation
images /= 255.0
return images, labels, len(labels_mapping), reverse_labels_mapping
# Chargement des données
tab_images, tab_labels, num_classes, reverse_labels_mapping = load_data_from_csv(csv_file, image_dir, size)
# Division du jeu de données
train_images, test_images, train_labels, test_labels = train_test_split(tab_images, tab_labels, test_size=0.10, random_state=42)
print(f"Nombre d'images d'entraînement : {len(train_images)}, Nombre d'images de test : {len(test_images)}")
# Sauvegarde des labels d'entraînement dans un CSV
train_filenames = [f'train_img_{i}.jpg' for i in range(len(train_images))]
train_labels_str = [reverse_labels_mapping[label] for label in train_labels]
df_train = pd.DataFrame({
'filename': train_filenames,
'label': train_labels_str
})
# Sauvegarder le CSV
df_train.to_csv(output_csv, index=False)
print(f"Fichier CSV des labels d'entraînement sauvegardé à l'emplacement : {output_csv}")
# Création des datasets TensorFlow
train_ds = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(batch_size)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(batch_size)
# Compilation du modèle
model_panneau = panneau_model(num_classes)
model_panneau.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
print("Modèle compilé.")
# Entraînement du modèle avec barre de progression pour chaque époque
def train(model, train_ds, test_ds, nbr_entrainement):
for epoch in range(nbr_entrainement):
print(f"Début de l'entraînement {epoch + 1}...")
start = time.time()
# Nombre de batches dans une époque
num_batches = len(train_ds)
# Initialiser tqdm pour les batches
with tqdm(total=num_batches, desc=f"Époque {epoch + 1}", unit='batch') as pbar:
for batch_images, batch_labels in train_ds:
history = model.train_on_batch(batch_images, batch_labels)
pbar.update(1) # Mise à jour de la barre de progression
# Afficher les résultats après l'époque
train_loss, train_accuracy = history
print(f'Entraînement {epoch + 1:04d} : perte : {train_loss:6.4f}, précision : {train_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
test(model, test_ds)
def test(model, test_ds):
print("Début du test...")
start = time.time()
test_loss, test_accuracy = model.evaluate(test_ds, verbose=0)
print(f' >>> Test : perte : {test_loss:6.4f}, précision : {test_accuracy * 100:7.4f}%, temps : {time.time() - start:7.4f}')
print("Début de l'entraînement du modèle.")
train(model_panneau, train_ds, test_ds, nbr_entrainement)
# Chemin de sauvegarde du modèle
model_save_path = "server-ia/data/modeles/tensorflow/tf_modele_speed_panneau.keras"
model_panneau.save(model_save_path)
print(f"Modèle sauvegardé à l'emplacement : {model_save_path}")
# Évaluation des prédictions
print("Évaluation des prédictions sur les images de test.")
for i in range(len(test_images)):
prediction = model_panneau.predict(np.array([test_images[i]]))
predicted_label_index = np.argmax(prediction[0])
predicted_label = reverse_labels_mapping[predicted_label_index]
actual_label = reverse_labels_mapping[test_labels[i]]
print(f"Image {i}: Prédiction = {predicted_label}, Label réel = {actual_label}")
cv2.imshow("image", test_images[i])
if cv2.waitKey() & 0xFF == ord('q'):
break
cv2.destroyAllWindows()