CARIA.2.0

Precedent repo CARIA:
Trainer pour CARIA-INTELLIGENT modeles
This commit is contained in:
ccunatbrule
2024-05-28 16:03:52 +02:00
parent 07b371fd68
commit 194398cebc
7 changed files with 577 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
import cv2
import os
import time
import dataset
size=42
dir_images_panneaux="server-trainer/images/road_sign_speed_trainers/panneaux"
dir_images_autres_panneaux="server-trainer/images/road_sign_speed_trainers/autres_panneaux"
dir_images_genere_sans_panneaux="server-trainer/images/road_sign_speed_trainers/genere_sans_panneaux"
batch_size=128
nbr_entrainement=1 #20
def panneau_model(nbr_classes):
model=tf.keras.Sequential()
model.add(layers.Input(shape=(size, size, 3), dtype='float32'))
model.add(layers.Conv2D(128, 3, strides=1))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Conv2D(128, 3, strides=1))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.MaxPool2D(pool_size=2, strides=2))
model.add(layers.Conv2D(256, 3, strides=1))
model.add(layers.Dropout(0.3))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Conv2D(256, 3, strides=1))
model.add(layers.Dropout(0.4))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.MaxPool2D(pool_size=2, strides=2))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.BatchNormalization())
model.add(layers.Dense(nbr_classes, activation='sigmoid'))
return model
def lire_images_panneaux(dir_images_panneaux, size=None):
tab_panneau=[]
tab_image_panneau=[]
if not os.path.exists(dir_images_panneaux):
quit("Le repertoire d'image n'existe pas: {}".format(dir_images_panneaux))
files=os.listdir(dir_images_panneaux)
if files is None:
quit("Le repertoire d'image est vide: {}".format(dir_images_panneaux))
for file in sorted(files):
if file.endswith("png"):
tab_panneau.append(file.split(".")[0])
image=cv2.imread(dir_images_panneaux+"/"+file)
if size is not None:
image=cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
tab_image_panneau.append(image)
return tab_panneau, tab_image_panneau
tab_panneau, tab_image_panneau=lire_images_panneaux(dir_images_panneaux, size)
tab_images=np.array([]).reshape(0, size, size, 3)
tab_labels=np.array([]).reshape(0, len(tab_image_panneau))
id=0
for image in tab_image_panneau:
lot = []
for _ in range(120):
lot.append(dataset.modif_img(image))
lot = np.array(lot)
tab_images=np.concatenate((tab_images, lot))
tab_labels=np.concatenate([tab_labels, np.repeat([np.eye(len(tab_image_panneau))[id]], len(lot), axis=0)])
id += 1
files=os.listdir(dir_images_autres_panneaux)
if files is None:
quit("Le repertoire d'image est vide:".format(dir_images_autres_panneaux))
nbr=0
for file in files:
lot = []
if file.endswith("png"):
path=os.path.join(dir_images_autres_panneaux, file)
image=cv2.resize(cv2.imread(path), (size, size), cv2.INTER_LANCZOS4)
for _ in range(700):
lot.append(dataset.modif_img(image))
lot = np.array(lot)
tab_images=np.concatenate([tab_images, lot])
nbr+=len(lot)
tab_labels=np.concatenate([tab_labels, np.repeat([np.full(len(tab_image_panneau), 0)], nbr, axis=0)])
nbr_np=int(len(tab_images)/2)
id=1
nbr=0
tab=[]
for cpt in range(nbr_np):
file=dir_images_genere_sans_panneaux+"/{:d}.png".format(id)
if not os.path.isfile(file):
break
image=cv2.resize(cv2.imread(file), (size, size))
tab.append(image)
id+=1
nbr+=1
tab_images=np.concatenate([tab_images, tab])
tab_labels=np.concatenate([tab_labels, np.repeat([np.full(len(tab_image_panneau), 0)], nbr, axis=0)])
tab_panneau=np.array(tab_panneau)
tab_images=np.array(tab_images, dtype=np.float32)/255
tab_labels=np.array(tab_labels, dtype=np.float32) #.reshape([-1, 1])
train_images, test_images, train_labels, test_labels=train_test_split(tab_images, tab_labels, test_size=0.10)
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)
print("train_images", len(train_images))
print("test_images", len(test_images))
@tf.function
def train_step(images, labels):
with tf.GradientTape() as tape:
predictions=model_panneau(images)
loss=my_loss(labels, predictions)
gradients=tape.gradient(loss, model_panneau.trainable_variables)
optimizer.apply_gradients(zip(gradients, model_panneau.trainable_variables))
train_loss(loss)
train_accuracy(labels, predictions)
def train(train_ds, nbr_entrainement):
for entrainement in range(nbr_entrainement):
start=time.time()
for images, labels in train_ds:
train_step(images, labels)
message='Entrainement {:04d}: loss: {:6.4f}, accuracy: {:7.4f}%, temps: {:7.4f}'
print(message.format(entrainement+1,
train_loss.result(),
train_accuracy.result()*100,
time.time()-start))
train_loss.reset_states()
train_accuracy.reset_states()
test(test_ds)
def my_loss(labels, preds):
labels_reshape=tf.reshape(labels, (-1, 1))
preds_reshape=tf.reshape(preds, (-1, 1))
result=loss_object(labels_reshape, preds_reshape)
return result
def test(test_ds):
start=time.time()
for test_images, test_labels in test_ds:
predictions=model_panneau(test_images)
t_loss=my_loss(test_labels, predictions)
test_loss(t_loss)
test_accuracy(test_labels, predictions)
message=' >>> Test: loss: {:6.4f}, accuracy: {:7.4f}%, temps: {:7.4f}'
print(message.format(test_loss.result(),
test_accuracy.result()*100,
time.time()-start))
test_loss.reset_states()
test_accuracy.reset_states()
optimizer=tf.keras.optimizers.Adam()
loss_object=tf.keras.losses.BinaryCrossentropy()
train_loss=tf.keras.metrics.Mean()
train_accuracy=tf.keras.metrics.BinaryAccuracy()
test_loss=tf.keras.metrics.Mean()
test_accuracy=tf.keras.metrics.BinaryAccuracy()
model_panneau=panneau_model(len(tab_panneau))
checkpoint=tf.train.Checkpoint(model_panneau=model_panneau)
print("Entrainement")
train(train_ds, nbr_entrainement)
checkpoint.save(file_prefix="server-ia/data/modeles/road_sign_speed_trainers/modele_panneau")
quit()
for i in range(len(test_images)):
prediction=model_panneau(np.array([test_images[i]]))
print("prediction", prediction[0])
if np.sum(prediction[0])<0.6:
print("Ce n'est pas un panneau")
else:
print("C'est un panneau:", tab_panneau[np.argmax(prediction[0])])
cv2.imshow("image", test_images[i])
if cv2.waitKey()&0xFF==ord('q'):
break

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_speed"
valid_data_dir = "server-trainer/images/road_sign_trainers/test_speed"
# 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/RoadSign", "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/RoadSign/modele_signaux_routiers.h5")
# É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,31 @@
import os
# Assurez-vous d'être dans le répertoire Darknet
os.chdir("chemin/vers/votre/darknet")
# Entraînement du modèle YOLOv3 pour les panneaux de signalisation routière
# Utilisation du CPU uniquement
# Chemin vers les données d'entraînement et de validation
train_data = "server-trainer/images/road_sign_trainers/train_speed"
valid_data = "server-trainer/images/road_sign_trainers/test_speed"
# Paramètres d'entraînement
batch_size = 64
subdivisions = 16
num_epochs = 1000
# Commande d'entraînement
train_command = f"./darknet detector train data/obj.data cfg/yolov3_custom_train.cfg yolov3.weights -map -dont_show -gpus 0"
# Boucle d'entraînement
for epoch in range(num_epochs):
print(f"Epoch {epoch+1}/{num_epochs}")
# Entraînement sur les données d'entraînement
os.system(train_command)
# Validation sur les données de validation
os.system(f"./darknet detector map data/obj.data cfg/yolov3_custom_test.cfg backup/yolov3_custom_train_{epoch+1}.weights")
print("Entraînement terminé!")

View File

@@ -0,0 +1,33 @@
import cv2
import os
import numpy as np
import pickle
image_dir="server-trainer/images/avatars/"
current_id=0
label_ids={}
x_train=[]
y_labels=[]
for root, dirs, files in os.walk(image_dir):
if len(files):
label=root.split("/")[-1]
for file in files:
if file.endswith("jpg"):
path=os.path.join(root, file)
if not label in label_ids:
label_ids[label]=current_id
current_id+=1
id_=label_ids[label]
image=cv2.imread(path, cv2.IMREAD_GRAYSCALE)
x_train.append(image)
y_labels.append(id_)
with open("server-ia/data/modeles/camera_identification_user/labels.pickle", "wb") as f:
pickle.dump(label_ids, f)
x_train=np.array(x_train)
y_labels=np.array(y_labels)
recognizer=cv2.face.LBPHFaceRecognizer_create()
recognizer.train(x_train, y_labels)
recognizer.save("server-ia/data/modeles/camera_identification_user/trainner.yml")

82
server-trainer/dataset.py Normal file
View File

@@ -0,0 +1,82 @@
import numpy as np
import cv2
import multiprocessing
import random
# dataset pour train_panneau.py
def bruit(image_orig):
h, w, c = image_orig.shape
n = np.random.randn(h, w, c) * random.randint(5, 30)
return np.clip(image_orig + n, 0, 255).astype(np.uint8)
def change_gamma(image, alpha=1.0, beta=0.0):
return np.clip(alpha * image + beta, 0, 255).astype(np.uint8)
def modif_img(img):
h, w, c = img.shape
r_color = [np.random.randint(255), np.random.randint(255), np.random.randint(255)]
img = np.where(img == [142, 142, 142], r_color, img).astype(np.uint8)
if np.random.randint(3):
k_max = 3
kernel_blur = np.random.randint(k_max) * 2 + 1
img = cv2.GaussianBlur(img, (kernel_blur, kernel_blur), 0)
M = cv2.getRotationMatrix2D((int(w / 2), int(h / 2)), random.randint(-10, 10), 1)
img = cv2.warpAffine(img, M, (w, h))
if np.random.randint(2):
a = int(max(w, h) / 5) + 1
pts1 = np.float32([[0, 0], [w, 0], [0, h], [w, h]])
pts2 = np.float32([[0 + random.randint(-a, a), 0 + random.randint(-a, a)], [w - random.randint(-a, a), 0 + random.randint(-a, a)], [0 + random.randint(-a, a), h - random.randint(-a, a)], [w - random.randint(-a, a), h - random.randint(-a, a)]])
M = cv2.getPerspectiveTransform(pts1,pts2)
img = cv2.warpPerspective(img, M, (w, h))
if np.random.randint(2):
r = random.randint(0, 5)
h2 = int(h * 0.9)
w2 = int(w * 0.9)
if r == 0:
img = img[0:w2, 0:h2]
elif r == 1:
img = img[w - w2:w, 0:h2]
elif r == 2:
img = img[0:w2, h - h2:h]
elif r == 3:
img = img[w - w2:w, h - h2:h]
img = cv2.resize(img, (h, w))
if np.random.randint(2):
r = random.randint(1, int(max(w, h) * 0.15))
img = img[r:w - r, r:h - r]
img = cv2.resize(img, (h, w))
if not np.random.randint(4):
t = np.empty((h, w, c), dtype=np.float32)
for i in range(h):
for j in range(w):
for k in range(c):
t[i][j][k] = (i / h)
M = cv2.getRotationMatrix2D((int(w / 2), int(h / 2)), np.random.randint(4) * 90, 1)
t = cv2.warpAffine(t, M, (w, h))
img = (cv2.multiply((img / 255).astype(np.float32), t) * 255).astype(np.uint8)
img = change_gamma(img, random.uniform(0.6, 1.0), -np.random.randint(50))
if not np.random.randint(4):
p = (15 + np.random.randint(10)) / 100
img = (img * p + 50 * (1 - p)).astype(np.uint8) + np.random.randint(100)
img = bruit(img)
return img
# NOT WORKING ERREUR
def create_lot_img(image, nbr, nbr_thread=None):
if nbr_thread is None:
nbr_thread = multiprocessing.cpu_count()
lot_original = np.repeat([image], nbr, axis=0)
p = Pool(nbr_thread)
lot_result = p.map(modif_img, lot_original)
p.close()
return lot_result

View File

@@ -0,0 +1,85 @@
import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
from sklearn.utils import shuffle
import os
import cv2
import dataset
###GENERE DES IMAGES AVEC PANNEAUX DEPUIS UN MEDIA###
# Tuto25[OpenCV] Lecture des panneaux de vitesse p.1 (houghcircles) 28min
# Taille des images
size = 42
# Chemin vers le répertoire contenant les images de panneaux
dir_images_panneaux = "server-trainer/images/road_sign_speed_trainers/panneaux"
dir_images_genere_panneaux = "server-trainer/images/road_sign_speed_trainers/genere_panneaux"
# Fonction pour lire les images de panneaux à partir du répertoire spécifié
def lire_images_panneaux(dir_images_panneaux, size=None):
tab_panneau = []
tab_image_panneau = []
# Vérifie si le répertoire existe
if not os.path.exists(dir_images_panneaux):
quit("Le repertoire d'image n'existe pas: {}".format(dir_images_panneaux))
# Liste tous les fichiers dans le répertoire
files = os.listdir(dir_images_panneaux)
# Quitte si le répertoire est vide
if files is None:
quit("Le repertoire d'image est vide: {}".format(dir_images_panneaux))
# Parcours des fichiers dans le répertoire
for file in sorted(files):
# Vérifie si le fichier est un fichier PNG
if file.endswith("png"):
# Ajoute le nom du fichier (sans l'extension) à tab_panneau
tab_panneau.append(file.split(".")[0])
# Lit l'image et redimensionne si une taille est spécifiée
image = cv2.imread(dir_images_panneaux + "/" + file)
if size is not None:
image = cv2.resize(image, (size, size), cv2.INTER_LANCZOS4)
tab_image_panneau.append(image)
return tab_panneau, tab_image_panneau
# Appel de la fonction pour lire les images de panneaux
tab_panneau, tab_image_panneau = lire_images_panneaux(dir_images_panneaux, size)
# Initialisation des tableaux pour les images et les labels
tab_images = np.array([]).reshape(0, size, size, 3)
tab_labels = []
# Génération des données d'entraînement
id = 0
for image in tab_image_panneau:
lot = []
for _ in range(100):
lot.append(dataset.modif_img(image))
lot = np.array(lot)
tab_images = np.concatenate([tab_images, lot])
tab_labels = np.concatenate([tab_labels, np.full(len(lot), id)])
id += 1
# Conversion des tableaux en type approprié et normalisation des images
tab_panneau = np.array(tab_panneau)
tab_images = np.array(tab_images, dtype=np.float32) / 255
tab_labels = np.array(tab_labels).reshape([-1, 1])
# Mélange des données
tab_images, tab_labels = shuffle(tab_images, tab_labels)
# Boucle pour sauvegarder les images générées dans le répertoire de sortie
for i in range(len(tab_images)):
# Générer un nom de fichier unique en fonction de l'ID et du nom du panneau
file_name = "{:d}_{}.png".format(i, tab_panneau[int(tab_labels[i])])
# Enregistrer l'image dans le répertoire de sortie
cv2.imwrite(os.path.join(dir_images_genere_panneaux, file_name), tab_images[i] * 255.0) # Retour à l'échelle 0-255
# Affichage des images avec leur label
for i in range(len(tab_images)):
cv2.imshow("panneau", tab_images[i])
print("label", tab_labels[i], "panneau", tab_panneau[int(tab_labels[i])])
if cv2.waitKey() & 0xFF == ord('q'):
quit()

View File

@@ -0,0 +1,39 @@
import cv2
import numpy as np
import random
import os
###GENERE DES IMAGES SANS PANNEAUX DEPUIS UN MEDIA###
#YT:Tuto25[Tensorflow2] Lecture des panneaux de vitesse p.2 - 4min30
size=42
video="server-trainer/videos/autoroute.mp4"
dir_images_genere_sans_panneaux="server-trainer/images/road_sign_speed_trainers/genere_sans_panneaux"
if not os.path.isdir(dir_images_genere_sans_panneaux):
os.mkdir(dir_images_genere_sans_panneaux)
if not os.path.exists(video):
print("Vidéo non présente:", video)
quit()
cap=cv2.VideoCapture(video)
id=0
nbr_image=1500
nbr_image_par_frame=int(1500/cap.get(cv2.CAP_PROP_FRAME_COUNT))+1
while True:
ret, frame=cap.read()
if ret is False:
quit()
h, w, c=frame.shape
for cpt in range(nbr_image_par_frame):
x=random.randint(0, w-size)
y=random.randint(0, h-size)
img=frame[y:y+size, x:x+size]
cv2.imwrite(dir_images_genere_sans_panneaux+"/{:d}.png".format(id), img)
id+=1
if id==nbr_image:
quit()