-
Notifications
You must be signed in to change notification settings - Fork 2
/
classify_images_by_vote.py
84 lines (66 loc) · 3.63 KB
/
classify_images_by_vote.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
from pathlib import Path
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay
import tensorflow as tf
from utilities.timer import Timer
from utilities.dataloader import save_dataframe_as_csv
from labeled_images.labeledimages import LabeledTestingImages
from models.modeltrainingarguments import ModelTestingArguments
THRESHOLD = 0.5
def main():
timer = Timer('Classify test images')
arguments = ModelTestingArguments()
images = LabeledTestingImages()
images.load_testing_images(arguments.image_folders, arguments.image_size, arguments.color_mode)
print('Images imported.')
results_dir = Path('test_results')
if not os.path.exists(results_dir):
os.makedirs(results_dir)
combined_results = pd.DataFrame()
combined_results['image filenames'] = images.test_image_file_paths
sum_of_predictions = np.zeros((images.img_count, len(images.class_labels)))
for model_path in arguments.list_of_models:
predicted_class, current_predictions = make_and_save_predictions(model_path, combined_results, images)
generate_confusion_matrix(len(images.class_labels), images, predicted_class, model_path.stem, results_dir)
sum_of_predictions = sum_of_predictions + current_predictions
prediction_accuracy = accuracy_score(images.test_labels, predicted_class)
print(f'### The accuracy of model {model_path.stem} is: {prediction_accuracy*100:0.2f}%. ###')
if len(arguments.list_of_models) > 1:
votes = np.argmax(np.array(sum_of_predictions), axis=1)
generate_confusion_matrix(len(images.class_labels), images, votes, 'vote', results_dir)
combined_results['voted'] = votes
voted_labels = pd.DataFrame(votes)
voted_labels = voted_labels.apply(lambda a: images.class_labels[int(a)], axis=1)
combined_results['voted_class'] = voted_labels
prediction_accuracy = accuracy_score(images.test_labels, votes)
print(f'### The voted classification accuracy is: {prediction_accuracy*100:0.2f}%. ###')
save_dataframe_as_csv(results_dir, 'results', combined_results, timestamp=False)
timer.stop()
timer.print_results()
def make_and_save_predictions(model_path: Path,
combined_results: pd.DataFrame,
images: LabeledTestingImages) -> (np.ndarray, np.ndarray):
model_name = model_path.stem
model = tf.keras.models.load_model(model_path)
print(f'Model {model_path.stem} loaded.')
predictions: np.array = model.predict(images.test_image_set)
predicted_class = np.argmax(np.array(predictions), axis=1)
print('Predictions generated.')
labels = [f'{i} prediction' for i in images.class_labels]
labeled_predictions = pd.DataFrame(predictions, columns=labels)
prediction_column_names = [f'{model_name} {i}' for i in labels]
combined_results[prediction_column_names] = labeled_predictions
combined_results[f'{model_name} - actual class'] = images.test_labels
combined_results[f'{model_name} - voted label'] = predicted_class
return predicted_class, predictions
def generate_confusion_matrix(col, images, predicted_class, matrix_name: str, results_dir: Path) -> None:
matrix = confusion_matrix(images.test_labels, predicted_class, labels=list(range(col)))
display_matrix = ConfusionMatrixDisplay(confusion_matrix=matrix, display_labels=list(range(col)))
display_matrix.plot()
file_name = f'test_set-confusion_matrix-{matrix_name}.png'
plt.savefig(Path(results_dir, file_name), format='png')
if __name__ == '__main__':
main()