Tire Quality Predict AI - ML (Part 2)
- tcanengin
- Jan 20, 2025
- 18 min read
This section focuses on the process of training the ML model. Importing the necessary libraries for analyzing:
In [133]:
import matplotlib.pyplot as plt
import numpy as np
import PIL # pillow - the Python imaging library https://python-pillow.org/
import tensorflow as tf
import os
import cv2
from PIL import Image
from tensorflow import keras # keras is a neural network library that runs on TF
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
Image file directories are specified as below:
In [137]:
This code snippet defines a function called read_images_from_dir_with_class(directory) and uses it to read images from two directories.
# Define function to read images from directory
def read_images_from_dir_with_class(directory):
images = []
for file in os.listdir(directory):
if file.endswith(".jpg") or file.endswith(".png"):
image_path = os.path.join(directory, file)
image = Image.open(image_path)
images.append(image)
return images
# Define directories for good and defective images
good_dir = "C:/Users/engin/Desktop/Anaconda/Digital/good"
defective_dir = "C:/Users/engin/Desktop/Anaconda/Digital/defective"
# Read images from directories
images_good_class_dir1 = read_images_from_dir_with_class(good_dir)
images_defective_class_dir2 = read_images_from_dir_with_class(defective_dir)
# Process images and make predictions
# Add your code here to process images and make predictions
In [138]:
# Display an image from the "Good" class
plt.subplot(1, 2, 1)
plt.imshow(images_good_class_dir1[0]) # Displaying the first image from the "Good" class
plt.title("Good")
plt.axis('off')
# Display an image from the "Defective" class
plt.subplot(1, 2, 2)
plt.imshow(images_defective_class_dir2[0]) # Displaying the first image from the "Defective" class
plt.title("Defective")
plt.axis('off')
plt.show()

This code snippet displays two images side by side, one from the "Good" class and the other from the "Defective" class.
Overall, this code displays the first image from the "Good" class on the left and the first image from the "Defective" class on the right, side by side, with their respective titles.
# Get the count of "Good" images
count_good_images = len(images_good_class_dir1)
# Get the count of "Defective" images
count_defective_images = len(images_defective_class_dir2)
# Get the count of "Total" images
count_total_images = len(images_good_class_dir1) + len(images_defective_class_dir2)
print("Number of Good images:", count_good_images)
print("Number of Defective images:", count_defective_images)
print("Number of Total images:", count_total_images)
Number of Good images: 828
Number of Defective images: 1028
Number of Total images: 1856
In [92]:
batch_size = 32
img_height = 180
img_width = 180
In [155]:
# Assign class labels to images
class_names = ["good"] * len(images_good_class_dir1) + ["defective"] * len(images_defective_class_dir2)
# Combine the "Good" and "Defective" images into a single list
all_images = images_good_class_dir1 + images_defective_class_dir2
# Separate the images
X = [image_data for image_data in all_images] # Image data
# Split the dataset into training and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, class_names, test_size=0.2, random_state=42)
# Print class names
#print(class_names)
# Print the number of images in each set
print("Training set - Number of images:", len(X_train))
print("Validation set - Number of images:", len(X_val))
# Print theshape of the train and val sets
print("Number of samples in X_train:", len(X_train))
print("Number of samples in X_val:", len(X_val))
print("Number of samples in y_train:", len(y_train))
print("Number of samples in y_val:", len(y_val))
#print("Number of samples in y_val:", y_train)
Training set - Number of images: 1484
Validation set - Number of images: 372
Number of samples in X_train: 1484
Number of samples in X_val: 372
Number of samples in y_train: 1484
Number of samples in y_val: 372
Overall, this code snippet prepares the data for training and validation by assigning labels to images, combining them into a single list, and then splitting them into training and validation sets along with their respective labels. Simply for illustration and viewing purposes, here are the first nine images from the training dataset:
In [146]:
# Display the first nine images from the training dataset
plt.figure(figsize=(10, 10))
for i in range(9):
plt.subplot(3, 3, i + 1)
plt.imshow(X_train[i])
plt.title(y_train[i]) # Assuming y_train contains class labels
plt.axis('off')
plt.show()

from PIL import Image
# Create a dictionary to group image data by class name
image_data_by_class = {}
# Iterate over all_images and group image data by class name
for image_data in all_images:
image = image_data # Image data
class_name = "good" if image in images_good_class_dir1 else "defective" # Class label
# Check if the class name is already a key in the dictionary
if class_name in image_data_by_class:
# If it is, append the image data to the existing list
image_data_by_class[class_name].append(image)
else:
# If it's not, create a new list with the image data
image_data_by_class[class_name] = [image]
# Print the grouped image data
for class_name, image_data_list in image_data_by_class.items():
print("Class Name:", class_name)
print("Number of images:", len(image_data_list))
# Example image path
example_image_path = "C:/Users/engin/Desktop/Anaconda/Digital/defective/Defective (1).jpg"
example_image = Image.open(example_image_path)
image_shape = example_image.size
num_channels = len(example_image.getbands())
print("Image shape:", image_shape)
print("Number of channels:", num_channels)
Class Name: good
Number of images: 828
Class Name: defective
Number of images: 1028
Image shape: (748, 748)
Number of channels: 3
In [164]:
import numpy as np
from PIL import Image
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Input
from sklearn.model_selection import train_test_split
# Function to preprocess images
def preprocess_images(images, img_height=150, img_width=150):
processed_images = []
for img in images:
# Convert PIL Image to numpy array
img_array = np.array(img)
# Convert image to RGB (in case it's grayscale)
if len(img_array.shape) < 3 or img_array.shape[2] < 3:
img_array = np.stack((img_array,) * 3, axis=-1)
# Resize image to common dimensions
img_array = np.array(Image.fromarray((img_array * 255).astype(np.uint8)).resize((img_height, img_width)))
# Normalize pixel values
img_array = img_array / 255.0
processed_images.append(img_array)
return np.array(processed_images)
# Assuming X_train, X_val, y_train, y_val are already loaded as lists of PIL images
# Split the dataset into training and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
# Preprocess training and validation images
X_train = preprocess_images(X_train)
X_val = preprocess_images(X_val)
# Convert labels to numpy arrays
y_train = np.array(y_train)
y_val = np.array(y_val)
# Define common image dimensions
img_height, img_width = 150, 150
num_channels = 3 # Assuming RGB images
# Define the CNN model
model = Sequential()
model.add(Input(shape=(img_height, img_width, num_channels))) # First layer with Input shape
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile the model
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
Overall, this code prepares a CNN model for image classification, compiles it, and is ready for training with the prepared dataset.
In [165]:
model.summary()
Overall, the summary provides a concise overview of the model's architecture, including the types of layers, their output shapes, and the number of parameters.
print(y_train[1])
0
In [168]:
# Train the model
history = model.fit(X_train, y_train,
epochs=10,
batch_size=32,
validation_data=(X_val, y_val))
Epoch 1/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 13s 143ms/step - accuracy: 0.4868 - loss: 0.9785 - val_accuracy: 0.5538 - val_loss: 0.6914
Epoch 2/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 130ms/step - accuracy: 0.5544 - loss: 0.6916 - val_accuracy: 0.5538 - val_loss: 0.6913
Epoch 3/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 133ms/step - accuracy: 0.5535 - loss: 0.6912 - val_accuracy: 0.6559 - val_loss: 0.6784
Epoch 4/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 134ms/step - accuracy: 0.6039 - loss: 0.6854 - val_accuracy: 0.6263 - val_loss: 0.6916
Epoch 5/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 133ms/step - accuracy: 0.5756 - loss: 0.6864 - val_accuracy: 0.5591 - val_loss: 0.6903
Epoch 6/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 133ms/step - accuracy: 0.5611 - loss: 0.6918 - val_accuracy: 0.5538 - val_loss: 0.6845
Epoch 7/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 131ms/step - accuracy: 0.5499 - loss: 0.6874 - val_accuracy: 0.5538 - val_loss: 0.6875
Epoch 8/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 134ms/step - accuracy: 0.5662 - loss: 0.6845 - val_accuracy: 0.6129 - val_loss: 0.6889
Epoch 9/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 133ms/step - accuracy: 0.6542 - loss: 0.6290 - val_accuracy: 0.5995 - val_loss: 0.6658
Epoch 10/10
47/47 ━━━━━━━━━━━━━━━━━━━━ 6s 132ms/step - accuracy: 0.6607 - loss: 0.6164 - val_accuracy: 0.5806 - val_loss: 0.7663
In [169]:
import matplotlib.pyplot as plt
# Evaluate the model
loss, accuracy = model.evaluate(X_val, y_val)
print(f'Validation Loss: {loss}, Validation Accuracy: {accuracy}')
# Get training history
training_loss = history.history['loss']
validation_loss = history.history['val_loss']
training_accuracy = history.history['accuracy']
validation_accuracy = history.history['val_accuracy']
epochs = range(1, len(training_loss) + 1)
# Plot training and validation loss
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_loss, 'b', label='Training Loss')
plt.plot(epochs, validation_loss, 'r', label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()
# Plot training and validation accuracy
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_accuracy, 'b', label='Training Accuracy')
plt.plot(epochs, validation_accuracy, 'r', label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
plt.show()
12/12 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step - accuracy: 0.5871 - loss: 0.7399
Validation Loss: 0.7662876844406128, Validation Accuracy: 0.5806451439857483

These metrics provide insights into the performance of the model on the validation dataset after completing the training epoch. They help evaluate how well the model generalizes to unseen data and guide further adjustments to improve performance if needed.
import numpy as np from PIL import Image from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization from tensorflow.keras.preprocessing.image import ImageDataGenerator from sklearn.model_selection import train_test_split # Assuming X_train, X_val, y_train, y_val are already loaded as lists of PIL images # Function to preprocess images def preprocess_images(images, img_height=150, img_width=150): processed_images = [] for img in images: img_array = np.array(img) if len(img_array.shape) < 3 or img_array.shape[2] < 3: img_array = np.stack((img_array,) 3, axis=-1) img_array = np.array(Image.fromarray((img_array 255).astype(np.uint8)).resize((img_height, img_width))) img_array = img_array / 255.0 processed_images.append(img_array) return np.array(processed_images) # Preprocess images X_train = preprocess_images(X_train) X_val = preprocess_images(X_val) # Convert labels to numpy arrays y_train = np.array(y_train) y_val = np.array(y_val) # Data augmentation train_datagen = ImageDataGenerator( rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest') train_generator = train_datagen.flow( X_train, y_train, batch_size=32) # Define the CNN model model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(512, activation='relu')) model.add(Dropout(0.5)) # Dropout for regularization model.add(Dense(1, activation='sigmoid')) # Compile the model model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) # Train the model history = model.fit(train_generator, steps_per_epoch=len(X_train) // 32, epochs=10, validation_data=(X_val, y_val)) # Evaluate on validation data loss, accuracy = model.evaluate(X_val, y_val) print("Validation Loss:", loss) print("Validation Accuracy:", accuracy)
This code snippet trains a convolutional neural network (CNN) model with data augmentation using Keras's ImageDataGenerator.
Epoch 1/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 16s 251ms/step - accuracy: 0.4969 - loss: 0.7202 - val_accuracy: 0.5538 - val_loss: 0.6899
Epoch 2/10
1/46 ━━━━━━━━━━━━━━━━━━━━ 6s 139ms/step - accuracy: 0.6250 - loss: 0.686246/46 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - accuracy: 0.6250 - loss: 0.6862 - val_accuracy: 0.5538 - val_loss: 0.6897
Epoch 3/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 12s 246ms/step - accuracy: 0.5606 - loss: 0.6880 - val_accuracy: 0.5538 - val_loss: 0.6830
Epoch 4/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - accuracy: 0.5938 - loss: 0.6744 - val_accuracy: 0.5538 - val_loss: 0.6832
Epoch 5/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 12s 245ms/step - accuracy: 0.5477 - loss: 0.6865 - val_accuracy: 0.6102 - val_loss: 0.6587
Epoch 6/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.5000 - loss: 0.6839 - val_accuracy: 0.6129 - val_loss: 0.6563
Epoch 7/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 12s 244ms/step - accuracy: 0.6049 - loss: 0.6681 - val_accuracy: 0.5565 - val_loss: 0.6702
Epoch 8/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - accuracy: 0.5938 - loss: 0.6305 - val_accuracy: 0.5699 - val_loss: 0.6631
Epoch 9/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 12s 242ms/step - accuracy: 0.6207 - loss: 0.6583 - val_accuracy: 0.6129 - val_loss: 0.6642
Epoch 10/10
46/46 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - accuracy: 0.5625 - loss: 0.6375 - val_accuracy: 0.6505 - val_loss: 0.6491
12/12 ━━━━━━━━━━━━━━━━━━━━ 1s 46ms/step - accuracy: 0.6304 - loss: 0.6582
Validation Loss: 0.6491140127182007
Validation Accuracy: 0.6505376100540161
This approach allows the model to learn from a larger variety of training samples through data augmentation, which can improve its generalization ability. The validation loss and accuracy are then printed to assess the model's performance on unseen data.
import matplotlib.pyplot as plt
# Evaluate the model
loss, accuracy = model.evaluate(X_val, y_val)
print(f'Validation Loss: {loss}, Validation Accuracy: {accuracy}')
# Get training history
training_loss = history.history['loss']
validation_loss = history.history['val_loss']
training_accuracy = history.history['accuracy']
validation_accuracy = history.history['val_accuracy']
epochs = range(1, len(training_loss) + 1)
# Plot training and validation loss
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_loss, 'b', label='Training Loss')
plt.plot(epochs, validation_loss, 'r', label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()
# Plot training and validation accuracy
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_accuracy, 'b', label='Training Accuracy')
plt.plot(epochs, validation_accuracy, 'r', label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
plt.show()
12/12 ━━━━━━━━━━━━━━━━━━━━ 1s 53ms/step - accuracy: 0.6304 - loss: 0.6582
Validation Loss: 0.6491140127182007, Validation Accuracy: 0.6505376100540161

import numpy as np from PIL import Image from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import ReduceLROnPlateau from tensorflow.keras.applications import VGG16 from tensorflow.keras.preprocessing.image import ImageDataGenerator from sklearn.model_selection import train_test_split # Assuming X_train, X_val, y_train, y_val are already loaded as lists of PIL images # Function to preprocess images def preprocess_images(images, img_height=150, img_width=150): processed_images = [] for img in images: img_array = np.array(img) if len(img_array.shape) < 3 or img_array.shape[2] < 3: img_array = np.stack((img_array,) 3, axis=-1) img_array = np.array(Image.fromarray((img_array 255).astype(np.uint8)).resize((img_height, img_width))) img_array = img_array / 255.0 processed_images.append(img_array) return np.array(processed_images) # Preprocess images X_train = preprocess_images(X_train) X_val = preprocess_images(X_val) # Convert labels to numpy arrays y_train = np.array(y_train) y_val = np.array(y_val) # Data augmentation train_datagen = ImageDataGenerator( rotation_range=30, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest') train_generator = train_datagen.flow( X_train, y_train, batch_size=32) # Load pre-trained VGG16 model base_model = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3)) # Freeze pre-trained layers for layer in base_model.layers: layer.trainable = False # Add custom classification layers on top x = Flatten()(base_model.output) x = Dense(512, activation='relu')(x) x = Dropout(0.5)(x) output = Dense(1, activation='sigmoid')(x) # Create the model model = Model(inputs=base_model.input, outputs=output) # Compile the model # Compile the model optimizer = Adam(learning_rate=0.001) # Set initial learning rate model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy']) # Define learning rate reduction callback reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1) # Train the model history = model.fit(train_generator, steps_per_epoch=len(X_train) // 32, epochs=15, validation_data=(X_val, y_val), callbacks=[reduce_lr]) # Evaluate on validation data loss, accuracy = model.evaluate(X_val, y_val) print("Validation Loss:", loss) print("Validation Accuracy:", accuracy)
This script trains a CNN model using transfer learning with the VGG16 architecture pre-trained on the ImageNet dataset.
Epoch 1/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 49s 1s/step - accuracy: 0.6044 - loss: 1.3621 - val_accuracy: 0.8629 - val_loss: 0.3433 - learning_rate: 0.0010
Epoch 2/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 10s 195ms/step - accuracy: 0.7500 - loss: 0.5908 - val_accuracy: 0.8602 - val_loss: 0.3426 - learning_rate: 0.0010
Epoch 3/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 973ms/step - accuracy: 0.8146 - loss: 0.4122 - val_accuracy: 0.8333 - val_loss: 0.3556 - learning_rate: 0.0010
Epoch 4/15
1/46 ━━━━━━━━━━━━━━━━━━━━ 33s 753ms/step - accuracy: 0.8438 - loss: 0.4566
Epoch 4: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.
46/46 ━━━━━━━━━━━━━━━━━━━━ 9s 192ms/step - accuracy: 0.8438 - loss: 0.4566 - val_accuracy: 0.8360 - val_loss: 0.3592 - learning_rate: 0.0010
Epoch 5/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 974ms/step - accuracy: 0.8112 - loss: 0.4015 - val_accuracy: 0.8844 - val_loss: 0.2882 - learning_rate: 5.0000e-04
Epoch 6/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 9s 192ms/step - accuracy: 0.8438 - loss: 0.3122 - val_accuracy: 0.8925 - val_loss: 0.2829 - learning_rate: 5.0000e-04
Epoch 7/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 47s 989ms/step - accuracy: 0.8085 - loss: 0.4056 - val_accuracy: 0.8898 - val_loss: 0.2672 - learning_rate: 5.0000e-04
Epoch 8/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 9s 192ms/step - accuracy: 0.8125 - loss: 0.4863 - val_accuracy: 0.8898 - val_loss: 0.2702 - learning_rate: 5.0000e-04
Epoch 9/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 0s 781ms/step - accuracy: 0.8280 - loss: 0.3653
Epoch 9: ReduceLROnPlateau reducing learning rate to 0.0002500000118743628.
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 974ms/step - accuracy: 0.8280 - loss: 0.3651 - val_accuracy: 0.8925 - val_loss: 0.2688 - learning_rate: 5.0000e-04
Epoch 10/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 9s 194ms/step - accuracy: 0.8750 - loss: 0.3610 - val_accuracy: 0.8871 - val_loss: 0.2707 - learning_rate: 2.5000e-04
Epoch 11/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 982ms/step - accuracy: 0.8352 - loss: 0.3348 - val_accuracy: 0.8978 - val_loss: 0.2495 - learning_rate: 2.5000e-04
Epoch 12/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 10s 195ms/step - accuracy: 0.9062 - loss: 0.2800 - val_accuracy: 0.8978 - val_loss: 0.2497 - learning_rate: 2.5000e-04
Epoch 13/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 974ms/step - accuracy: 0.8449 - loss: 0.3386 - val_accuracy: 0.8978 - val_loss: 0.2399 - learning_rate: 2.5000e-04
Epoch 14/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 10s 195ms/step - accuracy: 0.9062 - loss: 0.2600 - val_accuracy: 0.9005 - val_loss: 0.2400 - learning_rate: 2.5000e-04
Epoch 15/15
46/46 ━━━━━━━━━━━━━━━━━━━━ 0s 782ms/step - accuracy: 0.8536 - loss: 0.3166
Epoch 15: ReduceLROnPlateau reducing learning rate to 0.0001250000059371814.
46/46 ━━━━━━━━━━━━━━━━━━━━ 46s 978ms/step - accuracy: 0.8536 - loss: 0.3166 - val_accuracy: 0.9059 - val_loss: 0.2408 - learning_rate: 2.5000e-04
12/12 ━━━━━━━━━━━━━━━━━━━━ 9s 714ms/step - accuracy: 0.9083 - loss: 0.2531
Validation Loss: 0.24076128005981445
Validation Accuracy: 0.9059139490127563
This approach leverages the pre-trained VGG16 model's learned features and fine-tunes them on the specific dataset with custom classification layers, enabling the model to achieve better performance with less training data.
In [207]:
import matplotlib.pyplot as plt
# Evaluate the model
loss, accuracy = model.evaluate(X_val, y_val)
print(f'Validation Loss: {loss}, Validation Accuracy: {accuracy}')
# Get training history
training_loss = history.history['loss']
validation_loss = history.history['val_loss']
training_accuracy = history.history['accuracy']
validation_accuracy = history.history['val_accuracy']
epochs = range(1, len(training_loss) + 1)
# Plot training and validation loss
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_loss, 'b', label='Training Loss')
plt.plot(epochs, validation_loss, 'r', label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()
# Plot training and validation accuracy
plt.figure(figsize=(10, 5))
plt.plot(epochs, training_accuracy, 'b', label='Training Accuracy')
plt.plot(epochs, validation_accuracy, 'r', label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
plt.show()
12/12 ━━━━━━━━━━━━━━━━━━━━ 9s 718ms/step - accuracy: 0.9083 - loss: 0.2531
Validation Loss: 0.24076128005981445, Validation Accuracy: 0.9059139490127563

In [221]:
from PIL import Image
import numpy as np
# Load the image
image_path = "C:/Users/engin/Desktop/Anaconda/Digital/good/Good (1).jpg" # Replace with the path to your image
image = Image.open(image_path)
# Preprocess the image
# Resize the image to match the input shape expected by the model
img_height, img_width = 150, 150 # Assuming the same input shape as your model
image = image.resize((img_height, img_width))
# Convert the image to a numpy array
image_array = np.array(image)
# Normalize pixel values
image_array = image_array / 255.0
# Reshape the array to match the input shape expected by the model
image_array = np.expand_dims(image_array, axis=0) # Add batch dimension
# Make predictions
prediction = model.predict(image_array)
# Since it's a binary classification, you might want to threshold the prediction
threshold = 0.5
binary_prediction = "Good" if prediction > threshold else "Defective"
print("Predicted class:", binary_prediction)
print(prediction)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 58ms/step
Predicted class: Good
[[0.7656142]]
This script loads an image, preprocesses it to match the input shape expected by the model, and then makes predictions using the trained model. You can see the result above for that image is 0.76 which its predicted class "Good".


