File size: 6,687 Bytes
dfd5176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# -*- coding: utf-8 -*-
"""Butterfly classification with CNN.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/18Jo5pBel2xJCse_nNq61zkDnPN_zzg_u

# Import Libraries and Load Data
"""

## Remove Warnings ##
import warnings
warnings.filterwarnings("ignore")

## Data ##
import numpy as np
import pandas as pd
import os

## Visualization ##
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
import plotly.graph_objects as go

## Image ##
import cv2
from tensorflow.keras.preprocessing.image import ImageDataGenerator

## Tensorflow ##
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Input, Dense , Conv2D , Dropout , Flatten , Activation, MaxPooling2D , GlobalAveragePooling2D
from tensorflow.keras.optimizers import Adam , RMSprop
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.callbacks import ReduceLROnPlateau , EarlyStopping , ModelCheckpoint , LearningRateScheduler
from tensorflow.keras.applications import ResNet50V2

df = pd.read_csv('C:/Users/kamel/Documents/Image Classification/butterfly-dataset/butterflies and moths.csv')
IMAGE_DIR = 'C:/Users/kamel/Documents/Image Classification/butterfly-dataset'
df['filepaths'] = IMAGE_DIR + '/' + df['filepaths']
df.head()

train_df = df.loc[df['data set'] == 'train']
val_df = df.loc[df['data set'] == 'valid']
test_df = df.loc[df['data set'] == 'test']

"""# Exploratory Data Analysis"""

label_counts = df['labels'].value_counts()[:10]

fig = px.bar(x=label_counts.index,
             y=label_counts.values,
             color=label_counts.values,
             text=label_counts.values,
             color_continuous_scale='Blues')

fig.update_layout(
    title_text='Labels Distribution',
    template='plotly_white',
    xaxis=dict(
        title='Label',
    ),
    yaxis=dict(
        title='Count',
    )
)

fig.update_traces(marker_line_color='black',
                  marker_line_width=1.5,
                  opacity=0.8)

fig.show()

"""# Generate Image using ImageDataGenerator"""

# only train data needs to be augmented
train_gen = ImageDataGenerator(horizontal_flip=True, vertical_flip=True, rescale=1/255.)
val_gen = ImageDataGenerator(rescale=1/255.)

train_dir = 'C:/Users/kamel/Documents/Image Classification/butterfly-dataset/train'
val_dir = 'C:/Users/kamel/Documents/Image Classification/butterfly-dataset/valid'

BATCH_SIZE = 16
SEED = 56
IMAGE_SIZE = (244, 244)

train_flow_gen = train_gen.flow_from_directory(directory=train_dir,
                                              class_mode='sparse',
                                              batch_size=BATCH_SIZE,
                                              target_size=IMAGE_SIZE,
                                              seed=SEED)

val_flow_gen = val_gen.flow_from_directory(directory=val_dir,
                                            class_mode='sparse',
                                            batch_size=BATCH_SIZE,
                                            target_size=IMAGE_SIZE,
                                            seed=SEED)

"""# Create Model"""

verbose=False

input_tensor = Input(shape=(224, 224, 3))

base_model = ResNet50V2(input_tensor=input_tensor, include_top=False, weights='imagenet')

bm_output = base_model.output

x = GlobalAveragePooling2D()(bm_output)
x = Dense(1024, activation='relu')(x)
x = Dropout(rate=0.5)(x)
output = Dense(100, activation='softmax')(x)
model = Model(inputs=input_tensor, outputs=output)

if verbose:
    model.summary()

"""# ResNet Modelling"""

model.compile(optimizer=Adam(lr=0.001), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

rlr_cb = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, mode='min', verbose=0)
early_cb = EarlyStopping(monitor='val_loss', patience=5, mode='min', verbose=0)

model.fit(train_flow_gen, epochs=5,
         steps_per_epoch=int(np.ceil(train_df.shape[0]/BATCH_SIZE)),
         validation_data=val_flow_gen,
         validation_steps=int(np.ceil(val_df.shape[0]/BATCH_SIZE)),
         callbacks=[rlr_cb, early_cb])

test_dir = 'C:/Users/kamel/Documents/Image Classification/butterfly-dataset/test'
test_gen = ImageDataGenerator(rescale=1/255.)
test_flow_gen = test_gen.flow_from_directory(directory=test_dir,
                                             class_mode='sparse',
                                             batch_size=BATCH_SIZE,
                                             target_size=IMAGE_SIZE,
                                             seed=SEED)

print('ResNet Test Data Accuracy: {0}'.format(model.evaluate(test_flow_gen)[1:][0]))

# Save the current weights manually
model.save('C:/Users/kamel/Documents/Image Classification/model_checkpoint_manual_effnet.h5')

"""# Deployment"""

import gradio as gr
import tensorflow as tf
from tensorflow.keras.models import load_model
import numpy as np
import cv2

# Load the trained model
model_path = 'C:/Users/kamel/Documents/Image Classification/model_checkpoint_manual_effnet.h5'
model = load_model(model_path)

class_names = ['ADONIS', 'AFRICAN GIANT SWALLOWTAIL', 'AMERICAN SNOOT', 'AN 88', 'APPOLLO', 'ARCIGERA FLOWER MOTH', 'ATALA', 'ATLAS MOTH', 'BANDED ORANGE HELICONIAN', 'BANDED PEACOCK']

# Define a function to preprocess the input image
def preprocess_image(img):
    # Check if img is a file path or an image object
    if isinstance(img, str):
        # Load and preprocess the image
        img = cv2.imread(img)
        img = cv2.resize(img, (224, 224))
        img = img / 255.0  # Normalize pixel values
        img = np.expand_dims(img, axis=0)  # Add batch dimension
    elif isinstance(img, np.ndarray):
        # If img is already an image array, resize it
        img = cv2.resize(img, (224, 224))
        img = img / 255.0  # Normalize pixel values
        img = np.expand_dims(img, axis=0)  # Add batch dimension
    else:
        raise ValueError("Unsupported input type. Please provide a file path or a NumPy array.")

    return img

# Define the classification function
def classify_image(img):
    # Preprocess the image
    img = preprocess_image(img)

    # Make predictions
    predictions = model.predict(img)

    # Get the predicted class label
    predicted_class = np.argmax(predictions)

    # Get the predicted class name
    predicted_class_name = class_names[predicted_class]

    return f"Predicted Class: {predicted_class_name}"

# Create a Gradio interface
iface = gr.Interface(fn=classify_image,
                     inputs="image",
                     outputs="text",
                     live=True)

# Launch the Gradio app
iface.launch()