From e5cc65c015fca5362b71a06e7073a54a0093517c Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Thu, 20 Mar 2025 07:34:19 +0100 Subject: [PATCH] added the resources for tensorflow1 benchmark. Received from Eric Robin on 10/03/2025 work related to [https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3345] --- iprbench/resources/tensorflow1/DS_Data.py | 69 +++++++++++++++++++++ iprbench/resources/tensorflow1/DS_Train.py | 53 ++++++++++++++++ iprbench/resources/tensorflow1/GAN.bmp | Bin 0 -> 17462 bytes 3 files changed, 122 insertions(+) create mode 100644 iprbench/resources/tensorflow1/DS_Data.py create mode 100644 iprbench/resources/tensorflow1/DS_Train.py create mode 100644 iprbench/resources/tensorflow1/GAN.bmp diff --git a/iprbench/resources/tensorflow1/DS_Data.py b/iprbench/resources/tensorflow1/DS_Data.py new file mode 100644 index 0000000..33f8d8f --- /dev/null +++ b/iprbench/resources/tensorflow1/DS_Data.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Sep 25 14:19:41 2024 + +@author: errobin +""" + +import numpy as np #pour faire du calcul matriciel +from PIL import Image #pour lire une image +import matplotlib.pyplot as plt #pour faire des tracer + +#lecture image ###################################### + +image_file = Image.open("GAN.bmp") +image_bmp = 1.*np.array(image_file) # on transforme le fichier en matrice nommée image_bmp +image_file.close() #fermeture du fichier en lecture +##################################################### + + + + +# code pour aider à comprendre une image +################################################################################ + +# recupère les dimension de l'image ############### +dim=image_bmp.shape + +nb_ligne=dim[0] +nb_colonne=dim[1] +image_traitee=np.zeros((nb_ligne,nb_colonne)) #déclaration d'un tableau au dimension de l'image +################################################### + +# Affecte les valeurs de la matrice image_bmp à image_traitee +for colonne in range(0,nb_colonne): + for ligne in range(0,nb_ligne): + + image_traitee[ligne,colonne]=image_bmp[ligne,colonne]#regarder les tableaux avec variable explorer + +# plt.imshow(image_traitee,'gray') +# plt.show() +################################################################################# + +# fin code pour comprendre une image + + + + +# DS partie Data +#complétez le code suivant pour créer votre database tq; x_train = position du pixel et y_target = couleur du pixel + + + + +#declaration des tableaux +X_train=np.zeros((nb_colonne*nb_ligne,2)) +Y_target=np.zeros((nb_colonne*nb_ligne)) + +compt=0 +for colonne in range(0,nb_colonne): + for ligne in range(0,nb_ligne): + X_train[compt,0]=colonne + X_train[compt,1]=ligne + + Y_target[compt]=image_bmp[colonne,ligne]/255. + compt=compt+1 + +#sauvagarde de la database +np.savetxt("X_train.txt", X_train, delimiter=';') +np.savetxt("Y_target.txt", Y_target, delimiter=';') diff --git a/iprbench/resources/tensorflow1/DS_Train.py b/iprbench/resources/tensorflow1/DS_Train.py new file mode 100644 index 0000000..bc57397 --- /dev/null +++ b/iprbench/resources/tensorflow1/DS_Train.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Sep 25 14:38:32 2024 + +@author: errobin +""" + +# DS partie Train +#complétez/joué sur les hyperparamètres (vitesse d'apprentissage et nb epoch) et sur l'architecture du modèle pour l'entrainer et pour le sauver (une fois entrainé) +# ASTUCE un loss inférieur à 0.005 permets déjà d'obtenir des résultats intéréssants + + +import tensorflow as tf +import numpy as np +from PIL import Image #pour lire une image + + +X_train = np.genfromtxt('X_train.txt',delimiter=';') +Y_target = np.genfromtxt('Y_target.txt',delimiter=';') + +#Partie ANN definition + entrainement +#***************************************** +model = tf.keras.models.Sequential() + +model.add(tf.keras.layers.Dense(2048, activation="relu")) +model.add(tf.keras.layers.Dense(1024, activation="relu")) +model.add(tf.keras.layers.Dense(512, activation="relu")) +model.add(tf.keras.layers.Dense(256, activation="relu")) +model.add(tf.keras.layers.Dense(128, activation="relu")) +model.add(tf.keras.layers.Dense(64, activation="relu")) +model.add(tf.keras.layers.Dense(32, activation="relu")) +model.add(tf.keras.layers.Dense(1)) + +model.compile( + loss="mse", + optimizer="adam" +) + + + +###### D'après à quoi peuvent servir le code des lignes 38 à 41 +def scheduler(epoch):# dans cette fonction il est possible de faire des test if en fonction de epoch pour retourner différente valeur de la ??? + return 0.0001 + +callback_vitesse_apprentissage = tf.keras.callbacks.LearningRateScheduler(scheduler) +################################################################### + +import time +start_time = time.time() +model.fit(X_train, Y_target, epochs=3,verbose=1,callbacks=[callback_vitesse_apprentissage]) +end_time = time.time() +temps_cal = end_time - start_time +print(temps_cal) \ No newline at end of file diff --git a/iprbench/resources/tensorflow1/GAN.bmp b/iprbench/resources/tensorflow1/GAN.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0409f132522947715afd61c2b12a6c7d783ca4f5 GIT binary patch literal 17462 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 literal 0 HcmV?d00001