diff --git a/Learning/ObjectBased.py b/Learning/ObjectBased.py index aa7aa9636c2bdbe71b5364b66050ac91d2a8ea59..243e1be8cb9d04de76c3f9c2bb9af426eb616da4 100644 --- a/Learning/ObjectBased.py +++ b/Learning/ObjectBased.py @@ -63,23 +63,30 @@ class ObjectBasedClassifier: raise Exception("Not all classes are present in each split.\n" "Please check that you have enough groups (e.g. 2 x (1/test_train_ratio)) per class.") - def train_RF(self, n_estimators): + def train_RF(self, n_estimators, return_true_vs_pred=False): assert('folds' in self.training_base.keys()) models = [] results = [] - for tr_i, ts_i in self.training_base['folds']: + yt_yp = [] + for tr_i, ts_i in tqdm(self.training_base['folds'], desc='Training'): models.append(RandomForestClassifier(n_estimators=n_estimators)) models[-1].fit(self.training_base['X'][tr_i], self.training_base['Y'][tr_i]) l, c = self.training_base['obj_id'][ts_i], models[-1].predict(self.training_base['X'][ts_i]) y_true, y_pred = self.obia_base.true_pred_bypixel(l, c) - results.append( - { - 'conf_matrix': confusion_matrix(y_true, y_pred), - 'accuracy': accuracy_score(y_true, y_pred), - 'kappa' : cohen_kappa_score(y_true, y_pred), - 'p_r_f1': precision_recall_fscore_support(y_true, y_pred, zero_division=0) - } - ) + if return_true_vs_pred: + yt_yp.append((y_true, y_pred)) + else: + results.append( + { + 'conf_matrix': confusion_matrix(y_true, y_pred), + 'accuracy': accuracy_score(y_true, y_pred), + 'kappa' : cohen_kappa_score(y_true, y_pred), + 'p_r_f1': precision_recall_fscore_support(y_true, y_pred, zero_division=0) + } + ) + if return_true_vs_pred: + return models, yt_yp + else: summary = { 'accuracy_mean': np.mean([x['accuracy'] for x in results]), 'accuracy_std': np.std([x['accuracy'] for x in results]), @@ -92,9 +99,10 @@ class ObjectBasedClassifier: 'f1_mean': np.mean([x['p_r_f1'][2] for x in results], axis=0), 'f1_std': np.std([x['p_r_f1'][2] for x in results], axis=0) } - return models, summary, results + return models, summary, results def classify(self, model, output_file=None, compress='NONE'): + prg = tqdm(desc='Classification', total=len(self.obia_base.tiles)) if isinstance(model, list): for t, L, X in self.obia_base.tiled_data(normalize=[self.training_base['perc2'], self.training_base['perc98']]): @@ -104,11 +112,13 @@ class ObjectBasedClassifier: prob = np.prod(prob, axis=0) c = model[0].classes_[np.argmax(prob, axis=1)] self.obia_base.populate_map(t, L, c, output_file, compress) + prg.update(1) else: for t,L,X in self.obia_base.tiled_data(normalize=[self.training_base['perc2'], self.training_base['perc98']]): c = model.predict(X) self.obia_base.populate_map(t, L, c, output_file, compress) + prg.update(1) return #TEST CODE @@ -124,9 +134,6 @@ def run_test(): glob.glob('/DATA/Benin/OBSYDYA_data/MORINGA/ext_features')) ''' obc.gen_k_folds(5) - print('Performing Training and Cross-Validation...') - m,s,r = obc.train_RF(100) - print(s) - print('Performing Classification...') - obc.classify(m, '/DATA/Benin/OBSYDYA_data/MORINGAv2/firstmap.tif') - return obc + m,yt_yp = obc.train_RF(100, return_true_vs_pred=True) + obc.classify(m, '/DATA/Moringa_Sample/Parakou/output/classification/firstmap.tif') + return yt_yp diff --git a/Postprocessing/Report.py b/Postprocessing/Report.py new file mode 100644 index 0000000000000000000000000000000000000000..f3addd2c95f164d87499ef4a1abe097705fce931 --- /dev/null +++ b/Postprocessing/Report.py @@ -0,0 +1,32 @@ +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +from sklearn.metrics import ConfusionMatrixDisplay, classification_report +import numpy as np +import os + +def generate_report_figures(yt_yp, out_dir, class_names=None): + with plt.ioff(): + if not os.path.exists(out_dir): + os.makedirs(out_dir) + if not isinstance(yt_yp, list): + yt_yp = [yt_yp] + of = {} + of['conf_matrices'] = [] + for i,r in enumerate(yt_yp): + cm = ConfusionMatrixDisplay.from_predictions(r[0], r[1], display_labels=class_names, normalize='true', + include_values=True, xticks_rotation=45) + of['conf_matrices'].append('{}/conf_matrix_{}.eps'.format(out_dir, str(i).zfill(2))) + cm.figure_.savefig(of['conf_matrices'][-1], bbox_inches='tight') + + of['cl_rep'] = [] + summary = [] + for r in yt_yp: + of['cl_rep'].append(classification_report(r[0], r[1], output_dict=True, target_names=class_names)) + + of['summary'] + fsc = [np.array([x[c]['f1-score'] for x in of['cl_rep']]) for c in class_names] + fsc_m = [np.mean(x) for x in fsc] + fsc_s = [np.std(x) for x in fsc] + + return fsc