FISH BREED CLASSIFICATION¶
IMPORT LIBRARY AND DATA¶
In [3]:
!pip install wget
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import seaborn as sns
import cv2
from sklearn.model_selection import StratifiedShuffleSplit,train_test_split
import glob
import tensorflow as tf
from sklearn import metrics
from tensorflow import keras
!wget -N 'https://cainvas-static.s3.amazonaws.com/media/user_data/devanshchowd/fish.tar.gz'
import tarfile
file = tarfile.open('fish.tar.gz')
file.extractall('./')
file.close()
BASIC ANALYSIS¶
In [23]:
data = pd.read_csv('fish/data.csv')
display(data)
sns.set_style('darkgrid')
sns.countplot(data = data,y = 'label')
Out[23]:
In [109]:
def get_img(index):
img = plt.imread(data.iloc[index]['path'])
return img
demo = pd.DataFrame(data.groupby('label').first()).reset_index()
fig,ax = plt.subplots(3,3,figsize=(15,15))
for i in range(3):
for j in range(3):
ax[i][j].imshow(plt.imread(demo.iloc[i*3+j].path))
ax[i][j].tick_params(left = False, bottom = False)
ax[i][j].set_xticks([])
ax[i][j].set_yticks([])
ax[i][j].set_title(demo.iloc[i*3+j].label)
display(demo)
fig.savefig('Sample.png')
MODEL¶
In [100]:
def get_model(dim = (288,384,3)):
keras.backend.clear_session()
model = keras.models.Sequential()
model.add(keras.layers.Conv2D(32,(3,3),activation='relu',input_shape=dim))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Conv2D(32,(3,3),activation='relu',padding="valid"))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',padding="valid"))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Conv2D(64,(5,5),activation='relu',padding="valid"))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Conv2D(64,(5,5),activation='relu',padding="valid"))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dropout(.4))
model.add(keras.layers.Dense(9,activation='softmax'))
model.summary()
return model
train_val,test = train_test_split(data,stratify=data['label'],test_size=45,shuffle=True)
train,val = train_test_split(train_val,stratify=train_val['label'],test_size=.25,shuffle=True)
train.reset_index(drop=True,inplace=True)
val.reset_index(drop=True,inplace=True)
test.reset_index(drop=True,inplace=True)
print(len(train),len(val),len(test))
get_model()
Out[100]:
In [102]:
datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1/255.,
horizontal_flip = True,
vertical_flip=True,)
datagen_scale = keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
train_generator= datagen.flow_from_dataframe(train,x_col ='path',y_col='label',target_size=(288,384),batch_size=32,shuffle=True)
valid_generator= datagen.flow_from_dataframe(val,x_col ='path',y_col='label',target_size=(288,384),shuffle=False)
test_generator = datagen.flow_from_dataframe(test,x_col ='path',y_col='label',target_size=(288,384),shuffle=False)
In [103]:
model = get_model()
model.compile(loss='categorical_crossentropy',metrics='accuracy',optimizer=keras.optimizers.Adam(learning_rate=.0008))
early_stop = keras.callbacks.EarlyStopping(monitor= 'val_accuracy',patience=12,restore_best_weights=True)
red_lr = keras.callbacks.ReduceLROnPlateau(patience=4,monitor= 'val_accuracy',factor=0.75)
model_check = keras.callbacks.ModelCheckpoint(f"fishes.h5",save_best_only=True)
history = model.fit(train_generator,validation_data=valid_generator,epochs=200,callbacks = [early_stop,model_check,red_lr])
In [105]:
fig = plt.figure()
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()
fig.savefig('Accuracy vs Epoch.png')
In [106]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()
fig.savefig('Loss vs Epoch.png')
EVALUATE¶
In [108]:
datagen_scale = keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
train_generator= datagen_scale.flow_from_dataframe(train,x_col ='path',y_col='label',target_size=(288,384),batch_size=48,shuffle=True)
valid_generator= datagen_scale.flow_from_dataframe(val,x_col ='path',y_col='label',target_size=(288,384),shuffle=False)
test_generator = datagen_scale.flow_from_dataframe(test,x_col ='path',y_col='label',target_size=(288,384),shuffle=False)
model.evaluate(train_generator)
model.evaluate(valid_generator)
model.evaluate(test_generator)
Out[108]:
PREDICT¶
In [118]:
demo = pd.DataFrame(test.groupby('label').first()).reset_index()
datagen_scale = keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
test_generator = datagen_scale.flow_from_dataframe(demo,x_col ='path',y_col='label',target_size=(288,384),shuffle=False)
demo = pd.concat((demo,pd.Series(np.argmax(model.predict(test_generator),axis=1),name='Prediction').map({a:b for b,a in test_generator.class_indices.items()})),axis=1)
fig,ax = plt.subplots(3,3,figsize=(15,10))
plt.tick_params(left = False, bottom = False)
for i in range(3):
for j in range(3):
ax[i][j].imshow(plt.imread(demo.iloc[i*3+j].path))
ax[i][j].tick_params(left = False, bottom = False)
ax[i][j].set_xticks([])
ax[i][j].set_yticks([])
ax[i][j].set_title("Truth Label "+demo.iloc[i*3+j].label+" \n PREDICTED "+demo.iloc[i*3+j].Prediction)
fig.savefig('Predict.png')
In [119]:
model.save("Fish_breed_classification.h5")