Ejemplo n.º 1
0
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")
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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))
Ejemplo n.º 4
0
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))
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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))