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(
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
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")
# 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")