Butterfly-Classification-using-CNN / butterfly_classification_with_cnn.py
KameliaZaman's picture
Upload butterfly_classification_with_cnn.py
dfd5176 verified
# -*- 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()