CoolFace
Modelpublic

fernandoperlar/preprocessing_image

sourceHugging Faceupdated 5y agoView on Hugging Face
0likes
Model.py221 linesDownload Raw Back to scripts
1from logging import Filter2import matplotlib.pyplot as plt3import matplotlib.cm as cm4import numpy as np5import cv2 as cv6import tensorflow as tf7from keras import callbacks, models, layers, utils, losses, preprocessing, backend8from sklearn import metrics9from tensorflow.keras import optimizers10from .Misc import *11 12class Model:13	def __init__(self, name, filter, new=True, summary=True, plot=True):14		self.name = name15		self.filter = filter16		self.model = self.__create_model()17		self.weights_path = f"./output/{self.name}/weights_" + "{epoch:03d}" + ".hdf5"18		self.best_epoch = 019 20		computer.create_output_folder(self.name, new)21		22		utils.vis_utils.plot_model(self.model, to_file=f"./output/{self.name}/model.png", show_shapes=True, show_layer_names=True)23 24		if summary:25			self.model.summary()26 27		if plot:28			plt.imshow(plt.imread(f"./output/{self.name}/model.png"))29			plt.axis("off")30 31			plt.show()32 33	def __create_model(self):34		class FilterLayer(layers.Layer):35			def __init__(self, filter, **kwargs):36				self.filter = filter37 38				super(FilterLayer, self).__init__(name="filter_layer", **kwargs)39 40			def call(self, image):41				shape = image.shape42				[image, ] = tf.py_function(self.filter, [image], [tf.float32])43				image = backend.stop_gradient(image)44				image.set_shape(shape)45				46				return image47 48			def get_config(self):49				return super().get_config()50 51		model = models.Sequential()52 53		model.add(layers.Input(shape=(215, 538, 3)))54		model.add(FilterLayer(filter=self.filter))55 56		model.add(layers.Conv2D(32, (3, 3), activation="relu"))57		model.add(layers.MaxPooling2D(pool_size=(2, 2)))58 59		model.add(layers.Conv2D(32, (3, 3), activation="relu"))60		model.add(layers.GlobalAveragePooling2D())61 62		model.add(layers.Dropout(rate=0.4))63		model.add(layers.Dense(32, activation="relu"))64		model.add(layers.Dropout(rate=0.4))65		model.add(layers.Dense(2, activation="softmax"))66 67		return model68 69	def compile(self):		70		self.model.compile(loss=losses.binary_crossentropy, optimizer=optimizers.Adam(learning_rate=5*10e-4), metrics=["accuracy"])71 72		with open(f"./output/{self.name}/model.json", "w") as json_file:73			json_file.write(self.model.to_json())74 75	def fit(self, train_generator, validation_generator, epochs, verbose=True, plot=True):76		class GetProgress(callbacks.Callback):77			def __init__(self, name, weights_path):78				self.name = name79				self.weights_path = weights_path80				self.best_accuracy = 081				self.best_epoch = 082 83			def on_epoch_end(self, epoch, logs=None):84				if logs["val_accuracy"] > self.best_accuracy:85					self.best_accuracy = logs["val_accuracy"]86					self.best_epoch = epoch87 88				print(89					f"\rModel {self.name} -> " +90					f"Epoch {epoch + 1}/{epochs} -> " +91					f"Accuracy (Validation): {round(logs['val_accuracy'], 2)} -> " +92					f"{self.weights_path.format(epoch=self.best_epoch + 1)}"93				, end="")94 95				if epoch + 1 >= epochs:96					print("\n", end="")97 98		checkpoint = callbacks.ModelCheckpoint(99			self.weights_path,100			monitor="val_accuracy",101			verbose=1 if verbose else 0,102			save_best_only=True,103			mode="max"104		)105 106		get_progress = GetProgress(self.name, self.weights_path)107 108		history = self.model.fit(109			train_generator,110			epochs=epochs,111			verbose=1 if verbose else 0,112			validation_data=validation_generator,113			callbacks=[114				checkpoint,115				get_progress116			]117		)118 119		self.best_epoch = get_progress.best_epoch120 121		if plot:122			plt.style.use("ggplot")123 124			plt.figure()125 126			plt.plot(history.history["loss"], label="Training loss")127			plt.plot(history.history["val_loss"], label="Validation loss")128			plt.plot(history.history["accuracy"], label="Training accuracy")129			plt.plot(history.history["val_accuracy"], label="Validation accuracy")130 131			plt.title("Training Loss and Accuracy")132			plt.xlabel("Epoch #")133			plt.ylabel("Loss/Accuracy")134			plt.legend(loc="lower left")135 136			plt.show()137 138	def load_model(self, path=None):139		self.model = models.load_model(self.weights_path.format(epoch=self.best_epoch + 1) if path is None else path)140 141	def evaluate(self, predict, path=None):142		if path is not None:143			self.load_model(path)144 145		predictions = np.argmax(self.model.predict(predict), axis=-1)146		cm = metrics.confusion_matrix(predict.classes, predictions)147		148		metrics.ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=np.unique(predict.labels)).plot(cmap=plt.cm.Blues, xticks_rotation=0)149		plt.show()150 151		print(metrics.classification_report(predict.classes, predictions))152 153		TP = cm[1][1]154		TN = cm[0][0]155		FP = cm[0][1]156		FN = cm[1][0]157 158		accuracy = (float(TP + TN) / float(TP + TN + FP + FN))159		print("Accuracy:", round(accuracy, 4))160 161		specificity = (TN / float(TN + FP))162		print("Specificity:", round(specificity, 4))163 164		sensitivity = (TP / float(TP + FN))165		print("Sensitivity:", round(sensitivity, 4))166 167		precision = (TP / float(TP + FP))168		print("Precision:", round(precision, 4))169 170	def visualize_heatmap(self, image):171		img = cv.cvtColor(cv.imread(image.image), cv.COLOR_BGR2RGB).astype("float32") * 1./255172		img = np.expand_dims(img, axis=0)173 174		heatmap = self.__compute_heatmap(img)175		jet_heatmap, superimposed_img = self.__get_heatmap(image.image, heatmap)176 177		fig, ax = plt.subplots(1, 3, figsize=(20, 8))178 179		ax[0].imshow(img[0])180		ax[0].set_title(os.path.basename(image.image))181		ax[1].imshow(preprocessing.image.array_to_img(jet_heatmap))182		ax[1].set_title(f"Real class: {image.category}")183		ax[2].imshow(superimposed_img)184		ax[2].set_title(f"Predicted class: {np.argmax(self.model.predict(img)[0])}")185 186		plt.show()187 188	def compute_heatmap(self, image):189		last_layer = self.model.get_layer(index=2)190 191		grad_model = models.Model(inputs=[self.model.input], outputs=[last_layer.output, self.model.output])192 193		with tf.GradientTape() as tape:194			model_output, last_layer = grad_model(image)195 196			grads = tape.gradient(last_layer[:, 1], model_output)197			pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))198 199		heatmap = model_output[0] @ pooled_grads[..., tf.newaxis]200		heatmap = tf.squeeze(heatmap)201		heatmap = tf.maximum(heatmap, 0)/tf.math.reduce_max(heatmap)202 203		return heatmap.numpy()204 205	def get_heatmap(self, path, heatmap):206		img = preprocessing.image.load_img(path, color_mode="grayscale")207		img = preprocessing.image.img_to_array(img)208 209		jet = cm.get_cmap("jet")210		jet_colors = jet(np.arange(256))[:, :3]211		212		jet_heatmap = jet_colors[np.uint8(255 * heatmap)]213		jet_heatmap = preprocessing.image.array_to_img(jet_heatmap)214		jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))215		jet_heatmap = preprocessing.image.img_to_array(jet_heatmap)216 217		superimposed_img = jet_heatmap * 0.4 + img218		superimposed_img = preprocessing.image.array_to_img(superimposed_img)219 220		return jet_heatmap, superimposed_img221