示例#1
0
def main():
    gpu = on_gpu()
    print("ON GPU is " + str(gpu))

    #Parameters
    parser = argparse.ArgumentParser(description='train')
    parser.add_argument('--patch_size', default=1, type=int)
    parser.add_argument('--nb_features',
                        default=150,
                        type=int,
                        help="Number of hidden features in GRU.")
    parser.add_argument('--nb_features_final',
                        default=10,
                        type=int,
                        help="Number of final features of the encoder.")
    parser.add_argument(
        '--nb_clusters',
        default=15,
        type=int,
        help=
        "Number of desired clusters. In case if we do not compute for a range of clusters."
    )
    parser.add_argument('--batch_size', default=50, type=int)
    parser.add_argument('--epoch_nb', default=150, type=int)
    parser.add_argument('--learning_rate', default=0.001, type=float)
    args = parser.parse_args()

    #Start time
    start_time = time.time()
    run_name = "." + str(time.strftime("%Y-%m-%d_%H%M"))
    print(run_name)

    #Montpellier
    path_results_seg_series = os.path.expanduser(
        '~/Desktop/Results/Segmentation_outliers_upd_filled/Montpellier_SPOT5_graph_cut_series_2D/'
    )
    seg_folder_series = "series_sigma_0.3_k_6_min_10_bands_3_threshold_int_0.4/"
    folder_encoded = "patch_9_feat_5.2019-09-03_1619_noise1_mean_std"
    path_results = path_results_seg_series + seg_folder_series + "Graph_coverage_filtered/"
    path_results_final = path_results + "alpha_" + str(alpha) + "_t1_" + str(
        t1) + "_t2_" + str(t2) + "_t3_" + str(t3) + "/"

    # We open BB file that contains synopses
    bb_final_list = np.load(path_results_final + "Graph_list_synopsys_alpha_" +
                            str(alpha) + "_t1_" + str(t1) + "_t2_" + str(t2) +
                            "_t3_" + str(t3) + "_" + folder_encoded + ".npy")
    for z in range(8):
        bb_final_list = np.c_[bb_final_list, np.full(len(bb_final_list), None)]

    folder_results = "Synopsys_padding_feat_" + str(
        args.nb_features) + "_lr_" + str(args.learning_rate) + run_name

    # Folder with the results
    path_results_NN = path_results_final + model + "_" + type + "/" + folder_results + "/"
    create_dir(path_results_NN)
    stats_file = path_results_NN + 'stats.txt'
    path_model = path_results_NN + 'model' + run_name + "/"
    create_dir(path_model)

    # We add new arguments to the parser
    print_stats(stats_file, folder_encoded, print_to_console=False)
    print_stats(stats_file, str(args), print_to_console=False)
    parser.add_argument('--stats_file', default=stats_file)
    parser.add_argument('--path_results', default=path_results_NN)
    parser.add_argument('--path_model', default=path_model)
    parser.add_argument('--run_name', default=run_name)
    args = parser.parse_args()

    # We open segmentation rasters
    segm_array_list = []
    date_list = []
    image_name_segm_list = np.sort(
        list(
            filter(
                lambda f:
                (f.endswith(".TIF") and f.startswith("Segments_1D_20")),
                os.listdir(path_results))))
    nbr_images = len(image_name_segm_list)
    print(image_name_segm_list)
    for i in range(nbr_images):
        image_name_segm = image_name_segm_list[i]
        date = (re.search("_([0-9]*).TIF", image_name_segm)).group(1)
        print(date)
        date_list.append(date)
        image_array_seg, H, W, geo, proj, bands_nb = open_tiff(
            path_results,
            os.path.splitext(image_name_segm)[0])
        segm_array_list.append(image_array_seg)
    nbr_images = np.max(bb_final_list[:, 0]) + 1

    # we get synopses
    if type == "mean":
        segments = bb_final_list[:, 8]
    else:
        segments = bb_final_list[:, 7]
    feat_nb = len(segments[0][0])

    # We zero-pad all the sequences, so they have the same length over the dataset (equal to dataset length). See the article
    segments_padding = np.zeros((len(bb_final_list), nbr_images, feat_nb))
    for s in range(len(segments)):
        segments_padding[s][:len(segments[s])] = segments[s]
    print(segments_padding.shape)

    # We prepare the training dataset
    image = ImageDataset(segments_padding, args.patch_size, 0,
                         np.arange(len(segments)),
                         feat_nb)  # we create a dataset with tensor patches
    loader_pretrain = dsloader(image, gpu, args.batch_size, shuffle=True)
    loader_enc = dsloader(image, gpu, batch_size=1000, shuffle=False)

    # We initialize the model
    encoder = Encoder(feat_nb, args.nb_features,
                      args.nb_features_final)  # On CPU
    decoder = Decoder(feat_nb, args.nb_features,
                      args.nb_features_final)  # On CPU
    if gpu:
        encoder = encoder.cuda()  # On GPU
        decoder = decoder.cuda()  # On GPU

    print_stats(stats_file, str(encoder), print_to_console=False)

    # We pretrain the model
    pretrain_lstm(args.epoch_nb, encoder, decoder, loader_pretrain, args)
    # pretrain_lstm(0, encoder, decoder, loader_pretrain, args)

    end_time = time.clock()
    total_time_pretraining = end_time - start_time
    total_time_pretraining = str(
        datetime.timedelta(seconds=total_time_pretraining))
    print_stats(
        args.stats_file,
        "Total time pretraining =" + str(total_time_pretraining) + "\n")

    # We start encoding and clustering
    start_time = time.time()

    bb_final_list_flipped = np.flip(np.copy(bb_final_list), axis=0)
    print_stats(stats_file, 'Initializing clusters...')
    cl_nb = list(range(5, 51, 5))

    labels_list, labels_h_list, hidden_array = encode_lstm(
        encoder, W, loader_enc, cl_nb)
    for c in range(len(cl_nb)):
        feat_cl = cl_nb[c]
        print(feat_cl)
        labels, labels_h = labels_list[c], labels_h_list[c]
        labels, labels_h = np.flip(labels, axis=0), np.flip(labels_h, axis=0)
        new_labels = np.zeros((H * W))
        new_labels_h = np.zeros((H * W))

        # We optionally write clustering results to the BB list
        for l in range(len(labels)):
            if feat_cl == 15:
                bb_final_list_flipped[l, 9] = labels_h[l] + 1
            if feat_cl == 20:
                bb_final_list_flipped[l, 10] = labels_h[l] + 1
            if feat_cl == 25:
                bb_final_list_flipped[l, 11] = labels_h[l] + 1
            if feat_cl == 30:
                bb_final_list_flipped[l, 12] = labels_h[l] + 1
            if feat_cl == 35:
                bb_final_list_flipped[l, 13] = labels_h[l] + 1
            if feat_cl == 40:
                bb_final_list_flipped[l, 14] = labels_h[l] + 1
            if feat_cl == 45:
                bb_final_list_flipped[l, 15] = labels_h[l] + 1
            if feat_cl == 50:
                bb_final_list_flipped[l, 16] = labels_h[l] + 1
            img, ind = bb_final_list_flipped[l, 0:2]
            coverage_ind = np.where(segm_array_list[img].flatten() == ind)[0]
            new_labels[coverage_ind] = labels[l] + 1
            new_labels_h[coverage_ind] = labels_h[l] + 1

        ds = create_tiff(
            1, args.path_results + "Kmeans_initial_clusters_" +
            str(feat_cl) + ".TIF", W, H, gdal.GDT_Int16,
            np.reshape(new_labels, (H, W)), geo, proj)
        ds.GetRasterBand(1).SetNoDataValue(0)
        vectorize_tiff(path_results, "Kmeans_initial_clusters_" + str(feat_cl),
                       ds)
        ds = None
        ds = create_tiff(
            1, args.path_results + "Hierarchical_initial_clusters_" +
            str(feat_cl) + ".TIF", W, H, gdal.GDT_Int16,
            np.reshape(new_labels_h, (H, W)), geo, proj)
        ds.GetRasterBand(1).SetNoDataValue(0)
        vectorize_tiff(path_results,
                       "Hierarchical_initial_clusters_" + str(feat_cl), ds)
        ds = None

    np.save(
        args.path_results + "Graph_list_synopsys_clusters_alpha_" +
        str(alpha) + "_t1_" + str(t1) + "_t2_" + str(t2) + "_t3_" + str(t3),
        np.flip(np.copy(bb_final_list_flipped), axis=0))

    end_time = time.time()
    total_time_pretraining = end_time - start_time
    total_time_pretraining = str(
        datetime.timedelta(seconds=total_time_pretraining))
    print_stats(stats_file,
                "Total time encoding =" + str(total_time_pretraining) + "\n")
    image_extended1 = extend(image_array1, patch_size).astype(float)
    image_extended2 = extend(image_array2, patch_size).astype(float)

    for band in range(len(image_extended1)):
        image_extended1[band] = (image_extended1[band] - list_norm[band][0]
                                 ) / (list_norm[band][1] - list_norm[band][0])
        image_extended2[band] = (image_extended2[band] - list_norm[band][0]
                                 ) / (list_norm[band][1] - list_norm[band][0])

    if sampleTrue:
        nbr_patches_per_image = int(H * W / 2)
        samples_list = np.sort(sample(range(H * W), nbr_patches_per_image))
        image = ImageDataset(
            image_extended1, image_extended2, patch_size,
            samples_list)  # we create a dataset with tensor patches
        loader = dsloader(image, gpu, batch_size=batch_size, shuffle=True)

    elif maskTrue:
        mask = np.where((list_image_mask[im] +
                         list_image_mask[im + 1]).flatten() == 0)[0]
        image = ImageDataset(image_extended1, image_extended2, patch_size,
                             mask)  # we create a dataset with tensor patches
        loader = dsloader(image, gpu, batch_size, shuffle=True)

    else:
        image = ImageDataset(
            image_extended1, image_extended2, patch_size,
            list(range(H * W)))  # we create a dataset with tensor patches
        loader = dsloader(image, gpu, batch_size=batch_size, shuffle=True)

    image_enc = ImageDataset(
示例#3
0
    if maskTrue:
        mask = np.where(list_image_mask[ii].flatten() == 1)[0]
        samples_list = np.sort(sample(list(mask), nbr_patches_per_image))
    else:
        samples_list = np.sort(sample(range(H * W), nbr_patches_per_image))
    if image is None:
        image = ImageDataset(
            list_image_extended[ii], patch_size, ii,
            samples_list)  # we create a dataset with tensor patches
    else:
        image2 = ImageDataset(
            list_image_extended[ii], patch_size, ii,
            samples_list)  # we create a dataset with tensor patches
        image = torch.utils.data.ConcatDataset([image, image2])

loader = dsloader(image, gpu, batch_size, shuffle=True)
image = None
list_image_extended = None

with open(path_results + "stats.txt", 'a') as f:
    f.write("patch_size=" + str(patch_size) + "\n")
    f.write("epoch_nb=" + str(epoch_nb) + "\n")
    f.write("batch_size=" + str(batch_size) + "\n")
    f.write("learning_rate=" + str(learning_rate) + "\n")
    f.write("bands_to_keep= " + str(bands_to_keep) + "\n")
    f.write("Nbr patches per image " + str(nbr_patches_per_image) + "\n")
f.close()

# we create models
encoder = Encoder(bands_nb, patch_size)  # On CPU
decoder = Decoder(bands_nb, patch_size)  # On CPU
示例#4
0
def main():
    gpu = on_gpu()
    print("ON GPU is " + str(gpu))

    #Parameters
    parser = argparse.ArgumentParser(description='train')
    parser.add_argument('--satellite',
                        default="SPOT5",
                        type=str,
                        help="choose from SPOT5 and S2")
    parser.add_argument('--patch_size', default=9, type=int)
    parser.add_argument('--patch_size_ndvi', default=5, type=int)
    parser.add_argument('--nb_features',
                        default=10,
                        type=int,
                        help="f parameter from the article")
    parser.add_argument('--batch_size', default=150, type=int)
    parser.add_argument(
        '--bands_to_keep',
        default=4,
        type=int,
        help=
        'whether we delete swir band for spot-5 or blue for S2, defauld - all 4 bands'
    )
    parser.add_argument('--epoch_nb', default=2, type=int)
    parser.add_argument('--learning_rate', default=0.0001, type=float)
    parser.add_argument('--noise_factor',
                        default=0.25,
                        type=float,
                        help='for denoising AE, original images')
    parser.add_argument('--noise_factor_ndvi',
                        default=None,
                        type=float,
                        help='for denoising AE, NDVI branch')
    parser.add_argument(
        '--centered',
        default=True,
        type=bool,
        help='whether we center data with mean and std before training')
    parser.add_argument(
        '--original_layers',
        default=[32, 32, 64, 64],
        type=list,
        help='Nb of conv. layers to build AE')  #Default article model
    parser.add_argument(
        '--ndvi_layers',
        default=[16, 16, True],
        type=list,
        help='Nb of conv. layers to build AE and pooling option'
    )  #Default article model
    args = parser.parse_args()

    start_time = time.time()
    run_name = "." + str(time.strftime("%Y-%m-%d_%H%M%S"))
    print(run_name)

    # We define all the paths
    path_results_final = os.path.expanduser('~/Desktop/Results/TS_clustering/')

    if args.satellite == "SPOT5":
        path_datasets = os.path.expanduser(
            '~/Desktop/Datasets/Montpellier_SPOT5_Clipped_relatively_normalized_03_02_mask_vegetation_water_mode_parts_2004_no_DOS1_/'
        )
        path_datasets_ndvi = os.path.expanduser(
            '~/Desktop/Results/TS_clustering/NDVI_results/NDVI_images/')
        folder_results = "Double_Trivial_feat_" + str(
            args.nb_features) + "_patch_" + str(args.patch_size) + run_name
        path_results = path_results_final + "Conv_3D/" + folder_results + "/"

    else:
        path_datasets = os.path.expanduser(
            '~/Desktop/Datasets/Montpellier_S2_Concatenated_1C_Clipped_norm_4096/'
        )
        path_datasets_ndvi = os.path.expanduser(
            '~/Desktop/Results/TS_clustering/NDVI_results/NDVI_images_S2/')
        folder_results = "Double_Trivial_feat_" + str(
            args.nb_features) + "_patch_" + str(args.patch_size) + run_name
        path_results = path_results_final + "Conv_3D_S2/" + folder_results + "/"

    create_dir(path_results)
    stats_file = path_results + 'stats.txt'
    path_model = path_results + 'model' + run_name + "/"
    create_dir(path_model)

    print_stats(stats_file, str(args), print_to_console=True)
    parser.add_argument('--stats_file', default=stats_file)
    parser.add_argument('--path_results', default=path_results)
    parser.add_argument('--path_model', default=path_model)
    parser.add_argument('--run_name', default=run_name)
    args = parser.parse_args()

    # This part of the code opens and pre-processes the images before creating a dataset
    # This is the part for original images, i am lazy, so i will copy-paste it for ndvi images below
    #We open extended images
    images_list = os.listdir(path_datasets)
    path_list = []
    list_image_extended = []
    list_image_date = []
    for image_name_with_extention in images_list:
        if image_name_with_extention.endswith(
                ".TIF") and not image_name_with_extention.endswith("band.TIF"):
            img_path = path_datasets + image_name_with_extention
            if args.satellite == "SPOT5":
                image_date = (re.search("_([0-9]*)_",
                                        image_name_with_extention)).group(1)
            else:
                image_date = (re.search("S2_([0-9]*).",
                                        image_name_with_extention)).group(1)

            path_list.append(img_path)
            image_array, H, W, geo, proj, bands_nb = open_tiff(
                path_datasets,
                os.path.splitext(image_name_with_extention)[0])
            if args.bands_to_keep == 3:
                if args.satellite == "SPOT5":
                    image_array = np.delete(image_array, 3, axis=0)
                if args.satellite == "S2":
                    image_array = np.delete(image_array, 0, axis=0)
            # We deal with all the saturated pixels
            if args.satellite == "S2":
                for b in range(len(image_array)):
                    image_array[b][image_array[b] > 4096] = np.max(
                        image_array[b][image_array[b] <= 4096])
            if args.satellite == "SPOT5":
                for b in range(len(image_array)):
                    image_array[b][image_array[b] > 475] = np.max(
                        image_array[b][image_array[b] <= 475])
            bands_nb = args.bands_to_keep
            image_extended = extend(
                image_array, args.patch_size
            )  # we mirror image border rows and columns so we would be able to clip patches for the pixels from these rows and cols
            list_image_extended.append(image_extended)
            list_image_date.append(image_date)
    sort_ind = np.argsort(
        list_image_date)  # we arrange images by date of acquisition
    list_image_extended = np.asarray(list_image_extended,
                                     dtype=float)[sort_ind]
    bands_nb = list_image_extended.shape[1]
    temporal_dim = list_image_extended.shape[0]
    list_image_date = np.asarray(list_image_date)[sort_ind]
    nbr_images = len(list_image_extended)
    print(list_image_date)

    if args.centered is True:
        list_norm = []
        for band in range(len(list_image_extended[0])):
            all_images_band = list_image_extended[:, band, :, :].flatten()
            min = np.min(all_images_band)
            max = np.max(all_images_band)
            mean = np.mean(all_images_band)
            std = np.std(all_images_band)
            list_norm.append([min, max, mean, std])

        for i in range(len(list_image_extended)):
            for band in range(len(list_image_extended[0])):
                list_image_extended[i][band] = (
                    list_image_extended[i][band] -
                    list_norm[band][2]) / list_norm[band][3]

    list_norm = []
    for band in range(len(list_image_extended[0])):
        all_images_band = list_image_extended[:, band, :, :].flatten()
        min = np.min(all_images_band)
        max = np.max(all_images_band)
        list_norm.append([min, max])

    for i in range(len(list_image_extended)):
        for band in range(len(list_image_extended[0])):
            list_image_extended[i][band] = (
                list_image_extended[i][band] -
                list_norm[band][0]) / (list_norm[band][1] - list_norm[band][0])

    list_norm = []
    for band in range(len(list_image_extended[0])):
        all_images_band = list_image_extended[:, band, :, :].flatten()
        mean = np.mean(all_images_band)
        std = np.std(all_images_band)
        list_norm.append([mean, std])

    #We do exactly the same with NDVI images. I was lasy to create a separate function for this
    images_list_ndvi = os.listdir(path_datasets_ndvi)
    path_list_ndvi = []
    list_image_extended_ndvi = []
    list_image_date_ndvi = []
    for image_name_with_extention_ndvi in images_list_ndvi:
        if image_name_with_extention_ndvi.endswith(
                ".TIF") and image_name_with_extention_ndvi.startswith("NDVI_"):
            img_path_ndvi = path_datasets_ndvi + image_name_with_extention_ndvi
            # print(img_path_ndvi)
            image_date_ndvi = (re.search(
                "_([0-9]*).", image_name_with_extention_ndvi)).group(1)
            # print(image_date_ndvi)
            # print_stats(stats_file, str(image_date), print_to_console=True)
            path_list_ndvi.append(img_path_ndvi)
            image_array_ndvi, H, W, geo, proj, _ = open_tiff(
                path_datasets_ndvi,
                os.path.splitext(image_name_with_extention_ndvi)[0])
            image_array_ndvi = np.reshape(image_array_ndvi, (1, H, W))
            image_extended_ndvi = extend(image_array_ndvi,
                                         args.patch_size_ndvi)
            list_image_extended_ndvi.append(image_extended_ndvi)
            list_image_date_ndvi.append(image_date_ndvi)
    sort_ind_ndvi = np.argsort(
        list_image_date_ndvi)  # we arrange images by date of acquisition
    list_image_extended_ndvi = np.asarray(list_image_extended_ndvi,
                                          dtype=float)[sort_ind_ndvi]
    list_image_date_ndvi = np.asarray(list_image_date_ndvi)[sort_ind_ndvi]
    print(list_image_date_ndvi)

    if args.centered is True:
        list_norm_ndvi = []
        for band in range(len(list_image_extended_ndvi[0])):
            all_images_band = list_image_extended_ndvi[:, band, :, :].flatten()
            min = np.min(all_images_band)
            max = np.max(all_images_band)
            mean = np.mean(all_images_band)
            std = np.std(all_images_band)
            list_norm_ndvi.append([min, max, mean, std])

        for i in range(len(list_image_extended_ndvi)):
            for band in range(len(list_image_extended_ndvi[0])):
                list_image_extended_ndvi[i][band] = (
                    list_image_extended_ndvi[i][band] -
                    list_norm_ndvi[band][2]) / list_norm_ndvi[band][3]

    list_norm_ndvi = []
    for band in range(len(list_image_extended_ndvi[0])):
        all_images_band = list_image_extended_ndvi[:, band, :, :].flatten()
        min = np.min(all_images_band)
        max = np.max(all_images_band)
        list_norm_ndvi.append([min, max])

    for i in range(len(list_image_extended_ndvi)):
        for band in range(len(list_image_extended_ndvi[0])):
            list_image_extended_ndvi[i][band] = (
                list_image_extended_ndvi[i][band] - list_norm_ndvi[band][0]
            ) / (list_norm_ndvi[band][1] - list_norm_ndvi[band][0])

    list_norm_ndvi = []
    for band in range(len(list_image_extended_ndvi[0])):
        all_images_band = list_image_extended_ndvi[:, band, :, :].flatten()
        mean = np.mean(all_images_band)
        std = np.std(all_images_band)
        list_norm_ndvi.append([mean, std])

    # We create a training dataset from our SITS
    list_image_extended_tr = np.transpose(list_image_extended, (1, 0, 2, 3))
    list_image_extended_ndvi_tr = np.transpose(list_image_extended_ndvi,
                                               (1, 0, 2, 3))
    nbr_patches_per_image = H * W  # Nbr of training patches for the dataset
    print_stats(stats_file,
                "Nbr of training patches  " + str(nbr_patches_per_image),
                print_to_console=True)
    image = ImageDataset(
        list_image_extended_tr,
        list_image_extended_ndvi_tr, args.patch_size, args.patch_size_ndvi,
        range(nbr_patches_per_image))  #we create a dataset with tensor patches
    loader_pretrain = dsloader(image, gpu, args.batch_size, shuffle=True)
    image = None

    # We create encoder and decoder models
    if args.noise_factor is not None:
        encoder = Encoder(bands_nb, args.patch_size, args.patch_size_ndvi,
                          args.nb_features, temporal_dim, args.original_layers,
                          args.ndvi_layers, np.asarray(list_norm),
                          np.asarray(list_norm_ndvi), args.noise_factor,
                          args.noise_factor_ndvi)  # On CPU
    else:
        encoder = Encoder(bands_nb, args.patch_size, args.patch_size_ndvi,
                          args.nb_features, temporal_dim, args.original_layers,
                          args.ndvi_layers)  # On CPU
    decoder = Decoder(bands_nb, args.patch_size, args.patch_size_ndvi,
                      args.nb_features, temporal_dim, args.original_layers,
                      args.ndvi_layers)  # On CPU
    if gpu:
        encoder = encoder.cuda()  # On GPU
        decoder = decoder.cuda()  # On GPU

    print_stats(stats_file, str(encoder), print_to_console=False)

    # We pretrain the model
    pretrain(args.epoch_nb, encoder, decoder, loader_pretrain, args)
    end_time = time.time()
    total_time_pretraining = end_time - start_time
    total_time_pretraining = str(
        datetime.timedelta(seconds=total_time_pretraining))
    print_stats(
        args.stats_file,
        "Total time pretraining =" + str(total_time_pretraining) + "\n")

    # We pass to the encoding part
    start_time = time.time()
    # We create a dataset for SITS encoding, its size depends on the available memory
    image = None
    loader_pretrain = None
    image = ImageDataset(list_image_extended_tr, list_image_extended_ndvi_tr,
                         args.patch_size, args.patch_size_ndvi, range(
                             H * W))  # we create a dataset with tensor patches
    try:
        batch_size = W
        loader_enc_final = dsloader(image,
                                    gpu,
                                    batch_size=batch_size,
                                    shuffle=False)
    except RuntimeError:
        try:
            batch_size = int(W / 5)
            loader_enc_final = dsloader(image,
                                        gpu,
                                        batch_size=batch_size,
                                        shuffle=False)
        except RuntimeError:
            batch_size = int(W / 20)
            loader_enc_final = dsloader(image,
                                        gpu,
                                        batch_size=batch_size,
                                        shuffle=False)
    image = None

    print_stats(stats_file, 'Encoding...')
    encoded_array = encoding(encoder, loader_enc_final, batch_size)

    # We stretch encoded images between 0 and 255
    encoded_norm = []
    for band in range(args.nb_features):
        min = np.min(encoded_array[:, band])
        max = np.max(encoded_array[:, band])
        encoded_norm.append([min, max])
    for band in range(args.nb_features):
        encoded_array[:, band] = 255 * (
            encoded_array[:, band] - encoded_norm[band][0]) / (
                encoded_norm[band][1] - encoded_norm[band][0])
    print(encoded_array.shape)

    # We write the image
    new_encoded_array = np.transpose(encoded_array, (1, 0))
    ds = create_tiff(
        encoded_array.shape[-1], args.path_results + "Encoded_3D_conv_" +
        str(encoded_array.shape[-1]) + ".TIF", W, H, gdal.GDT_Int16,
        np.reshape(new_encoded_array,
                   (encoded_array.shape[-1], H, W)), geo, proj)
    ds.GetRasterBand(1).SetNoDataValue(-9999)
    ds = None

    end_time = time.time()
    total_time_pretraining = end_time - start_time
    total_time_pretraining = str(
        datetime.timedelta(seconds=total_time_pretraining))
    print_stats(stats_file,
                "Total time encoding =" + str(total_time_pretraining) + "\n")
示例#5
0
# We normalize the couple of images
for band in range(len(image_extended1)):
    image_extended1[band] = (image_extended1[band] - list_norm[band][0]) / (
        list_norm[band][1] - list_norm[band][0])
    image_extended2[band] = (image_extended2[band] - list_norm[band][0]) / (
        list_norm[band][1] - list_norm[band][0])

# Create the dataset for finetuning
# If we finetune the images only on the sample of patches
if sampleTrue:
    nbr_patches_per_image = int(H * W / 2)
    samples_list = np.sort(sample(range(H * W), nbr_patches_per_image))
    image = ImageDataset(
        image_extended1, image_extended2, patch_size,
        samples_list)  # we create a dataset with tensor patches
    loader = dsloader(image, gpu, batch_size, shuffle)
else:
    image = ImageDataset(
        image_extended1, image_extended2, patch_size,
        list(range(H * W)))  # we create a dataset with tensor patches
    loader = dsloader(image, gpu, batch_size, shuffle)

# Create the dataset for the encoding
image_enc = ImageDataset(
    image_extended1, image_extended2, patch_size,
    list(range(H * W)))  # we create a dataset with tensor patches

#we save everything to stats file
with open(path_results + "stats.txt", 'a') as f:
    f.write(
        "Relu activations for every layer except the last one. The last one is not activated"
def main():
    gpu = on_gpu()
    print("ON GPU is " + str(gpu))

    start_time = time.time()
    run_name = "." + str(time.strftime("%Y-%m-%d_%H%M"))
    print(run_name)

    #Parameters
    parser = argparse.ArgumentParser(description='train')
    parser.add_argument('--patch_size', default=9, type=int)
    parser.add_argument('--nb_features', default=5, type=int)
    parser.add_argument('--batch_size', default=150, type=int)
    parser.add_argument('--bands_to_keep', default=4, type=int)
    parser.add_argument('--epoch_nb', default=4, type=int)
    parser.add_argument('--satellite', default="SPOT5", type=str)
    parser.add_argument('--learning_rate', default=0.0001, type=float)
    args = parser.parse_args()

    # path with images to encode
    path_datasets = os.path.expanduser(
        '~/Desktop/Datasets/Montpellier_SPOT5_Clipped_relatively_normalized_03_02_mask_vegetation_water_mode_parts_2004_no_DOS1_/'
    )
    # folder and path to results
    folder_results = "All_images_ep_" + str(args.epoch_nb) + "_patch_" + str(
        args.patch_size) + "_batch_" + str(args.batch_size) + "_feat_" + str(
            args.nb_features) + "_lr_" + str(
                args.learning_rate) + run_name + "_noise1"
    path_results = os.path.expanduser(
        '~/Desktop/Results/Encode_TS_noise/') + folder_results + "/"
    create_dir(path_results)
    # folder with AE models
    path_model = path_results + 'model' + run_name + "/"
    create_dir(path_model)
    # file with corresponding statistics
    stats_file = path_results + 'stats.txt'

    print_stats(stats_file, str(args), print_to_console=False)
    parser.add_argument('--stats_file', default=stats_file)
    parser.add_argument('--path_results', default=path_results)
    parser.add_argument('--path_model', default=path_model)
    parser.add_argument('--run_name', default=run_name)
    args = parser.parse_args()

    #We open images and "extend" them (we mirror border rows and columns for correct patch extraction)
    images_list = os.listdir(path_datasets)
    path_list = []
    list_image_extended = []
    list_image_date = []
    for image_name_with_extention in images_list:
        if image_name_with_extention.endswith(
                ".TIF") and not image_name_with_extention.endswith("band.TIF"):
            img_path = path_datasets + image_name_with_extention
            path_list.append(img_path)
            image_date = (re.search("_([0-9]*)_",
                                    image_name_with_extention)).group(1)
            # we open images
            image_array, H, W, geo, proj, bands_nb = open_tiff(
                path_datasets,
                os.path.splitext(image_name_with_extention)[0])
            # we delete swir bands for spot-5 or blue for Sentinel-2 if needed
            if args.bands_to_keep == 3:
                if args.satellite == "SPOT5":
                    image_array = np.delete(image_array, 3, axis=0)
                else:
                    image_array = np.delete(image_array, 0, axis=0)
            bands_nb = args.bands_to_keep
            # we extend image
            image_extended = extend(image_array, args.patch_size)
            list_image_extended.append(image_extended)
            list_image_date.append(image_date)
    sort_ind = np.argsort(
        list_image_date)  # we arrange images by date of acquisition
    list_image_extended = np.asarray(list_image_extended,
                                     dtype=float)[sort_ind]
    list_image_date = np.asarray(list_image_date)[sort_ind]

    # We normalize all the images with dataset mean and std
    list_norm = []
    for band in range(len(list_image_extended[0])):
        all_images_band = list_image_extended[:, band, :, :].flatten()
        min = np.min(all_images_band)
        max = np.max(all_images_band)
        mean = np.mean(all_images_band)
        std = np.std(all_images_band)
        list_norm.append([min, max, mean, std])

    for i in range(len(list_image_extended)):
        for band in range(len(list_image_extended[0])):
            list_image_extended[i][band] = (
                list_image_extended[i][band] -
                list_norm[band][2]) / list_norm[band][3]

    # We rescale from 0 to 1
    list_norm = []
    for band in range(len(list_image_extended[0])):
        all_images_band = list_image_extended[:, band, :, :].flatten()
        min = np.min(all_images_band)
        max = np.max(all_images_band)
        mean = np.mean(all_images_band)
        std = np.std(all_images_band)
        list_norm.append([min, max, mean, std])

    for i in range(len(list_image_extended)):
        for band in range(len(list_image_extended[0])):
            list_image_extended[i][band] = (
                list_image_extended[i][band] -
                list_norm[band][0]) / (list_norm[band][1] - list_norm[band][0])

    # We recompute mean and std to use them for creation of Gaussian noise later
    list_norm = []
    for band in range(len(list_image_extended[0])):
        all_images_band = list_image_extended[:, band, :, :].flatten()
        mean = np.mean(all_images_band)
        std = np.std(all_images_band)
        list_norm.append([mean, std])

    # We create training and validation datasets with H*W/(SITS_length)*2 patches by concatenating datasets created for every image
    image = None
    image_valid = None
    nbr_patches_per_image = int(H * W / len(list_image_extended) * 2)
    # nbr_patches_per_image = H * W
    for ii in range(len(list_image_extended)):
        samples_list = np.sort(sample(range(H * W), nbr_patches_per_image))
        samples_list_valid = np.sort(
            sample(range(H * W), int(nbr_patches_per_image / 100)))
        if image is None:
            image = ImageDataset(
                list_image_extended[ii], args.patch_size, ii,
                samples_list)  # we create a dataset with tensor patches
            image_valid = ImageDataset(
                list_image_extended[ii], args.patch_size, ii,
                samples_list_valid)  # we create a dataset with tensor patches
        else:
            image2 = ImageDataset(
                list_image_extended[ii], args.patch_size, ii,
                samples_list)  # we create a dataset with tensor patches
            image = torch.utils.data.ConcatDataset([image, image2])
            image_valid2 = ImageDataset(
                list_image_extended[ii], args.patch_size, ii,
                samples_list_valid)  # we create a dataset with tensor patches
            image_valid = torch.utils.data.ConcatDataset(
                [image_valid, image_valid2])

    loader = dsloader(image, gpu, args.batch_size, shuffle=True)
    loader_valid = dsloader(image_valid, gpu, H, shuffle=False)

    # we create AE model
    encoder = Encoder(bands_nb, args.patch_size, args.nb_features,
                      np.asarray(list_norm))  # On CPU
    decoder = Decoder(bands_nb, args.patch_size, args.nb_features)  # On CPU
    if gpu:
        encoder = encoder.cuda()  # On GPU
        decoder = decoder.cuda()  # On GPU

    optimizer_encoder = torch.optim.Adam(encoder.parameters(),
                                         lr=args.learning_rate)
    optimizer_decoder = torch.optim.Adam(decoder.parameters(),
                                         lr=args.learning_rate)

    criterion = nn.MSELoss()

    with open(path_results + "stats.txt", 'a') as f:
        f.write(str(encoder) + "\n")
    f.close()

    # Here we deploy early stopping algorithm taken from https://github.com/Bjarten/early-stopping-pytorch
    # to track the average training loss per epoch as the model trains
    avg_train_losses = []
    # to track the average validation loss per epoch as the model trains
    avg_valid_losses = []
    early_stopping = EarlyStopping(patience=1, verbose=True)

    # we train the model
    def train(epoch):
        encoder.train()
        decoder.train()
        train_loss_total = 0
        for batch_idx, (data, _, _) in enumerate(loader):
            if gpu:
                data = data.cuda()
            encoded, id1 = encoder(Variable(data))
            decoded = decoder(encoded, id1)
            loss = criterion(decoded, Variable(data))
            train_loss_total += loss.item()
            optimizer_encoder.zero_grad()
            optimizer_decoder.zero_grad()
            loss.backward()
            optimizer_encoder.step()
            optimizer_decoder.step()
            if (batch_idx + 1) % 200 == 0:
                print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                    (epoch), (batch_idx + 1) * args.batch_size,
                    len(samples_list) * len(list_image_extended),
                    100. * (batch_idx + 1) / len(loader), loss.item()))
        train_loss_total = train_loss_total / len(loader)
        epoch_stats = "Epoch {} Complete: Avg. Loss: {:.7f}".format(
            epoch, train_loss_total)
        print(epoch_stats)
        with open(path_results + "stats.txt", 'a') as f:
            f.write(epoch_stats + "\n")
        f.close()

        # We save trained model after each epoch. Optional
        torch.save([encoder, decoder],
                   (path_model + 'ae-model_ep_' + str(epoch + 1) + "_loss_" +
                    str(round(train_loss_total, 5)) + run_name + '.pkl'))
        torch.save(
            [encoder.state_dict(), decoder.state_dict()],
            (path_model + 'ae-dict_ep_' + str(epoch + 1) + "_loss_" +
             str(round(train_loss_total, 5)) + run_name + '.pkl'))

        #Validation part
        valid_loss_total = 0
        encoder.eval()
        decoder.eval()  # prep model for evaluation
        for batch_idx, (data, _, _) in enumerate(loader_valid):
            if gpu:
                data = data.cuda()
            # forward pass: compute predicted outputs by passing inputs to the model
            encoded, id1 = encoder(Variable(data))
            decoded = decoder(encoded, id1)
            # calculate the loss
            loss = criterion(decoded, Variable(data))
            # record validation loss
            valid_loss_total += loss.item()

        valid_loss_total = valid_loss_total / len(loader_valid)

        avg_train_losses.append(train_loss_total)
        avg_valid_losses.append(valid_loss_total)

        epoch_len = len(str(args.epoch_nb))

        print_msg = (f'[{epoch:>{epoch_len}}/{args.epoch_nb:>{epoch_len}}] ' +
                     f'train_loss: {train_loss_total:.5f} ' +
                     f'valid_loss: {valid_loss_total:.5f}')
        print(print_msg)

        # We plot the loss
        if (epoch + 1) % 5 == 0:
            plotting(epoch, avg_train_losses, path_results)

        # early_stopping needs the validation loss to check if it has decresed,
        # and if it has, it will make a checkpoint of the current model
        early_stopping(valid_loss_total, [encoder, decoder])

    for epoch in range(1, args.epoch_nb + 1):
        train(epoch)
        if early_stopping.early_stop:
            print("Early stopping")
            break

    end_time_learning = time.clock()
    total_time_learning = end_time_learning - start_time
    total_time_learning = str(datetime.timedelta(seconds=total_time_learning))
    print_stats(args.stats_file,
                "Total time pretraining =" + str(total_time_learning) + "\n")

    # We get the best model (here by default it is the last one)
    best_epoch = epoch
    best_epoch_loss = avg_train_losses[best_epoch - 1]
    print("best epoch " + str(best_epoch))
    print("best epoch loss " + str(best_epoch_loss))
    best_encoder = encoder
    if gpu:
        best_encoder = best_encoder.cuda()  # On GPU

    #ENCODING PART
    for ii in range(len(list_image_extended)):
        print("Encoding " + str(list_image_date[ii]))
        samples_list = np.array(range(H * W))
        image_encode = ImageDataset(
            list_image_extended[ii], args.patch_size, ii,
            samples_list)  # we create a dataset with tensor patches

        loader_encode = dsloader(image_encode, gpu, H, shuffle=False)

        name_results = list_image_date[ii]
        encode_image(best_encoder, loader_encode, H * 10, args.nb_features,
                     gpu, H, W, geo, proj, name_results, path_results)

    end_time_encoding = time.time()
    total_time_encoding = end_time_encoding - end_time_learning
    total_time_encoding = str(datetime.timedelta(seconds=total_time_encoding))
    print_stats(args.stats_file,
                "Total time encoding =" + str(total_time_encoding) + "\n")