<jupyter_start><jupyter_text>**Data and Libraries**<jupyter_code># Importing necessary libraries

import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import keras
import cv2

from keras import layers
from keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D
from keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D
from keras.models import Model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model

import keras.backend as K
K.set_image_data_format('channels_last')
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
print(tf.__version__)
# Mounting google drive

from google.colab import drive          
drive.mount('/content/drive')
# Testing if GPU exists

tf.test.gpu_device_name()
# Checking specifications of CPU & GPU

from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
# Using Image data generator from keras to handle the training as well as testing data

from keras.preprocessing.image import ImageDataGenerator

train_generator = ImageDataGenerator()
test_generator = ImageDataGenerator()

path = '/content/drive/MyDrive/Datasets/mechanical_parts_dataset'
train_iterator = train_generator.flow_from_directory(path+'/training',target_size=(128,128),class_mode = 'sparse',batch_size=64)
test_iterator = test_generator.flow_from_directory(path+'/testing',target_size=(128,128),class_mode = 'sparse',batch_size=1)<jupyter_output>Found 21130 images belonging to 4 classes.
Found 1524 images belonging to 4 classes.<jupyter_text>**Model-fromScratch**<jupyter_code># Building CNN model from scratch 

def MechanicalModel():

  X_input = Input((128,128,3))
  X = ZeroPadding2D((3,3))(X_input)
  X = Conv2D(32, (7, 7), strides = (1, 1), name = 'conv0')(X)
  X = BatchNormalization(axis = 3, name = 'bn0')(X)
  X = Activation('relu')(X)
  X = MaxPooling2D((2, 2), strides = (2, 2), name = 'Max_Pool0')(X)
  
  X = ZeroPadding2D((3,3))(X)
  X = Conv2D(64, (7, 7), strides = (1, 1), name = 'conv1')(X)
  X = BatchNormalization(axis = 3, name = 'bn1')(X)
  X = Activation('relu')(X)
  X = MaxPooling2D((2, 2), strides = (2, 2), name = 'Max_Pool1')(X)
  
  X = ZeroPadding2D((3,3))(X)
  X = Conv2D(64, (7, 7), strides = (1, 1), name = 'conv2')(X)
  X = BatchNormalization(axis = 3, name = 'bn2')(X)
  X = Activation('relu')(X)
  X = MaxPooling2D((2, 2), strides = (2, 2), name = 'Max_Pool2')(X)

  X = ZeroPadding2D((3,3))(X)
  X = Conv2D(128, (7, 7), strides = (1, 1), name = 'conv3')(X)
  X = BatchNormalization(axis = 3, name = 'bn3')(X)
  X = Activation('relu')(X)
  X = MaxPooling2D((2, 2), strides = (2, 2), name = 'Max_Pool3')(X)
  
  X = Flatten()(X)
  X = Dense(4, activation = 'softmax', name = 'fc')(X)
  print(X)
  model = tf.keras.Model(inputs = X_input, outputs = X, name = 'MechanicalModel')

  return model
# Compiling the model and storing it in mechanicalmodel

mechanicalmodel = MechanicalModel()

mechanicalmodel.compile(optimizer = 'adam', loss = tf.keras.losses.sparse_categorical_crossentropy, metrics = ["accuracy"])
# Training the model

model_history = mechanicalmodel.fit_generator(
    train_iterator, 
    epochs=20,
    validation_data=test_iterator
)
# Plotting the graphs of validation loss and validation accuracy vs epochs

accuracy = model_history.history['val_accuracy']
loss = model_history.history['val_loss']
x = np.arange(len(loss))

plt.plot(x,loss)
plt.title('Loss vs epochs')
plt.show()

plt.plot(x, accuracy)
plt.title('Accuracy v/s epochs')
plt.show()
# Defining a function that tests on a custom image using image path

# First we identify the actual class labels and what their corresponding index in the model
labels = train_iterator.class_indices
labels = dict((v,k) for k,v in labels.items())

def mechanical_parts_predictor(path):
  x_test_image =  cv2.imread(path)
  resized_test = cv2.resize(x_test_image,(128,128))

  list_of_test_images = []
  list_of_test_images.append(resized_test)
  test_image = np.array(list_of_test_images)

  prediction = mechanicalmodel.predict_generator(test_image)
  print(prediction)
  predicted_class_index = np.argmax(prediction)
  # predictions = 
  return labels[predicted_class_index]
# We test using a sample image

test_image_path = '/content/pin2.png'
part = mechanical_parts_predictor(test_image_path)
print("The given image is of " + part)<jupyter_output>[[6.7462701e-01 2.2120979e-01 1.0416172e-01 1.3801437e-06]]
The given image is of bolt<jupyter_text>**VGG** 

For purposes of comparison with standard models, we use pretrained VGG16<jupyter_code>from keras.models import Sequential
from keras.layers import Conv2D,Dense,MaxPooling2D,Flatten,BatchNormalization,AveragePooling2D
from keras.applications.vgg16 import VGG16


vgg_model = VGG16(input_shape=(128,128,3),include_top=False,weights='imagenet')
model = Sequential()

model.add(vgg_model)

model.add(Flatten())
model.add(Dense(4,activation='softmax'))

model.compile(loss='sparse_categorical_crossentropy', optimizer=keras.optimizers.Adam(lr=1e-3), metrics=['accuracy'])
for layer in vgg_model.layers:
    layer.trainable = False
model_history = model.fit_generator(
    train_iterator, 
    epochs=20,
    validation_data=test_iterator,
    steps_per_epoch = 64
)
# Plotting the graphs of validation loss and validation accuracy vs epochs

accuracy = model_history.history['val_accuracy']
loss = model_history.history['val_loss']
x = np.arange(len(loss))

plt.plot(x,loss)
plt.title('Loss vs epochs')
plt.show()

plt.plot(x, accuracy)
plt.title('Accuracy v/s epochs')
plt.show()
# Saving the model weights for future use

# model.save_weights('/content/drive/MyDrive/Datasets')
# model.save('model.h5')
# Copying the model that was saved in the temporary content to the drive destination

# %cp /content/model.h5 /content/drive/MyDrive/Datasets
# Loading the saved model weights 

model.load_weights('/content/drive/MyDrive/Datasets/model.h5')
# Saving the model weights in tf format 

model.save_weights('./model_weight_tf.tf',save_format='tf')
# Loading the tf format weights

# model.load_weights('/content/model_weight_tf.tf.index')
# Defining a function that tests on a custom image using image path

# First we identify the actual class labels and what their corresponding index in the model
# labels = train_iterator.class_indices
labels = {'bolt': 0, 'locatingpin': 1, 'nut': 2, 'washer': 3}
print("The corresponding classes and indices are ")
print(labels)
labels = dict((v,k) for k,v in labels.items())

def mechanical_parts_predictor(path):
  x_test_image =  cv2.imread(path)
  resized_test = cv2.resize(x_test_image,(128,128))
  list_of_test_images = []
  list_of_test_images.append(resized_test)
  test_image = np.array(list_of_test_images)
  prediction = model.predict_generator(test_image)
  print("The prediction probabilities are ")
  print(prediction)
  predicted_class_index = np.argmax(prediction)
  return labels[predicted_class_index]
# We test using a sample image

test_image_path = '/content/bolt.png'
display_image = cv2.imread(test_image_path)
plt.imshow(display_image)
part = mechanical_parts_predictor(test_image_path)
print("The given image is of " + part)<jupyter_output>The prediction probabilities are 
[[0.8018068  0.19124196 0.00394446 0.00300681]]
The given image is of bolt
{'fraction_non_alphanumeric': 0.11310592459605028, 'fraction_numerical': 0.03141831238779174, 'mean_word_length': 4.93983244478294, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '223693', 'license': 'MIT', 'n_tokens_mistral': 2886, 'n_tokens_neox': 2659, 'n_words': 647, 'path': 'DeepLearning_Model.ipynb', 'repo_name': 'm607stars/Mechanical_Parts_classifier', 'size': '7798'}