def _test(): from segmentation import Segmentation import input_output s = Segmentation(5) c1 = Nuage(input_output.get_clouds([0], 1, size=.01)[0], s) c2 = torch.tensor([[0., 0, 0], [1, 1, 1], [-1, -1, -1], [.2, .3, .0]]) c2 = Nuage(c2, s) n_mlp = 2 latent_size = 25088 grid_points = 4 epochs = 5 latent = input_output.get_latent([0], 1, nPerObj=1)[0] # équivalence des deux fonctions de loss (avec points écrits à la main) print("seg", Nuage.chamfer_seg(c1, c2)) print("quad", Nuage.chamfer_quad(c1.liste_points, c2.liste_points)) assert Nuage.chamfer_seg(c1, c2) == Nuage.chamfer_quad(c1.liste_points, c2.liste_points) # presque équivalence de convergence # (utilise les mêmes nombres aléatoires pour avoir le même résultat) torch.manual_seed(0) np.random.seed(0) reconstructeur1 = Reconstructeur(n_mlp, latent_size, grid_points, s, quadratic=False) torch.manual_seed(0) np.random.seed(0) reconstructeur2 = Reconstructeur(n_mlp, latent_size, grid_points, s, quadratic=True) res1 = fit_reconstructeur(reconstructeur1, ([latent], [c1]), epochs) print() res2 = fit_reconstructeur(reconstructeur2, ([latent], [c1]), epochs) # différences sûrement dues à des erreurs d'arrondi assert np.all( np.abs(np.array(res1["loss_train"]) - np.array(res2["loss_train"])) < 1e-3) print("tests passés")
def _main_inference(): chosen_subset = [0] n_per_cat = 10 sample_size = 1000 clouds = input_output.get_clouds(chosen_subset, n_per_cat, size=sample_size) latent = input_output.get_latent( chosen_subset, n_per_cat, nPerObj=1 ) # /!\ attention: il faut que les fichiers sur le disque correspondent latent_size = 25088 loaded_name = "trained_network_mlp6_grid4_lossmode2_idcat0_clouds2_epoch15" n_mlp = int(loaded_name.split("mlp")[1].split("_")[0]) # en inférence, on n'utilise pas forcément la même résolution de grille # grid_points = int(loaded_name.split("grid")[1].split("_")[0]) grid_points = 16 reconstructeur = Reconstructeur(n_mlp, latent_size, grid_points, Nuage.chamfer) reconstructeur.load_state_dict(torch.load(loaded_name)) for x, ground_truth in zip(latent, clouds): pred = reconstructeur.forward(x) fig = plt.figure('figure') ax = p3.Axes3D(fig) ax.set_axis_off() ax.set_frame_on(False) ax.set_xlim3d([-1.0, 1.0]) ax.set_ylim3d([-1.0, 1.0]) ax.set_zlim3d([-1.0, 1.0]) # trace le nuage ground truth l = ground_truth.detach().numpy() ax.plot(l[:, 0], l[:, 1], l[:, 2], "g,") l = pred.detach().numpy() ax.plot(l[:, 0], l[:, 1], l[:, 2], "r.") plt.show() # le dernier angle de vu est utilisé pour l'animation
def _main(): chosenSubSet = [0, 1] nCat = len(chosenSubSet) nPerCat = 100 nPerObj = 1 ratio_train = .8 latentVectors = input_output.get_latent(chosenSubSet, nPerCat, nPerObj) labels = ([0] * (len(latentVectors) // 2)) + ([1] * (len(latentVectors) // 2)) indexes = list(range(len(latentVectors))) random.shuffle(indexes) n_train = int(ratio_train * len(indexes)) train_x = [latentVectors[i] for i in indexes[:n_train]] test_x = [latentVectors[i] for i in indexes[n_train:]] train_y = [labels[i] for i in indexes[:n_train]] test_y = [labels[i] for i in indexes[n_train:]] #construction de notre modèle model = SimpleClassifier(len(latentVectors[0]), nCat) #apprentissage epochs = 1000 #aura convergé avant model.fit(train_x, train_y, epochs, 1, test_x, np.array(test_y)) #précision sur train pred_train = model.predict(train_x) print("précision train ", sum(np.array(pred_train) == np.array(train_y)) / len(train_y)) #précision sur test pred_test = model.predict(test_x) print("précision test ", sum(np.array(pred_test) == np.array(test_y)) / len(test_y))
def _main_train_network(): # fixe la graine aléatoire choose_seed() # quelle(s) catégorie(s) d'objet utiliser (une seule pour le moment) chosen_subset = [0] # nombre d'objets par catégories n_per_cat = 2 # taille des nuages de point de chaque objet (après sous-échantillonage) sample_size = 300 # ratio de sous-échantillonage factor_sample_size = 1 # charge les nuages du disque clouds = input_output.get_clouds(chosen_subset, n_per_cat, size=factor_sample_size * sample_size) clouds = [Nuage(x, eps=0) for x in clouds] # charge les vecteurs latents pré-calculés des images correspondantes latent = input_output.get_latent( chosen_subset, n_per_cat, nPerObj=1 ) # /!\ attention: il faut que les fichiers sur le disque correspondent ratio_test = .02 train_x, test_x, train_y, test_y = train_test_split( latent, clouds, test_size=round(len(clouds) * ratio_test)) print("nb train", len(train_y), "nb test", len(test_y)) print("taille des nuages ground truth:", sample_size, "extraits de", len(clouds[0].points)) ##### PARAMETRES DU MODELE ##### latent_size = 25088 # défini par l'encodeur utilisé grid_size = 1e0 n_mlp = 8 grid_points = 6 epochs = 15 lr = 1e-4 mini_batch_size = 1 loss_factor_mode = 0 if loss_factor_mode == 0: loss_factor = 1.0 elif loss_factor_mode == 1: loss_factor = .001 else: loss_factor = [.001] * (epochs * 2 // 3) + [1.0] * (epochs // 3) # création du modèle reconstructeur = Reconstructeur(n_mlp, latent_size, grid_points, Nuage.chamfer) affichage(n_mlp, latent_size, epochs, n_per_cat, grid_points, mini_batch_size) ##### paramètres indiquant les tâches à effectuer pendant le fit ##### # sauvegarder les loss en train et test list_epoch_loss = range(epochs) # sauvegarder les nuages construits # les 3 premiers et les 3 derniers objets (ils font partie des tests si il y en a) ind_cloud_saved = set(range(3)) | set(range(n_per_cat - 3, n_per_cat)) ind_cloud_saved = {x for x in ind_cloud_saved if 0 <= x < n_per_cat} # fit res = fit_reconstructeur(reconstructeur, (train_x, train_y), epochs, mini_batch_size=mini_batch_size, sample_size=sample_size, lr=lr, grid_scale=grid_size, loss_factor=loss_factor, test=(test_x, test_y), list_epoch_loss=list_epoch_loss, ind_cloud_saved=ind_cloud_saved) # sauvegarde du modèle et affichage root = os.path.abspath( os.path.dirname(__file__)) + "/../../outputs_animation/" file = "mlp" + str(n_mlp) + "_grid" + str(grid_points) + "_lossmode" + str(loss_factor_mode) + "_idcat"\ + (str(chosen_subset[0] if len(chosen_subset)==1 else chosen_subset)) # trained_network = "trained_network_"+file+"_clouds"+str(len(train_x))+"_epoch"+str(epochs) # if input("save ?") == 'y': # if not os.path.exists(trained_network) or input("override ?")=='y': # torch.save(reconstructeur.state_dict(), trained_network) # elif input("skip ?")!='y': # # permet à l'utilisateur d'exécuter un code arbitraire # import pdb # pdb.set_trace() save(root, file, res, epochs, sorted(list_epoch_loss), clouds, sorted(ind_cloud_saved))
def _main(): chosen_subset = [2] n_per_cat = 3 sample_size = 300 segmentation = Segmentation(5) clouds = input_output.get_clouds(chosen_subset, n_per_cat, size=sample_size) latent = input_output.get_latent( chosen_subset, n_per_cat, nPerObj=1 ) # /!\ attention: il faut que les fichiers sur le disque correspondent clouds = [Nuage(x, segmentation) for x in clouds] # plot_tailles(clouds) ratio_train = .8 n_train = int(ratio_train * len(clouds)) indexes = list(range(len(clouds))) #random.shuffle(indexes) train_x = [latent[i] for i in indexes[:n_train]] test_x = [latent[i] for i in indexes[n_train:]] train_y = [clouds[i] for i in indexes[:n_train]] test_y = [clouds[i] for i in indexes[n_train:]] latent_size = 25088 # défini par l'encodeur utilisé grid_size = 1e0 n_mlp = 8 grid_points = 6 epochs = 3 lr = 1e-4 loss_factor_mode = 0 if loss_factor_mode == 0: loss_factor = 1.0 elif loss_factor_mode == 1: loss_factor = .001 else: loss_factor = [.001] * (epochs * 2 // 3) + [10.0] * (epochs // 3) print("taille des nuages ground truth:", len(clouds[0].liste_points)) print("nombre de MLP:", n_mlp) print("résolution de la grille:", grid_points, "^2 =", grid_points**2) print("taille des nuages générés:", n_mlp, "*", grid_points**2, "=", n_mlp * grid_points**2) reconstructeur = Reconstructeur(n_mlp, latent_size, grid_points, segmentation) list_epoch_loss = range(0, epochs, max(1, epochs // 10)) ind_cloud_saved = {0, len(clouds) - 2, len(clouds) - 1} res = fit_reconstructeur(reconstructeur, (train_x, train_y), epochs, sample_size=sample_size, lr=lr, grid_scale=grid_size, loss_factor=loss_factor, test=(test_x, test_y), list_epoch_loss=list_epoch_loss, ind_cloud_saved=ind_cloud_saved) root = os.path.abspath( os.path.dirname(__file__)) + "/../../outputs_animation/" file = "mlp" + str(n_mlp) + "_grid" + str(grid_points) + "_lossmode" + str(loss_factor_mode) + "_idcat"\ + (str(chosen_subset[0] if len(chosen_subset)==1 else chosen_subset)) save(root, file, res, epochs, list_epoch_loss, clouds, ind_cloud_saved)
def _main_train_network(): chosen_subset = [0] n_per_cat = 10 sample_size = 300 factor_sample_size = 4 t = time() clouds = input_output.get_clouds(chosen_subset, n_per_cat, size=factor_sample_size * sample_size) latent = input_output.get_latent( chosen_subset, n_per_cat, nPerObj=1 ) # /!\ attention: il faut que les fichiers sur le disque correspondent clouds = [Nuage(x, eps=1e-3) for x in clouds] ratio_test = .2 train_x, test_x, train_y, test_y = train_test_split( latent, clouds, test_size=round(len(clouds) * ratio_test)) print("nb train", len(train_y), "nb test", len(test_y)) print("taille des nuages ground truth:", sample_size, "extraits de", len(clouds[0].points)) latent_size = 25088 # défini par l'encodeur utilisé grid_size = 1e0 n_mlp = 16 grid_points = 6 epochs = 45 lr = 1e-4 mini_batch_size = 5 loss_factor_mode = 0 if loss_factor_mode == 0: loss_factor = 1.0 elif loss_factor_mode == 1: loss_factor = .001 else: loss_factor = [.001] * (epochs * 2 // 3) + [1.0] * (epochs // 3) reconstructeur = Reconstructeur(n_mlp, latent_size, grid_points, Nuage.chamfer) n_weights = n_mlp * latent_size * 512 + 512 * 256 + 256 * 128 + 128 * 3 # nombre de coef dans un mlp n_weights_forward = n_weights * epochs * n_per_cat * grid_points**2 # nombre de lecture de poids n_weights_backward = n_weights * epochs * n_per_cat / mini_batch_size # nombre d'écriture de poids print("nombre de MLP:", n_mlp) print("résolution de la grille:", grid_points, "^2 =", grid_points**2) print("taille des nuages générés:", n_mlp, "*", grid_points**2, "=", n_mlp * grid_points**2) print("nombre de poids {0: .1e}".format(n_weights)) # print("nombre de loss {0: .1e}".format(n_mlp *n_per_cat * epochs)) # temps loss négligeable print( "nombre de lecture/écriture poids {0:.1e}".format(n_weights_forward + n_weights_backward)) print("temps estimé {0:.0f}".format( (n_weights_forward + n_weights_backward) * 5e-10)) # print("temps prétraitement", round(time() - t, 1)) # temps lecture et création kdtree négligeable list_epoch_loss = set(range(0, epochs, max(1, epochs // 5))) | {epochs - 1} ind_cloud_saved = set(range(3)) | set(range(n_per_cat - 3, n_per_cat)) ind_cloud_saved = {x for x in ind_cloud_saved if 0 <= x < n_per_cat} res = fit_reconstructeur(reconstructeur, (train_x, train_y), epochs, mini_batch_size=mini_batch_size, sample_size=sample_size, lr=lr, grid_scale=grid_size, loss_factor=loss_factor, test=(test_x, test_y), list_epoch_loss=list_epoch_loss, ind_cloud_saved=ind_cloud_saved) root = os.path.abspath( os.path.dirname(__file__)) + "/../../outputs_animation/" file = "mlp" + str(n_mlp) + "_grid" + str(grid_points) + "_lossmode" + str(loss_factor_mode) + "_idcat"\ + (str(chosen_subset[0] if len(chosen_subset)==1 else chosen_subset)) trained_network = "trained_network_" + file + "_clouds" + str( len(train_x)) + "_epoch" + str(epochs) if input("save ?") == 'y': if not os.path.exists(trained_network) or input("override ?") == 'y': torch.save(reconstructeur.state_dict(), trained_network) elif input("skip ?") != 'y': # permet à l'utilisateur d'exécuter un code arbitraire import pdb pdb.set_trace() save(root, file, res, epochs, sorted(list_epoch_loss), clouds, sorted(ind_cloud_saved))