def calculate_largest_areas(resmaps, thresholds): # initialize largest areas to an empty list largest_areas = [] # initialize progress bar printProgressBar(0, len(thresholds), prefix="Progress:", suffix="Complete", length=80) for index, threshold in enumerate(thresholds): # segment (threshold) residual maps resmaps_th = resmaps > threshold # compute labeled connected components _, areas_th = label_images(resmaps_th) # retieve largest area of all resmaps for current threshold areas_th_total = [item for sublist in areas_th for item in sublist] largest_area = np.amax(np.array(areas_th_total)) largest_areas.append(largest_area) # print progress bar time.sleep(0.1) printProgressBar(index + 1, len(thresholds), prefix="Progress:", suffix="Complete", length=80) return largest_areas
def generate_inspection_plots(self, group, save_dir=None): assert group in ["validation", "test"] logger.info("generating inspection plots on " + group + " images...") l = len(self.filenames) printProgressBar(0, l, prefix="Progress:", suffix="Complete", length=80) for i in range(len(self.imgs_input)): self.plot_input_pred_resmap(index=i, group=group, save_dir=save_dir) # print progress bar time.sleep(0.1) printProgressBar(i + 1, l, prefix="Progress:", suffix="Complete", length=80) if save_dir is not None: logger.info( "all generated files are saved at: \n{}".format(save_dir)) return
def determine_threshold(resmaps, min_area, thresh_min, thresh_max, thresh_step): # set initial threshold, counter and max number of steps n_steps = (thresh_max - thresh_min) // thresh_step + 1 thresholds = np.arange(start=thresh_min, stop=thresh_max + thresh_step, step=thresh_step) # initialize progress bar printProgressBar(0, n_steps, prefix="Progress:", suffix="Complete", length=50) for index, threshold in enumerate(thresholds): # segment (threshold) residual maps resmaps_th = resmaps > threshold # compute labeled connected components _, areas_all = label_images(resmaps_th) # check if area of largest anomalous region is below the minimum area areas_all_flat = [item for sublist in areas_all for item in sublist] largest_area = np.amax(np.array(areas_all_flat)) if min_area > largest_area: time.sleep(0.1) printProgressBar(n_steps, n_steps, prefix="Progress:", suffix="Complete", length=50) break # print progress bar time.sleep(0.1) printProgressBar(index, n_steps, prefix="Progress:", suffix="Complete", length=50) return threshold
def main(args): # Get validation arguments model_path = args.path method = args.method dtype = args.dtype # ============= LOAD MODEL AND PREPROCESSING CONFIGURATION ================ # load model and info model, info, _ = utils.load_model_HDF5(model_path) # set parameters input_directory = info["data"]["input_directory"] architecture = info["model"]["architecture"] loss = info["model"]["loss"] rescale = info["preprocessing"]["rescale"] shape = info["preprocessing"]["shape"] color_mode = info["preprocessing"]["color_mode"] vmin = info["preprocessing"]["vmin"] vmax = info["preprocessing"]["vmax"] nb_validation_images = info["data"]["nb_validation_images"] # get the correct preprocessing function preprocessing_function = get_preprocessing_function(architecture) # ========= LOAD AND PREPROCESS VALIDATION & FINETUNING IMAGES ============= # initialize preprocessor preprocessor = Preprocessor( input_directory=input_directory, rescale=rescale, shape=shape, color_mode=color_mode, preprocessing_function=preprocessing_function, ) # ------------------------------------------------------------------- # get validation generator validation_generator = preprocessor.get_val_generator( batch_size=nb_validation_images, shuffle=False) # retrieve preprocessed validation images from generator imgs_val_input = validation_generator.next()[0] # retrieve validation image_names filenames_val = validation_generator.filenames # reconstruct (i.e predict) validation images imgs_val_pred = model.predict(imgs_val_input) # instantiate TensorImages object to compute validation resmaps tensor_val = postprocessing.TensorImages( imgs_input=imgs_val_input, imgs_pred=imgs_val_pred, vmin=vmin, vmax=vmax, method=method, dtype=dtype, filenames=filenames_val, ) # ------------------------------------------------------------------- # get finetuning generator nb_test_images = preprocessor.get_total_number_test_images() finetuning_generator = preprocessor.get_finetuning_generator( batch_size=nb_test_images, shuffle=False) # retrieve preprocessed test images from generator imgs_test_input = finetuning_generator.next()[0] filenames_test = finetuning_generator.filenames # select a representative subset of test images for finetuning # using stratified sampling assert "good" in finetuning_generator.class_indices index_array = finetuning_generator.index_array classes = finetuning_generator.classes _, index_array_ft, _, classes_ft = train_test_split( index_array, classes, test_size=config.FINETUNE_SPLIT, random_state=42, stratify=classes, ) # get correct classes corresponding to selected images good_class_i = finetuning_generator.class_indices["good"] y_ft_true = np.array( [0 if class_i == good_class_i else 1 for class_i in classes_ft]) # select test images for finetuninig imgs_ft_input = imgs_test_input[index_array_ft] filenames_ft = list(np.array(filenames_test)[index_array_ft]) # reconstruct (i.e predict) finetuning images imgs_ft_pred = model.predict(imgs_ft_input) # instantiate TensorImages object to compute finetuning resmaps tensor_ft = postprocessing.TensorImages( imgs_input=imgs_ft_input, imgs_pred=imgs_ft_pred, vmin=vmin, vmax=vmax, method=method, dtype=dtype, filenames=filenames_ft, ) # ======================== COMPUTE THRESHOLDS =========================== # initialize finetuning dictionary dict_finetune = { "min_area": [], "threshold": [], "TPR": [], "TNR": [], "FPR": [], "FNR": [], "score": [], } # initialize discrete min_area values min_areas = np.arange( start=config.START_MIN_AREA, stop=config.STOP_MIN_AREA, step=config.STEP_MIN_AREA, ) # initialize thresholds thresholds = np.arange( start=tensor_val.thresh_min, stop=tensor_val.thresh_max + tensor_val.thresh_step, step=tensor_val.thresh_step, ) # compute largest anomaly areas in resmaps for increasing thresholds print( "step 1/2: computing largest anomaly areas for increasing thresholds..." ) largest_areas = calculate_largest_areas( resmaps=tensor_val.resmaps, thresholds=thresholds, ) # select best minimum area and threshold pair to use for testing print( "step 2/2: selecting best minimum area and threshold pair for testing..." ) printProgressBar(0, len(min_areas), prefix="Progress:", suffix="Complete", length=80) for i, min_area in enumerate(min_areas): # compare current min_area with the largest area for index, largest_area in enumerate(largest_areas): if min_area > largest_area: break # select threshold corresponding to current min_area threshold = thresholds[index] # apply the min_area, threshold pair to finetuning images y_ft_pred = predict_classes(resmaps=tensor_ft.resmaps, min_area=min_area, threshold=threshold) # confusion matrix tnr, fpr, fnr, tpr = confusion_matrix(y_ft_true, y_ft_pred, normalize="true").ravel() # record current results dict_finetune["min_area"].append(min_area) dict_finetune["threshold"].append(threshold) dict_finetune["TPR"].append(tpr) dict_finetune["TNR"].append(tnr) dict_finetune["FPR"].append(fpr) dict_finetune["FNR"].append(fnr) dict_finetune["score"].append((tpr + tnr) / 2) # print progress bar printProgressBar(i + 1, len(min_areas), prefix="Progress:", suffix="Complete", length=80) # get min_area, threshold pair corresponding to best score max_score_i = np.argmax(dict_finetune["score"]) max_score = float(dict_finetune["score"][max_score_i]) best_min_area = int(dict_finetune["min_area"][max_score_i]) best_threshold = float(dict_finetune["threshold"][max_score_i]) # ===================== SAVE FINETUNING RESULTS ======================== # create a results directory if not existent model_dir_name = os.path.basename(str(Path(model_path).parent)) save_dir = os.path.join( os.getcwd(), "results", input_directory, architecture, loss, model_dir_name, "finetuning", "{}_{}".format(method, dtype), ) if not os.path.isdir(save_dir): os.makedirs(save_dir) # save area and threshold pair finetuning_result = { "best_min_area": best_min_area, "best_threshold": best_threshold, "best_score": max_score, "method": method, "dtype": dtype, "split": config.FINETUNE_SPLIT, } print("finetuning results: {}".format(finetuning_result)) # save validation result with open(os.path.join(save_dir, "finetuning_result.json"), "w") as json_file: json.dump(finetuning_result, json_file, indent=4, sort_keys=False) logger.info("finetuning results saved at {}".format(save_dir)) # save finetuning plots plot_min_area_threshold(dict_finetune, index_best=max_score_i, save_dir=save_dir) plot_scores(dict_finetune, index_best=max_score_i, save_dir=save_dir) return
def generate_inspection_figure(self): # if filenames_plot != []: # indicies = [self.filenames.index(filename) for filename in filenames_plot] # else: indicies = list(range(len(self.imgs_input))) nrows = len(indicies) ncols = 5 printProgressBar(0, nrows, prefix="Progress:", suffix="Complete", length=80) fig, axarr = plt.subplots(nrows=nrows, ncols=ncols, figsize=(25, 5 * nrows)) for i, j in enumerate(indicies): axarr[i, 0].imshow(self.imgs_input[j], vmin=self.vmin, vmax=self.vmax, cmap=None) axarr[i, 0].set_title("Input\n{}".format(self.filenames[j])) axarr[i, 0].set_axis_off() axarr[i, 1].imshow(self.imgs_pred[j], vmin=self.vmin, vmax=self.vmax, cmap=None) axarr[i, 1].set_title("Reconstruction\n{}".format(self.filenames[j])) axarr[i, 1].set_axis_off() # resmap ssim gray res_ssim = axarr[i, 2].imshow( X=self.RC_ssim.resmaps[j], vmin=self.RC_ssim.vmin_resmap, vmax=self.RC_ssim.vmax_resmap, cmap=self.RC_ssim.cmap_resmap, ) axarr[i, 2].set_title("Resmap SSIM\n" + f"score = {self.RC_ssim.scores[j]:.2E}") axarr[i, 2].set_axis_off() if self.RC_ssim.color == "grayscale": fig.colorbar(res_ssim, ax=axarr[i, 2]) # resmap l1 gray res_l1 = axarr[i, 3].imshow( X=self.RC_l1.resmaps[j], vmin=self.RC_l1.vmin_resmap, vmax=self.RC_l1.vmax_resmap, cmap=self.RC_l1.cmap_resmap, ) axarr[i, 3].set_title("Resmap_L1\n" + f"score = {self.RC_l1.scores[j]:.2E}") axarr[i, 3].set_axis_off() if self.RC_l1.color == "grayscale": fig.colorbar(res_l1, ax=axarr[i, 3]) # resmap l2 gray res_l2 = axarr[i, 4].imshow( X=self.RC_l2.resmaps[j], vmin=self.RC_l2.vmin_resmap, vmax=self.RC_l2.vmax_resmap, cmap=self.RC_l2.cmap_resmap, ) axarr[i, 4].set_title("Resmap_L2\n" + f"score = {self.RC_l2.scores[j]:.2E}") axarr[i, 4].set_axis_off() if self.RC_l2.color == "grayscale": fig.colorbar(res_l2, ax=axarr[i, 4]) plt.tight_layout() printProgressBar(i + 1, nrows, prefix="Progress:", suffix="Complete", length=80) return fig