-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f612ad8
commit 414373a
Showing
13 changed files
with
3,879 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# AIM: To create a python file that maintains helper functions. | ||
|
||
|
||
from sklearn.model_selection import train_test_split | ||
from matplotlib import pyplot as plt | ||
import numpy as np | ||
import os | ||
import shutil | ||
|
||
|
||
def move_images(imagePaths): | ||
''' | ||
Function to move images into seperate train and validation directories. | ||
Parameters: | ||
imagePaths (list): List containing paths to all the images. | ||
Returns: | ||
None. | ||
''' | ||
labels = [] # list to collect labels | ||
for imagePath in imagePaths: | ||
label = imagePath.split(os.path.sep)[-2] | ||
labels.append(label) | ||
# create training directory with class folders | ||
if not os.path.exists('train_dir/' + label + '/'): | ||
os.makedirs('train_dir/' + label + '/') | ||
# create validation directory with class folders | ||
if not os.path.exists('valid_dir/' + label + '/'): | ||
os.makedirs('valid_dir/' + label + '/') | ||
|
||
# do stratified sampling | ||
(trainX, validX, _, _) = train_test_split(imagePaths, labels, | ||
test_size=0.3, random_state=42, stratify=labels) | ||
|
||
# move images into separate train directory | ||
for trainx in trainX: | ||
to_path = os.path.join("train_dir/", os.sep.join(trainx.rsplit(r"/")[-2:])) | ||
from_path = os.path.join("raw-img/", os.sep.join(trainx.rsplit(r"/")[-2:])) | ||
shutil.move(from_path, to_path) | ||
|
||
# move images into separate validation directory | ||
for validx in validX: | ||
to_path = os.path.join("valid_dir/", os.sep.join(validx.rsplit(r"/")[-2:])) | ||
from_path = os.path.join("raw-img/", os.sep.join(validx.rsplit(r"/")[-2:])) | ||
shutil.move(from_path, to_path) | ||
|
||
return 0 | ||
|
||
|
||
def plot_graphs(history): | ||
''' | ||
Function to plot accuracy and loss graph. | ||
Parameters: | ||
history (object): Trained model. | ||
Returns: | ||
fig (object): Accuracy and loss plots. | ||
''' | ||
accuracy = history.history['accuracy'] | ||
val_accuracy = history.history['val_accuracy'] | ||
loss = history.history['loss'] | ||
val_loss = history.history['val_loss'] | ||
|
||
N = np.arange(0, len(history.history['loss'])) | ||
|
||
fig = plt.figure(figsize=(8, 8)) | ||
|
||
plt.subplot(2, 1, 1) | ||
plt.plot(N, accuracy, label='Training Accuracy') | ||
plt.plot(N, val_accuracy, label='Validation Accuracy') | ||
plt.legend(loc='lower right') | ||
plt.title('Training and Validation Accuracy') | ||
|
||
plt.subplot(2, 1, 2) | ||
plt.plot(N, loss, label='Training Loss') | ||
plt.plot(N, val_loss, label='Validation Loss') | ||
plt.legend(loc='upper right') | ||
plt.title('Training and Validation Cross Entropy Loss') | ||
|
||
return fig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# AIM: To create LeNet class. | ||
|
||
|
||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Activation, Conv2D, Dense | ||
from tensorflow.keras.layers import Flatten, MaxPooling2D, Rescaling | ||
from tensorflow.keras import backend as K | ||
|
||
class LeNet: | ||
''' | ||
Class to construct LeNet model. | ||
LeNet Architecture: | ||
INPUT => CONV => RELU => POOL => CONV => RELU => POOL => | ||
FC => RELU => FC => SOFTMAX | ||
''' | ||
@staticmethod | ||
def build(width, height, depth, classes): | ||
''' | ||
Static method to build the LeNet model architecture. | ||
Parameters: | ||
width (int): Width of the input image. | ||
height (int): Height of the input image. | ||
depth (int): Depth of the input image. | ||
classes (int): Number of output classes to learn to predict. | ||
Returns: | ||
model: Constructed lenet network architecture. | ||
''' | ||
model = Sequential() | ||
inputShape = (height, width, depth) # initialize the model along with the input shape to be "channels last" | ||
if K.image_data_format() == "channels_first": # if we are using "channels first", update the input shape | ||
inputShape = (depth, height, width) | ||
|
||
# normalizing the images | ||
model.add(Rescaling(1./255, input_shape=inputShape)) | ||
|
||
# define the model layers | ||
model.add(Conv2D(20, (5, 5), padding="same", input_shape=inputShape)) | ||
model.add(Activation("relu")) | ||
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) | ||
model.add(Conv2D(50, (5, 5), padding="same")) | ||
model.add(Activation("relu")) | ||
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) | ||
model.add(Flatten()) | ||
model.add(Dense(500)) | ||
model.add(Activation("relu")) | ||
model.add(Dense(classes)) | ||
model.add(Activation("softmax")) | ||
|
||
# model name | ||
model._name = 'LeNet' | ||
|
||
return model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# AIM: To create MiniVGGNet class. | ||
|
||
|
||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Activation, BatchNormalization, Conv2D, Dense | ||
from tensorflow.keras.layers import Dropout, Flatten, MaxPooling2D, Rescaling | ||
from tensorflow.keras import backend as K | ||
|
||
|
||
class MiniVGGNet: | ||
''' | ||
Class to construct MiniVGGNet model. | ||
MiniVGGNet Architecture: | ||
INPUT => (CONV => RELU => CONV => RELU => POOL)*2 => | ||
FC => RELU => FC => SOFTMAX | ||
''' | ||
@staticmethod | ||
def build(width, height, depth, classes): | ||
''' | ||
Static method to build the MiniVGGNet model architecture. | ||
Parameters: | ||
width (int): Width of the input image. | ||
height (int): Height of the input image. | ||
depth (int): Depth of the input image. | ||
classes (int): Number of output classes to learn to predict. | ||
Returns: | ||
model: Constructed minivggnet network architecture. | ||
''' | ||
model = Sequential() # initialize the model along with the input shape to be "channels last" and the channels dimension itself | ||
inputShape = (height, width, depth) | ||
chanDim = -1 | ||
|
||
# if we are using "channels first", update the input shape and channels dimension | ||
if K.image_data_format() == "channels_first": | ||
inputShape = (depth, height, width) | ||
chanDim = 1 | ||
|
||
# normalizing the images | ||
model.add(Rescaling(1./255, input_shape=inputShape)) | ||
|
||
# first CONV => RELU => CONV => RELU => POOL layer set | ||
model.add(Conv2D(32, (3, 3), padding="same", input_shape=inputShape)) | ||
model.add(Activation("relu")) | ||
model.add(BatchNormalization(axis=chanDim)) | ||
model.add(Conv2D(32, (3, 3), padding="same")) | ||
model.add(Activation("relu")) | ||
model.add(BatchNormalization(axis=chanDim)) | ||
model.add(MaxPooling2D(pool_size=(2, 2))) | ||
model.add(Dropout(0.25)) | ||
|
||
# second CONV => RELU => CONV => RELU => POOL layer set | ||
model.add(Conv2D(64, (3, 3), padding="same")) | ||
model.add(Activation("relu")) | ||
model.add(BatchNormalization(axis=chanDim)) | ||
model.add(Conv2D(64, (3, 3), padding="same")) | ||
model.add(Activation("relu")) | ||
model.add(BatchNormalization(axis=chanDim)) | ||
model.add(MaxPooling2D(pool_size=(2, 2))) | ||
model.add(Dropout(0.25)) | ||
|
||
# remaining, FC => RELU => FC => SOFTMAX | ||
model.add(Flatten()) | ||
model.add(Dense(512)) | ||
model.add(Activation("relu")) | ||
model.add(BatchNormalization()) | ||
model.add(Dropout(0.5)) | ||
model.add(Dense(classes)) | ||
model.add(Activation("softmax")) | ||
|
||
# model name | ||
model._name = 'MiniVGGNet' | ||
|
||
return model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# AIM: To create MobileNetV3Large(transfer learning) class. | ||
# NOTE: For MobileNetV3Large, input preprocessing is part of the model by default. As we use | ||
# the preprocessing layer separately, it just acts as pass through function and has no | ||
# effect whatsoever. | ||
|
||
|
||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D | ||
from tensorflow.keras.applications import MobileNetV3Large | ||
from tensorflow.keras.applications.mobilenet_v3 import preprocess_input | ||
from tensorflow.keras import layers, Model, Input | ||
from tensorflow.keras import backend as K | ||
|
||
|
||
class MobileNetV3L: | ||
''' | ||
Class to construct MobileNetV3Large model. | ||
''' | ||
@staticmethod | ||
def build(width, height, depth, classes, data_aug, dense_layer): | ||
''' | ||
Static method to build the MobileNetV3Large model architecture. | ||
Parameters: | ||
width (int): Width of the input image. | ||
height (int): Height of the input image. | ||
depth (int): Depth of the input image. | ||
classes (int): Number of output classes to learn to predict. | ||
data_aug (boolean): If value set to True, then add data augmentation layer; else do not add. | ||
dense_layer (boolean): If value set to True, then add dense layer; else do not add. | ||
Returns: | ||
model: Constructed mobilenetv3large network architecture. | ||
''' | ||
# initialize the model along with the input shape to be "channels last" and the channels dimension itself | ||
inputShape = (height, width, depth) | ||
seed = 42 # set seed | ||
|
||
# if we are using "channels first", update the input shape and channels dimension | ||
if K.image_data_format() == "channels_first": | ||
inputShape = (depth, height, width) | ||
|
||
# add data augmentation layer if boolean value of dataAugmentation variable is set to 1 | ||
data_augmentation = Sequential([ | ||
layers.RandomFlip("horizontal", input_shape=inputShape, seed=seed), | ||
layers.RandomZoom(height_factor=-0.4, seed=seed), | ||
layers.RandomTranslation(0.3, 0.2, seed=seed) | ||
]) | ||
|
||
# defining mobilenetv3large network | ||
base_model = MobileNetV3Large(include_top=False, | ||
input_shape=inputShape, | ||
weights='imagenet') | ||
base_model.trainable=False | ||
|
||
# input layer | ||
inputs = Input(shape=inputShape) | ||
# data augmentation layer to be added if data_aug is set to True | ||
if data_aug==True: | ||
x = data_augmentation(inputs) # data augmentation layer | ||
x = preprocess_input(x) # preprocessing layer | ||
else: | ||
x = preprocess_input(inputs) # preprocessing layer | ||
# base model | ||
x = base_model(x, training=False) | ||
x = GlobalAveragePooling2D()(x) | ||
# dense layer to be added if dense_layer is set to True | ||
if dense_layer==True: | ||
x = Dense(128, activation="relu")(x) | ||
x = Dropout(0.2)(x) | ||
# output layer | ||
outputs = Dense(classes, activation="softmax")(x) | ||
model = Model(inputs, outputs) | ||
|
||
# model name | ||
model._name = 'MobileNetV3Large' | ||
|
||
return model | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# AIM: To create MobileNetV3Small(transfer learning) class. | ||
# NOTE: For MobileNetV3Small, input preprocessing is part of the model by default. As we use | ||
# the preprocessing layer separately, it just acts as pass through function and has no | ||
# effect whatsoever. | ||
|
||
|
||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D | ||
from tensorflow.keras.applications import MobileNetV3Small | ||
from tensorflow.keras.applications.mobilenet_v3 import preprocess_input | ||
from tensorflow.keras import layers, Model, Input | ||
from tensorflow.keras import backend as K | ||
|
||
|
||
class MobileNetV3S: | ||
''' | ||
Class to construct MobileNetV3Small model. | ||
''' | ||
@staticmethod | ||
def build(width, height, depth, classes, data_aug, dense_layer): | ||
''' | ||
Static method to build the MobileNetV3Small model architecture. | ||
Parameters: | ||
width (int): Width of the input image. | ||
height (int): Height of the input image. | ||
depth (int): Depth of the input image. | ||
classes (int): Number of output classes to learn to predict. | ||
data_aug (boolean): If value set to True, then add data augmentation layer; else do not add. | ||
dense_layer (boolean): If value set to True, then add dense layer; else do not add. | ||
Returns: | ||
model: Constructed mobilenetv3small network architecture. | ||
''' | ||
# initialize the model along with the input shape to be "channels last" and the channels dimension itself | ||
inputShape = (height, width, depth) | ||
seed = 42 # set seed | ||
|
||
# if we are using "channels first", update the input shape and channels dimension | ||
if K.image_data_format() == "channels_first": | ||
inputShape = (depth, height, width) | ||
|
||
# add data augmentation layer if boolean value of dataAugmentation variable is set to 1 | ||
data_augmentation = Sequential([ | ||
layers.RandomZoom(height_factor=-0.4, seed=seed), | ||
layers.RandomTranslation(0.3, 0.2, seed=seed) | ||
]) | ||
|
||
# defining mobilenetv3small network | ||
base_model = MobileNetV3Small(include_top=False, | ||
input_shape=inputShape, | ||
weights='imagenet') | ||
base_model.trainable=False | ||
|
||
# input layer | ||
inputs = Input(shape=inputShape) | ||
# data augmentation layer to be added if data_aug is set to True | ||
if data_aug==True: | ||
x = data_augmentation(inputs) # data augmentation layer | ||
x = preprocess_input(x) # preprocessing layer | ||
else: | ||
x = preprocess_input(inputs) # preprocessing layer | ||
# base model | ||
x = base_model(x, training=False) | ||
x = GlobalAveragePooling2D()(x) | ||
# dense layer to be added if dense_layer is set to True | ||
if dense_layer==True: | ||
x = Dense(124, activation="relu")(x) | ||
x = Dropout(0.2)(x) | ||
# output layer | ||
outputs = Dense(classes, activation="softmax")(x) | ||
model = Model(inputs, outputs) | ||
|
||
# model name | ||
model._name = 'MobileNetV3Small' | ||
|
||
return model | ||
|
||
|
Oops, something went wrong.