def _get_features(self, model): """ :param model: a Keras model instance :return: A list of features """ features = None if self._model_weights: image_path = self._images_path + 'cats4da3c9757cb337c692b9517b9f82abf7f21c681d8b1ce111f7ce546f30bdcf95.jpeg' PrintHelper.info_print("in if : ", image_path) img = image.load_img(image_path, target_size=self._target_size) x = image.img_to_array(img) x = x.transpose(1, 0, 2) x = np.expand_dims(x, axis=0) x = preprocess_input(x) features = model.predict(x) else: vaidation_datagen = ImageDataGenerator() validation_generator = vaidation_datagen.flow_from_directory( self._images_path, target_size=self._target_size, batch_size=20, class_mode='binary', shuffle=False) try: features = model.predict_generator(validation_generator, steps=self._image_count) except ValueError as e: PrintHelper.failure_print("_get features.....", e) return features
def get_saved_models(): """ :return: """ if request.method != 'GET': abort(403) try: saved_models = DatabaseFunctions().find_all_items( database_name=modelConstants.database, collection_name=modelConstants.collection) if saved_models is None: PrintHelper().failure_print('No models found in the database') return Response.create_failure_response('No saved models found') else: return Response.create_success_response( saved_models, 'Fetched models successfully') except Exception as e: PrintHelper().failure_print('sphere_WebAPI', e) return Response.create_failure_response('Database error')
def download_main_image_dataset(self, image_list): successfully_downloaded = False for key, value in image_list.items(): dataset = DatabaseFunctions().find_item(imageDatasetConstants.database, imageDatasetConstants.collection, imageDatasetConstants.id_dataset_name, key) if dataset is None: imageurls = [] for image in value: imagemodel = ImageModel() imagemodel.thumbnail = image['thumbnailUrl'] imagemodel.content = image['contentUrl'] imagemodel.format = image['format'] imageurls.append(imagemodel) self.imageUrls = imageurls successfully_downloaded = self._download_image_dataset(key) if successfully_downloaded: number_of_images = Constants.get_number_of_files(main_image_data_dir, key) mongo_entry = { 'name' : key, 'count': number_of_images } DatabaseFunctions().insert_item(imageDatasetConstants.database, imageDatasetConstants.collection, items_to_insert=mongo_entry) else: PrintHelper.warning_print("Image dataset already present") continue
def extract_features(self): """ :return: A list of features """ try: model = self._load_model() features = self._get_features(model) return features except Exception as e: PrintHelper.failure_print("extract features.....", e)
def get_predictions(self): """ :return: a list of predictions """ features = self.extract_features() predictions = None try: predictions = decode_predictions(features, top=3) except ValueError as e: PrintHelper.failure_print("get predictions.....", e) shutil.rmtree(self._images_path) return predictions
def recieve_image_dataset_from_user(self, fileList, class_name): destination = os.path.dirname(os.path.realpath(__file__)) + main_image_data_dir + class_name + "/" for upload in fileList: filename = upload.filename.rsplit("/")[0] PrintHelper.info_print("Uploaded: ", filename) Constants.directory_validation(destination) upload.save(destination + filename) number_of_images = Constants.get_number_of_files(main_image_data_dir, class_name) mongo_entry = { 'name' : class_name, 'count': number_of_images } DatabaseFunctions().insert_item(imageDatasetConstants.database, imageDatasetConstants.collection, items_to_insert=mongo_entry)
def invalid_request(error): """ :return: """ PrintHelper().failure_print('403 Error') return make_response( jsonify({ Constants.status: Constants.false, Constants.error_message: 'Invalid request' }), 403)
def not_found(error): """ :return: """ PrintHelper().failure_print('404 Error') return make_response( jsonify({ Constants.status: Constants.false, Constants.error_message: 'Not found' }), 404)
def image_dataset_upload(): try: form = request.form class_name = "" for key, value in form.items(): if key == 'class_name': class_name = value image_file_list = request.files.getlist("file") ImageDownloader().recieve_image_dataset_from_user( image_file_list, class_name) return Response.create_success_response( "Images Downloaded successfully", "success") except Exception as e: PrintHelper.failure_print("An error occurered: " + str(e)) return Response.create_failure_response("An error occurred: " + str(e))
def get_image_dataset_list(): """ :return: """ try: image_dataset = DatabaseFunctions().find_all_items( imageDatasetConstants.database, imageDatasetConstants.collection) return Response.create_success_response( image_dataset, 'Dataset fetched successfully') except Exception as e: PrintHelper().failure_print(e) return Response.create_failure_response('Database Error')
def _load_model(self): model = None try: if self._model_name == 'VGG16' or self._model_name == 'vgg16': model = VGG16(weights='imagenet', include_top=True) elif self._model_name == 'VGG19' or self._model_name == 'vgg19': model = VGG19(weights='imagenet', include_top=True) elif self._model_name == 'ResNet50' or self._model_name == 'resNet50' \ or self._model_name == 'Resnet50' or self._model_name == 'resnet50': model = ResNet50(weights='imagenet', include_top=True) elif self._model_name == 'Xception' or self._model_name == 'xception': model = Xception(weights='imagenet', include_top=True) elif self._model_name == 'InceptionV3' or self._model_name == 'inceptionV3' \ or self._model_name == 'inceptionv3' or self._model_name == 'Inceptionv3': model = InceptionV3(weights='imagenet', include_top=True) else: model = load_model(self._model_path) model.load_weights(self._model_weights) except Exception as e: PrintHelper.failure_print("loading models.....", e) return model
def download_dataset_images(): if not request.json or 'images' not in request.json: abort(400) try: image_list = request.json['images'] background_image_downloader.delay(image_list) return Response.create_success_response( "Images Downloaded", "Images are being downloaded. Once downloaded, " "they will be available for training") except Exception as e: PrintHelper().failure_print(e) return Response.create_failure_response( 'Could not download images with Error: ' + str(e))
def __init__(self, model_name, images, image_count, model_hash=None, base_model=None): """ :param model_name: name/hash of the model to predict/extract-features from :param images: path for the images downlaoded :param model_hash: hash saved in the database: required for loading weights and files :param base_model: required only when a custom generated model is being evaluated, check what is the base model of the model being used """ self._images_path = images self._model_name = model_name size = Constants.get_image_dimensions(model_name) self._target_size = (size, size) self._image_count = image_count self._model_path = None self._model_weights = None # only required for custom models, in which case base_model should be supplied if base_model is not None and model_hash is not None: try: self._model_path = os.path.dirname(os.path.realpath( __file__)) + Constants.saving_model_specific_file( base_model ) + base_model + '----model_file' + model_hash + '.h5' self._model_weights = os.path.dirname( os.path.realpath( __file__)) + Constants.saving_model_weights( base_model ) + base_model + '----weights' + model_hash + '.h5' except Exception as e: PrintHelper.failure_print("model file creation", e)
def start_validation(): """ :return: """ if request.method != 'POST': abort(403) if not request.json or 'model' not in request.json or 'hash' not in request.json: abort(400) try: model_name = request.json['model'] hash_key = request.json['hash'] start_background_validation.delay(model_name, hash_key) return Response.create_success_response('Validation Started', 'Validation Started') except Exception as e: PrintHelper().failure_print(e) return Response.create_failure_response( 'Could not start validation process')
def start_validation(model_name, class_hash): """ :return: """ img_width = Constants.get_image_dimensions(model_name) img_height = img_width cph = PrintHelper() validation_data_dir = os.path.dirname(os.path.realpath(__file__)) + test_data_dir + class_hash base_validation_dir = os.path.dirname(os.path.realpath(__file__)) + test_data_dir save_weights = os.path.dirname( os.path.realpath(__file__)) + Constants.weights_directory_path + 'Weights#' + class_hash + '.h5' save_model_path = os.path.dirname( os.path.realpath(__file__)) + Constants.model_file_directory_path + 'Model_file#' + class_hash + '.h5' batch_size = 5 number_of_files = ModelValidation.number_of_images(validation_data_dir) cph.info_print('Loading Model') model = load_model(save_model_path) model.load_weights(save_weights) models_result = SaveModelToMongo.validation_started(class_hash) PrintHelper.info_print(' Model Loaded') model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) PrintHelper.info_print(' Model Compiled') # prepare data augmentation configuration PrintHelper.info_print('creating image data generator') validation_generator = DataGeneratorUtility.validation_data_generator(img_height, img_width, batch_size=batch_size, validation_data_dir=validation_data_dir) PrintHelper.info_print('Starting Evaluate Generator') loss, accuracy = model.evaluate_generator(validation_generator,number_of_files) PrintHelper.info_print('Loss: ', loss, ' Accuracy: ', accuracy) shutil.rmtree(validation_data_dir) SaveModelToMongo.validation_completed(class_hash=class_hash, stats=cph.return_string('Accuracy: ', round(accuracy, 4), ' Loss: ', round(loss, 4)), models_result=models_result)
import os import shutil import random import requests import hashlib from libraries.image_classification.utils import Constants, PrintHelper, ImageModel, main_image_data_dir, \ train_data_dir, test_data_dir, DatabaseFunctions from libraries.image_classification.constants import ImageDatasetConstants as imageDatasetConstants cph = PrintHelper() class ImageDownloader: def __init__(self): pass def __str__(self): return "ImageDownloader" imageUrls = [] directory_name = '' selected_model_name = '' @staticmethod def _request_downloader(url, path): """ :param url: :param path: :return:
def start_predictions(): try: form = request.form model_name = "" # Needed only with custom model training base_model = None model_hash = None ###### for key, value in form.items(): if key == 'model_hash': model_hash = value if key == 'model_name': model_name = value if key == 'model_base_name': base_model = value image_count = 0 image_paths = '' save_files = request.files.getlist("file") for upload in request.files.getlist("file"): filename = upload.filename.rsplit("/")[0] PrintHelper.info_print("Uploaded: ", filename) destination_main = os.path.dirname( os.path.realpath(__file__)) + prediction_images_dir + '/' destination = destination_main + model_name + '/' Constants.directory_validation(destination) upload.save(destination + filename) image_paths = destination_main image_count = +1 feature_extraction = FeatureExtraction(model_name, image_paths, image_count) predictions = feature_extraction.get_predictions() # converting the complex tuple structre into javascript friendly json object count = 0 prediction_array = [] for item in predictions: result_outer = [] for items in item: result_inner = { "class": items[0], "description": items[1], "probability": str(items[2]) } result_outer.append(result_inner) image_file = save_files[count] count = count + 1 image_file_name = image_file.filename.rsplit("/")[0] final_prediction_result = { "filename": image_file_name, "predictions": result_outer } prediction_array.append(final_prediction_result) return Response.create_success_response(prediction_array, "success") except Exception as e: PrintHelper.failure_print("An error occurered: " + str(e)) return Response.create_failure_response("An error occurred: " + str(e))
def image_transfer_and_training(): """ :return: """ if not request.json or 'datasets' not in request.json or 'model' not in request.json: abort(400) try: dataset_items = request.json['datasets'] dataset_string = ','.join(str(element) for element in dataset_items) selected_model_name = request.json['model'] save_name_for_model = request.json['name'] same_name = DatabaseFunctions().find_item( modelConstants.database, modelConstants.collection, modelConstants.mm_model_saved_name, save_name_for_model) if same_name is not None: return Response().create_failure_response( "A model with the same name is already present. Please use a different name" ) if selected_model_name is not "VGG16" and selected_model_name is not "VGG19" and selected_model_name is not "ResNet50" and selected_model_name is not "Xception" and selected_model_name is not "Inceptionv3": models_terms = DatabaseFunctions().find_item( modelConstants.database, modelConstants.collection, modelConstants.mm_model_saved_name, selected_model_name) if models_terms is not None: present_search_terms = models_terms[ modelConstants.mm_model_search_terms] dataset_string = dataset_string + "," + present_search_terms encoded_keys = (dataset_string + selected_model_name).encode('utf-8') classes_hash_key = hashlib.sha256(encoded_keys) hash_digest = classes_hash_key.hexdigest() hash_digest = save_name_for_model + "###" + hash_digest models_result = DatabaseFunctions().find_item( modelConstants.database, modelConstants.collection, modelConstants.mm_model_hash, hash_digest) if models_result is None: PrintHelper().info_print( 'Model was not found, continue with the processing') DatabaseFunctions().insert_item( database_name=modelConstants.database, collection_name=modelConstants.collection, items_to_insert=DatabaseJSONStructure.insert_new_model( dataset_string, hash_digest, selected_model_name, model_save_name=save_name_for_model)) status, number_of_samples, number_of_classes = ImageDownloader( ).transfer_datasets_and_start_training(dataset_items, hash_digest) if status: start_background_training.delay(selected_model_name, hash_digest, number_of_classes, number_of_samples) return Response().create_success_response( '', 'Training Started on selected Model') else: return Response().create_failure_response( 'An already trained or currently in training model is already ' 'present in the database. Please check "View and Validate" tab to ' 'view and test this model') else: PrintHelper().warning_print('Model already present') return Response().create_failure_response( 'An already trained or currently in training model is already ' 'present in the database. Please check "View and Validate" tab to' ' view and test this model') except Exception as e: PrintHelper().failure_print(e) return Response.create_failure_response( 'Exception Occured: image_transfer_and_training' + str(e))