Exemplo n.º 1
0
class XceptionExtractor:
    '''
    
    '''
    def __init__(self):
        '''
        '''

        self.input_shape = (299, 299, 3)
        self.model = Xception(
            weights='imagenet',
            input_shape=self.input_shape,
            pooling='avg',
            include_top=False,
        )
        self.model.predict(zeros((1, 299, 299, 3)))

    def extract(self, img_path):
        '''
        '''

        img = image.load_img(img_path,
                             target_size=(self.input_shape[0],
                                          self.input_shape[1]))
        img = image.img_to_array(img)
        img = expand_dims(img, axis=0)
        img = preprocess_input(img)
        feat = self.model.predict(img)
        norm_feat = feat[0] / linalg.norm(feat[0])
        return [i.item() for i in norm_feat]
Exemplo n.º 2
0
 def extractImgFeature(self, filename, modelType):
     if modelType == 'inceptionv3':
         from tensorflow.keras.applications.inception_v3 import preprocess_input
         target_size = (299, 299)
         model = InceptionV3()
     elif modelType == 'xception':
         from tensorflow.keras.applications.xception import preprocess_input
         target_size = (299, 299)
         model = Xception()
     elif modelType == 'vgg16':
         from tensorflow.keras.applications.vgg16 import preprocess_input
         target_size = (224, 224)
         model = VGG16()
     elif modelType == 'resnet50':
         from tensorflow.keras.applications.resnet50 import preprocess_input
         target_size = (224, 224)
         model = ResNet50()
     model.layers.pop()
     model = Model(inputs=model.inputs, outputs=model.layers[-1].output)
     image = load_img(filename,
                      target_size=target_size)  # Loading and resizing image
     image = img_to_array(
         image)  # Convert the image pixels to a numpy array
     image = image.reshape((1, image.shape[0], image.shape[1],
                            image.shape[2]))  # Reshape data for the model
     image = preprocess_input(
         image)  # Prepare the image for the CNN Model model
     features = model.predict(
         image, verbose=0)  # Pass image into model to get encoded features
     return features
Exemplo n.º 3
0
    def prediction(self, update, context):
        """
        Prediction method that using pre-trained on ImageNet dataset
        Xception model for recognizing sent user's picture
        returns PICTURE that means switch to picture() method
        you can infinitely send images to bot until you print /cancel 
        or kill bot process by
        """

        id = str(update.message.from_user.id)
        img = image.load_img('userID_{}_photo.jpg'.format(id),
                             target_size=(299, 299))

        update.message.reply_text('[INFO] Preprocessing...')
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)

        update.message.reply_text('[INFO] Recognizing...')
        model = Xception()
        preds = model.predict(x)

        decoded_preds = decode_predictions(preds, top=1)[0][0]

        update.message.reply_text('Predicted: {} with {:.2f}% accuracy'.format(
            decoded_preds[1], decoded_preds[2] * 100))

        update.message.reply_text(
            'Send me another image or /cancel for stop conversation')

        return self.PICTURE
Exemplo n.º 4
0
def generateNewTrainingData(splitRatio, dim=(256, 256)):
    print("Obtaining images.")
    images, labels, classes = imageUploadUtils.getAllTrainImages('temp',
                                                                 dim=dim)

    trainx, testx, trainy, testy = train_test_split(images,
                                                    labels,
                                                    test_size=1 - splitRatio,
                                                    stratify=labels)

    print("Beginning Xception download.")
    xc = Xception(include_top=False,
                  weights='imagenet',
                  input_shape=trainx[0].shape)

    trainx = np.array(trainx)
    testx = np.array(testx)

    print("Beginning preprocessing for training set.")
    trainx = preprocess_input(trainx)

    print("Beginning preprocessing for testing set.")
    testx = preprocess_input(testx)

    print("Beginning passthrough of training set through Xception.")
    trainx = xc.predict(trainx, verbose=1)

    print("Beginning passthrough of testing set through Xception.")
    testx = xc.predict(testx, verbose=1)

    print(f"{len(trainx)} images have been collected for training.")
    print(f"{len(testx)} images have been collected for testing.")
    print(
        f"is data valid? {len(trainx) == len(trainy) and len(testx) == len(testy)}"
    )

    finaldata = (trainx, np.array(trainy), testx, np.array(testy))

    if os.path.exists("output"):
        directoryUtils.rmtree("output")

    os.makedirs("output")

    with open(os.path.join('output', 'labels.dat'), 'wb+') as f:
        pickle.dump(classes, f)

    return finaldata
Exemplo n.º 5
0
def single_feature_extract(imageArray) :
        model = Xception()
        # model = ResNet50(weights='imagenet')
        model.layers.pop()
        model = Model(inputs=model.inputs, outputs=model.layers[-2].output)
        image = cv2.resize(imageArray,((model.input_shape[1],model.input_shape[2])))
        # image = load_img(filename,target_size=(model.input_shape[1],model.input_shape[2]))
        image = img_to_array(image)
        image = np.expand_dims(image,axis=0)
        image = preprocess_input(image)
        feature = model.predict(image)
        return feature
Exemplo n.º 6
0
def extract_features(path):
    img = load_img(path, target_size=(299, 299))
    img = img_to_array(img)
    plt.imshow(img / 255.)
    # img=mpimg.imread(path)
    image = np.expand_dims(img, axis=0)
    image = preprocess_input(image)
    model = Xception(weights='imagenet')
    model = Model(inputs=model.inputs, outputs=model.layers[-2].output)
    feat = model.predict(image)
    plt.show()

    return feat
Exemplo n.º 7
0
    def featuresExtraction(self, dataset, modelType):
        print('Generating image features using ' +
              str(configuration['CNNmodelType']) + ' model...')
        if modelType == 'inceptionv3':
            from tensorflow.keras.applications.inception_v3 import preprocess_input
            target_size = (299, 299)
            model = InceptionV3()
        elif modelType == 'xception':
            from tensorflow.keras.applications.xception import preprocess_input
            target_size = (299, 299)
            model = Xception()
        elif modelType == 'vgg16':
            from tensorflow.keras.applications.vgg16 import preprocess_input
            target_size = (224, 224)
            model = VGG16()
        elif modelType == 'resnet50':
            from tensorflow.keras.applications.resnet50 import preprocess_input
            target_size = (224, 224)
            model = ResNet50()
        else:
            print("please select a appropriate model")

        model.layers.pop(
        )  # Removing the last layer from the loaded model because we dont have to classify the images
        model = Model(inputs=model.inputs, outputs=model.layers[-1].output)
        features = dict()
        for name in tqdm(os.listdir(dataset)):
            filename = dataset + name
            image = load_img(
                filename,
                target_size=target_size)  # Loading and resizing image
            image = img_to_array(
                image)  # Convert the image pixels to a numpy array
            image = image.reshape(
                (1, image.shape[0], image.shape[1],
                 image.shape[2]))  # Reshape the indexs of data for the model
            image = preprocess_input(
                image
            )  # Preprocess the image inorder to pass the image to the CNN Model model
            feature = model.predict(
                image, verbose=0)  # Pass image into model to get features
            imageId = name.split('.')[0]  # Store the features
            features[imageId] = feature

        dump(
            features,
            open(
                configuration['featuresPath'] + 'features_' +
                str(configuration['CNNmodelType']) + '.pkl', 'wb'))
        print("length of total features: ", len(features))
class xceptionClassification(object):

    def __init__(self):
        #this model gets to a top-1 validation accuracy of 0.790   
        self.model  = Xception(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000)
    
    def model_predict(self,image_path):
        img = image.load_img(image_path, target_size=(299,299))
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)
        predictions = self.model.predict(x)
        pred=decode_predictions(predictions, top=3)
        return ','.join([item[1] for item in pred[0]])
Exemplo n.º 9
0
def export_keras_model():
    if not os.path.exists(KERAS_MODEL_PATH):
        model = Xception(weights='imagenet')

        img = image.load_img(IMG_PATH, target_size=(299, 299))
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)

        preds = model.predict(x)
        #preds.tofile('out_0.txt', '\n')
        print('Keras Predicted:', decode_predictions(preds, top=5)[0])

        model.save(KERAS_MODEL_PATH)
Exemplo n.º 10
0
def predict_image():
    #file = request.files['image']
    #filename = os.path.join('selected', file.filename)

    #file.save(filename)

    # Load the VGG19 model
    # https://keras.io/applications/#VGG19
    model = Xception(include_top=True, weights='imagenet')

    # Define default image size for VGG19
    image_size = (299, 299)

    # initialize the response dictionary that will be returned
    message = request.get_json(force=True)
    encoded = message['image']
    decoded = base64.b64decode(encoded)
    img = Image.open(io.BytesIO(decoded))

    # if the image mode is not RGB, convert it
    if img.mode != "RGB":
        img = img.convert("RGB")

    # resize the input image and preprocess it
    img = img.resize(image_size)

    # Preprocess image for model prediction
    # This step handles scaling and normalization for VGG19
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)

    # Make predictions
    predictions = model.predict(x)
    prediction = decode_predictions(predictions, top=1)
    print('Predicted:', decode_predictions(predictions, top=3))

    response = {
        'predictions': {
            'label': np.array(prediction[0][0][1]).tolist(),
            'probability': np.array(prediction[0][0][2]).tolist()
        }
    }

    print(response)

    # return the response dictionary as a JSON response
    return jsonify(response)
Exemplo n.º 11
0
class Xception_imagenet:
    """
    pre-trained xception model
    """
    __name__ = "xception"

    def __init__(self, batch_size=1):
        self.model = Xception(include_top=False,
                              weights='imagenet',
                              pooling="avg")
        self.batch_size = batch_size
        self.data_format = K.image_data_format()

    def predict(self, x):
        if self.data_format == "channels_first":
            x = x.transpose(0, 3, 1, 2)
        x = preprocess_xception(x.astype(K.floatx()))
        return self.model.predict(x, batch_size=self.batch_size)
Exemplo n.º 12
0
def image_data():

    img_feat = dict()
    for name in os.listdir("Flicker8k_Dataset"):
        image = load_img(os.path.join("Flicker8k_Dataset", name),
                         target_size=(299, 299))
        image = img_to_array(image)
        image = np.expand_dims(image, axis=0)
        image = preprocess_input(image)

        model = Xception(weights='imagenet')
        model = Model(inputs=model.inputs, outputs=model.layers[-2].output)
        feat = model.predict(image)
        K.clear_session()

        id = name.split('.')[0]
        img_feat[id] = feat
        print(id, end=" ")

    np.save("ExtractedData/img_features.npy", img_feat)
Exemplo n.º 13
0
def train(num_result_images=25):
    # Convert 2D image matrix => 1D bottleneck vector
    print('\n** GENERATING BOTTLENECKS bottlenecks.csv **')

    # Setup model to convert 2D image matrix => 1D bottleneck vector
    base_model = Xception(include_top=False,
                          weights='imagenet',
                          input_shape=(img_w_size, img_h_size, 3),
                          pooling='avg')

    bottlenecks = base_model.predict(images)

    # TODO:  Change this to json
    np.savetxt("bottleneck.csv", bottlenecks, delimiter=",")
    print('\n** GENERATED BOTTLENECKS to bottleneck.csv **')

    bottlenecks = np.loadtxt("bottleneck.csv", delimiter=",")

    print('\n** GENERATING PAIRWISE pairwise_top_25.json **')
    dist = DistanceMetric.get_metric('euclidean')

    # Calculate pairwise distance -- O(n^2)
    bottleneck_pairwise_dist = dist.pairwise(bottlenecks)

    # Find the top 100 similar images per image
    retrieved_images = []
    for image_idx in range(0, len(bottleneck_pairwise_dist)):
        retrieved_indexes = pd.Series(
            bottleneck_pairwise_dist[image_idx]).sort_values().head(
                num_result_images).index.tolist()
        retrieved_indexes_int = list(
            map(lambda index: int(index), retrieved_indexes))

        pairwise_top_25[image_idx] = retrieved_indexes_int

    with open('pairwise_top_25.json', 'w') as fp:
        json.dump(pairwise_top_25, fp)

    print('\n** GENERATED PAIRWISE to pairwise_top_25.json **')
            if fName[0:2] == '._':
                continue
            if fName.endswith(".JPG") or fName.endswith(".jpg"):
                img_path = os.path.join(path_image, fName)

                #Load the image and crop it
                image_cv2 = cv2.imread(img_path)
                row_min = int(image_cv2.shape[0] * 0.0)
                row_max = int(image_cv2.shape[0] * 1.0)
                col_min = int(image_cv2.shape[1] * 0.33)
                col_max = int(image_cv2.shape[1] * 0.66)
                image_cv2 = image_cv2[row_min:row_max, col_min:col_max]

                #TODO: Instead of just cropping images, we can use semantic segmantion techniques to
                #discard weigh-belt pixels. This would be the best way of refining input data.

                #Read cropped image and preprocess it
                img_data = cv2.resize(image_cv2, (224, 224))
                img_data = np.expand_dims(img_data, axis=0)
                img_data = preprocess_input(img_data)

                #Feed pre-processed image to CNN and save the extracted feature
                cnn_feature = model.predict(img_data)
                featurePath = os.path.join(path_image, featureFolderName,
                                           fName[0:-3] + 'npy')
                np.save(featurePath, cnn_feature)
            else:
                print(
                    'Found a non-jpg file/folder:', fName
                )  #Printing this to keep track of un-processed file/folder names
#Note: for a refrigerator , it predicted 'safe'. However the second probability was correct.
# Predicted: [('n04125021', 'safe', 0.45633033), ('n04070727', 'refrigerator', 0.3461617), ('n03710193', 'mailbox', 0.03995161)]

from tensorflow.keras.applications.xception import Xception
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.xception import preprocess_input, decode_predictions
import numpy as np

#img_path = '../data/refrigerator.jpg'
img_path = '../data/d.jpg'
img = image.load_img(img_path, target_size=(299, 299))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

model = Xception(weights='imagenet')
preds = model.predict(x)
# decode the results into a list of tuples (class, description, probability)
# (one such list for each sample in the batch)
print('Predicted:', decode_predictions(preds, top=3)[0])
Exemplo n.º 16
0
def xception():
    if request.method == "POST":
        instaid = request.form["instaid"]

        #scraping images with beautifulsoup
        url = "https://www.instagram.com/" + instaid
        browser = Browser('chrome')
        browser.visit(url)
        sleep(1)
        bs = BeautifulSoup(browser.html, 'html.parser')

        #finds all the images in website and puts url in df
        images = bs.find_all('img', {'src': re.compile('.jpg')})
        image_urls = []
        for image in images:
            image_urls.append(str(image['src']))
        image_df = pd.DataFrame({"image": image_urls})

        import numpy as np
        import tensorflow as tf

        from tensorflow.keras.preprocessing import image
        from tensorflow.keras.applications.xception import (Xception,
                                                            preprocess_input,
                                                            decode_predictions)

        from PIL import Image
        import requests
        from io import BytesIO

        model = Xception(include_top=True, weights='imagenet')

        prds = []
        pcts = []
        for i in image_urls:
            url = i
            response = requests.get(url)
            img = Image.open(BytesIO(response.content))
            img = img.resize((299, 299), Image.NEAREST)
            x = image.img_to_array(img)
            x = np.expand_dims(x, axis=0)
            x = preprocess_input(x)
            predictions = model.predict(x)
            prds.append(decode_predictions(predictions, top=1)[0][0][1])
            pcts.append(decode_predictions(predictions, top=1)[0][0][2])
#             cnns.append(decode_predictions(predictions, top=3)[0])
        image_df["predictions"] = prds
        image_df["%"] = pcts
        image_df.sort_values("%", ascending=False, inplace=True)
        image_df.reset_index(drop=True, inplace=True)

        #         from IPython.display import Image
        #         from IPython.core.display import HTML

        #         def path_to_image_html(path):
        #             return '<img src="'+ path + '" width="300" >'

        #         print("Server received request for 'About' page...")
        #         return (image_df.to_html(escape=False ,formatters=dict(image=path_to_image_html)))

        gkey = "AIzaSyA-Rjp6nOeJp6815Xt1Kkuxc5XKMiKl_yA"
        depart = request.form["depart"]
        target_radius = 1000

        records = pd.DataFrame()
        target_list = list(set(image_df["predictions"]))[0:5]
        targets = str(depart).split(",")
        for target in targets:
            # Build the endpoint URL
            target_url = (
                f'https://maps.googleapis.com/maps/api/geocode/json?address={target}&key={gkey}'
            )
            geo_data = requests.get(target_url).json()

            target_adr = geo_data["results"][0]["formatted_address"]
            lat = geo_data["results"][0]["geometry"]["location"]["lat"]
            lng = geo_data["results"][0]["geometry"]["location"]["lng"]

            target_coordinates = str(lat) + "," + str(lng)

            #             target_radius = 800
            target_type = ""

            # set up a parameters dictionary

            for target_search in target_list:
                params = {
                    "location": target_coordinates,
                    "keyword": target_search,
                    "radius": target_radius,
                    "type": target_type,
                    "key": gkey
                }

                # base url
                base_url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"

                # run a request using our params dictionary
                response = requests.get(base_url, params=params)
                places_data = response.json()

                n = 0
                # while int(n) > len(places_data):
                while int(n) < len(places_data["results"]):
                    try:
                        price = places_data["results"][int(n)]["price_level"]
                    except KeyError:
                        price = "NA"
                    try:
                        link = places_data["results"][int(n)]["place_id"]
                    except KeyError:
                        link = "NA"
                    try:
                        score = places_data["results"][int(n)]["rating"]
                    except KeyError:
                        score = "NA"
                    try:
                        reviews = places_data["results"][int(
                            n)]["user_ratings_total"]
                    except KeyError:
                        reviews = "NA"
                    try:
                        lat = places_data["results"][int(
                            n)]["geometry"]["location"]["lat"]
                        lon = places_data["results"][int(
                            n)]["geometry"]["location"]["lng"]
#                         dist = pd.read_html(f"http://boulter.com/gps/distance/?from={target_coordinates}&to={poi_coord}&units=k")
#                         distance = float(str(dist[1][1][1]).split(" ")[0])
                    except IndexError or TimeoutError:
                        distance = "NA"


#                         drive_url = f"https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins={target_coordinates}&destinations={poi_coord}&key=AIzaSyA-Rjp6nOeJp6815Xt1Kkuxc5XKMiKl_yA"
#                         drive_res = requests.get(drive_url).json()
#                         distance = drive_res["rows"][0]["elements"][0]["distance"]["value"]/1000
#                         duration= int(drive_res["rows"][0]["elements"][0]["duration"]["value"]/60)
#                     except KeyError:
#                         distance = "NA"
#                         drive_dur = "NA"

#                     try:
#                         walk_url = f"https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins={target_coordinates}&destinations={poi_coord}&mode=walking&key=AIzaSyA-Rjp6nOeJp6815Xt1Kkuxc5XKMiKl_yA"
#                         walk_res = requests.get(walk_url).json()
#                         distance = walk_res["rows"][0]["elements"][0]["distance"]["value"]/1000
#                         walk_dur = int(walk_res["rows"][0]["elements"][0]["duration"]["value"]/60)
#                     except KeyError:
#                         walk_dur = "NA"

#                     try:
#                         transit_url = f"https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins={target_coordinates}&destinations={poi_coord}&mode=transit&key=AIzaSyA-Rjp6nOeJp6815Xt1Kkuxc5XKMiKl_yA"
#                         transit_res = requests.get(transit_url).json()
#                         transit_dur = int(transit_res["rows"][0]["elements"][0]["duration"]["value"]/60)
#                     except KeyError:
#                         transit_dur = "NA"

                    content = pd.DataFrame({
                        "depart":
                        target_adr,
                        "poi":
                        target_search,
                        "name": [places_data["results"][int(n)]["name"]],
                        "score":
                        score,
                        "reviews":
                        reviews,
                        "price":
                        price,
                        "link":
                        link,
                        "address":
                        [places_data["results"][int(n)]["vicinity"]],
                        "lat":
                        lat,
                        "lon":
                        lon
                    })
                    #                                             "drive":duration,
                    #                                             "public":transit_dur,
                    #                                             "walk":walk_dur})
                    records = records.append(content)
                    n += 1
        records.reset_index(drop=True, inplace=True)
        #         records["link"]=records["link"].apply(lambda x: '<a href="https://www.google.com/maps/place/?q=place_id:{0}">link</a>'.format(x))
        #         return (records.to_html(escape=False))
        px.set_mapbox_access_token(
            "pk.eyJ1IjoidGl2bWU3IiwiYSI6ImNrMWEwZDVtNDI4Zm4zYm1vY3o3Z25zejEifQ._yTPkj3nXTzor72zIevLCQ"
        )
        fig = px.scatter_mapbox(records,
                                lat="lat",
                                lon="lon",
                                color="poi",
                                hover_name="name",
                                zoom=13)
        fig.update_layout(autosize=True, width=1500, height=750)
        #                           ,margin=go.layout.Margin(l=50,r=50,b=100,t=100,pad=4))

        return (py.offline.plot(fig, output_type="div"))

    return render_template("xception.html")
print(dict(zip(binary_model.metrics_names, binary_result)))

# we want to know how good the dogs model on all the real dogs, and not only on the ones who predicted as dogs
print('============ dogs model evaluate ============')
dogs_result = dogs_model.evaluate(dogs_test_dataset)
print(dict(zip(dogs_model.metrics_names, dogs_result)))

# we want to know how good the cats model on all the real cats, and not only on the ones who predicted as cats
print('============ cats model evaluate ============')
cats_result = cats_model.evaluate(cats_test_dataset)
print(dict(zip(cats_model.metrics_names, cats_result)))
"""PREDICT MODELS"""
# binary prediction #
classes = train_generator.class_indices
inverted_classes = dict(map(reversed, classes.items()))
binary_predictions = binary_model.predict(test_dataset)
binary_predictions = tf.argmax(binary_predictions, axis=-1).numpy()
binary_predictions = [inverted_classes[i] for i in binary_predictions]

test_df['binary_prediction'] = binary_predictions
"""BREED MODELS"""

# dog breed prediction #
predicted_as_dogs_df = test_df[test_df['binary_prediction'] == 'dog']

if model_name == 'inception_resnet_v2':
    pre_process = preprocess_input_inception_resnet_v2
    predicted_as_dogs_data_gen = ImageDataGenerator(
        preprocessing_function=pre_process)
elif model_name == 'xception':
    pre_process = preprocess_input_xception
Exemplo n.º 18
0

img = get_image(
    "https://upload.wikimedia.org/wikipedia/commons/6/66/"
    "An_up-close_picture_of_a_curious_male_domestic_shorthair_tabby_cat.jpg")

# %%
print(img.shape)
plt.imshow(img)

# %%
# Resize to target shape
img = cv2.resize(img, input_shape)
plt.imshow(img)

# %%
# Xception uses tf preprocessing
img = preprocess_input(img)

# %%
# Note that 299 x 299 is default shape for xception
model = Xception()

# Need a 4th dim for samples
pred = model.predict(np.expand_dims(img, 0))

# %%
decode_predictions(pred, top=5)

# %%
def predict(images_dir_path='temp'):

    print("Obtaining images.")
    subdir = 'images' if images_dir_path == 'temp' else None
    oldImages, imageNames = imageUploadUtils.getAllPredictImages(
        images_dir_path, subdir=subdir)

    model = load_model(
        os.path.join("temp", "model",
                     os.listdir(os.path.join("temp", "model"))[0]))

    print("Preprocessing images.")
    images = preprocess_input(oldImages)

    print("Beginning Xception download.")
    xc = Xception(include_top=False,
                  weights='imagenet',
                  input_shape=images[0].shape)

    print("Beginning passthrough of images through Xception.")
    images = xc.predict(images)

    print("Beginning passthrough of images through trained model.")
    ys = model.predict(images)

    with open(
            os.path.join("temp", "label",
                         os.listdir(os.path.join("temp", "label"))[0]),
            'rb') as f:
        labels = pickle.load(f)

    print("Beginning image output.")
    if images_dir_path == 'temp':
        if os.path.exists("predictions"):
            directoryUtils.rmtree("predictions")
        os.mkdir("predictions")

        counters = dict((v, 0) for v in labels.values())

        for category in counters.keys():
            os.mkdir(os.path.join("predictions", category))

        for i, y in enumerate(ys):
            category = labels[np.argmax(y)]
            cv2.imwrite(
                os.path.join("predictions", category,
                             str(counters[category]) + ".jpg"), oldImages[i])

            counters[category] += 1
    else:
        output_dir = os.path.join(images_dir_path, "predictions")
        if os.path.isdir(output_dir):
            directoryUtils.rmtree(output_dir)
        os.mkdir(output_dir)

        for category in labels.values():
            os.mkdir(os.path.join(output_dir, category))

        for i, y in enumerate(ys):
            category = labels[np.argmax(y)]
            cv2.imwrite(os.path.join(output_dir, category, imageNames[i]),
                        oldImages[i])

    print("Image output complete.")
elif model_name == 'xception':
    model = Xception(weights=None, classes=num_of_classes)
else:
    raise ValueError(f"not supported model name {model_name}")

"""MODEL PARAMS AND CALLBACKS"""
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
checkpoint = ModelCheckpoint(filepath=f'flat_weights_{model_name}.hdf5', save_best_only=True, verbose=1)
early_stopping = EarlyStopping(monitor='val_accuracy', patience=10, verbose=1)
reduce_lr = ReduceLROnPlateau(patience=5, verbose=1)

"""FIT MODEL"""
print('============ fit flat model ============')
model.fit(train_generator, epochs=100, steps_per_epoch=np.ceil(len(train_df) / TRAIN_BATCH_SIZE),
          validation_data=val_dataset, callbacks=[checkpoint, early_stopping, reduce_lr])
# load the best (on validation) weights from .fit() phase
model.load_weights(filepath=f'flat_weights_{model_name}.hdf5')

print('============ predict flat model ============')
# we use the .predict() method and not .evaluate() so we can generate a confusion matrix (for example)
classes = train_generator.class_indices
inverted_classes = dict(map(reversed, classes.items()))
predictions = model.predict(test_dataset)
predictions = tf.argmax(predictions, axis=-1).numpy()
inverted_class_predictions = [inverted_classes[i] for i in predictions]

test_df['flat_prediction'] = inverted_class_predictions

accuracy = len(test_df[test_df['breed'] == test_df['flat_prediction']]) / len(test_df)
print(f'\n#RESULTS {model_name}# Flat Animal breed accuracy: {accuracy}. BATCH_SIZE: {TRAIN_BATCH_SIZE}')