In [7]:
import numpy as np
In [8]:
import tensorflow as tf
physical_devices = tf.config.list_physical_devices('GPU')
if len(physical_devices) > 0:
tf.config.experimental.set_memory_growth(physical_devices[0], True)
from tensorflow.keras import layers, Sequential
from tensorflow.keras.preprocessing.image import ImageDataGenerator
In [15]:
# Set batch size and image dimensions
batch_size = 32
img_height, img_width = 224, 224
data_gen = ImageDataGenerator(rescale = 1./255,
horizontal_flip=True,
vertical_flip=True,
brightness_range=(.2, 1),
rotation_range=30,
width_shift_range=0.2,
height_shift_range=0.2,
zoom_range=0.8)
flow_gen = data_gen.flow_from_directory(
'test_images',
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='sparse'
)
Found 28 images belonging to 15 classes.
In [16]:
# Make a training set from the directory
train_ds = tf.keras.utils.image_dataset_from_directory(
'test_images/',
validation_split=0.2,
subset='training',
seed=76,
image_size=(img_height, img_width),
batch_size=batch_size
)
# Get class names and the number of classes
class_names = train_ds.class_names
num_classes = len(class_names)
# Make a validation set from the directory
val_ds = tf.keras.utils.image_dataset_from_directory(
'test_images/',
validation_split=0.2,
subset='validation',
seed=76,
image_size=(img_height, img_width),
batch_size=batch_size
)
Found 28 files belonging to 15 classes. Using 23 files for training. Found 28 files belonging to 15 classes. Using 5 files for validation.
In [17]:
model = Sequential([
layers.Input(shape=(224, 224, 3)),
layers.Rescaling(1./255),
layers.Conv2D(32, 3, activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
In [18]:
hist = model.fit(
flow_gen,
validation_data=val_ds,
epochs=20
)
Epoch 1/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 2s 2s/step - accuracy: 0.0357 - loss: 2.7081 - val_accuracy: 0.2000 - val_loss: 15.4397 Epoch 2/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 380ms/step - accuracy: 0.0714 - loss: 2.7038 - val_accuracy: 0.2000 - val_loss: 23.9809 Epoch 3/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 385ms/step - accuracy: 0.0714 - loss: 2.6999 - val_accuracy: 0.2000 - val_loss: 23.3276 Epoch 4/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 380ms/step - accuracy: 0.0714 - loss: 2.6883 - val_accuracy: 0.2000 - val_loss: 24.6694 Epoch 5/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 391ms/step - accuracy: 0.0714 - loss: 2.6824 - val_accuracy: 0.2000 - val_loss: 26.4286 Epoch 6/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 388ms/step - accuracy: 0.1429 - loss: 2.6788 - val_accuracy: 0.2000 - val_loss: 27.9244 Epoch 7/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 376ms/step - accuracy: 0.1429 - loss: 2.6782 - val_accuracy: 0.2000 - val_loss: 27.6619 Epoch 8/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 377ms/step - accuracy: 0.1429 - loss: 2.6702 - val_accuracy: 0.2000 - val_loss: 29.8185 Epoch 9/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 387ms/step - accuracy: 0.0714 - loss: 2.6624 - val_accuracy: 0.2000 - val_loss: 33.1833 Epoch 10/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 382ms/step - accuracy: 0.0714 - loss: 2.6694 - val_accuracy: 0.2000 - val_loss: 36.2355 Epoch 11/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 378ms/step - accuracy: 0.1429 - loss: 2.6504 - val_accuracy: 0.2000 - val_loss: 41.2374 Epoch 12/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 381ms/step - accuracy: 0.1786 - loss: 2.6513 - val_accuracy: 0.2000 - val_loss: 47.5227 Epoch 13/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 374ms/step - accuracy: 0.1429 - loss: 2.6497 - val_accuracy: 0.2000 - val_loss: 50.9747 Epoch 14/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 382ms/step - accuracy: 0.1429 - loss: 2.6402 - val_accuracy: 0.2000 - val_loss: 54.6064 Epoch 15/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 380ms/step - accuracy: 0.1786 - loss: 2.6151 - val_accuracy: 0.2000 - val_loss: 58.3921 Epoch 16/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 381ms/step - accuracy: 0.1786 - loss: 2.6106 - val_accuracy: 0.2000 - val_loss: 61.9589 Epoch 17/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 386ms/step - accuracy: 0.2143 - loss: 2.6108 - val_accuracy: 0.2000 - val_loss: 66.4298 Epoch 18/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 388ms/step - accuracy: 0.1786 - loss: 2.5995 - val_accuracy: 0.2000 - val_loss: 68.8060 Epoch 19/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 388ms/step - accuracy: 0.1429 - loss: 2.5761 - val_accuracy: 0.2000 - val_loss: 69.8512 Epoch 20/20 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 379ms/step - accuracy: 0.1429 - loss: 2.6335 - val_accuracy: 0.2000 - val_loss: 74.2540
In [19]:
def predict_tartan(image_path):
# 1. Load and resize the image
img = tf.keras.utils.load_img(image_path, target_size=(224, 224))
# 2. Convert to array and expand dimensions to (1, 224, 224, 3)
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, axis=0)
# 3. Make prediction
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
# 4. Get the result
predicted_class = class_names[np.argmax(score)]
confidence = 100 * np.max(score)
print(f"This image likely belongs to {predicted_class} with {confidence:.2f}% confidence.")
In [20]:
predict_tartan('predict_images/MacDonald Clanranald(1).png')
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 1s/step This image likely belongs to Caledonia with 15.63% confidence.
In [21]:
from pathlib import Path
In [22]:
p = Path('predict_images')
for itm in p.iterdir():
print(itm.name)
predict_tartan(itm)
Abercrombie.JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step This image likely belongs to California State with 16.26% confidence. Lamont and None.JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step This image likely belongs to California State with 16.26% confidence. Lamont(1).JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step This image likely belongs to California State with 16.26% confidence. Lamont(2).JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step This image likely belongs to California State with 16.26% confidence. Lamont(3).jpeg 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step This image likely belongs to California State with 16.26% confidence. MacDonald Clanranald(1).png 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step This image likely belongs to Caledonia with 15.63% confidence. MacDonald ClanRanald(2).JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step This image likely belongs to California State with 16.26% confidence. MacDonald Clanranald(3).JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step This image likely belongs to California State with 16.26% confidence. None.JPG 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step This image likely belongs to California State with 16.26% confidence.
In [ ]: