Created
February 18, 2022 04:21
-
-
Save sciencegirl100/702ea9fd2b1fb691687e1ee170a4d417 to your computer and use it in GitHub Desktop.
Pets.py
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
# Import Required Dependencies | |
import tensorflow as tf | |
import numpy as np | |
from tensorflow import keras | |
import os | |
import matplotlib.pyplot as plt | |
from tensorflow.keras import layers | |
# Remove Badly Encoded Images | |
num_skipped = 0 | |
data_set_folder = "DataSets/PetImages" | |
for folder_name in ("Cat", "Dog"): | |
folder_path = os.path.join(data_set_folder, folder_name) | |
for fname in os.listdir(folder_path): | |
fpath = os.path.join(folder_path, fname) | |
try: | |
fobj = open(fpath, "rb") | |
is_jfif = tf.compat.as_bytes("JFIF") in fobj.peek(10) | |
finally: | |
fobj.close() | |
if not is_jfif: | |
num_skipped += 1 | |
# Delete corrupted image | |
os.remove(fpath) | |
print("Deleted %d images" % num_skipped) | |
# Create Datasets | |
image_size = (180, 180) | |
batch_size = 32 | |
train_ds = tf.keras.preprocessing.image_dataset_from_directory( | |
data_set_folder, | |
validation_split=0.2, | |
subset="training", | |
seed=1337, | |
image_size=image_size, | |
batch_size=batch_size, | |
) | |
val_ds = tf.keras.preprocessing.image_dataset_from_directory( | |
data_set_folder, | |
validation_split=0.2, | |
subset="validation", | |
seed=1337, | |
image_size=image_size, | |
batch_size=batch_size, | |
) | |
# Display Test Selection | |
plt.figure(figsize=(10, 10)) | |
for images, labels in train_ds.take(1): | |
for i in range(9): | |
ax = plt.subplot(3, 3, i + 1) | |
plt.imshow(images[i].numpy().astype("uint8")) | |
plt.title(int(labels[i])) | |
plt.axis("off") | |
# Artificial Data Augmentation to improve training | |
data_augmentation = keras.Sequential( | |
[ | |
layers.RandomFlip("horizontal"), | |
layers.RandomRotation(0.1), | |
] | |
) | |
augmented_train_ds = train_ds.map( | |
lambda x, y: (data_augmentation(x, training=True), y)) | |
plt.figure(figsize=(10, 10)) | |
for images, _ in train_ds.take(1): | |
for i in range(9): | |
augmented_images = data_augmentation(images) | |
ax = plt.subplot(3, 3, i + 1) | |
plt.imshow(augmented_images[0].numpy().astype("uint8")) | |
plt.axis("off") | |
# Configure Dataset and Build the Model | |
train_ds = train_ds.prefetch(buffer_size=32) | |
val_ds = val_ds.prefetch(buffer_size=32) | |
def make_model(input_shape, num_classes): | |
inputs = keras.Input(shape=input_shape) | |
# Image augmentation block | |
x = data_augmentation(inputs) | |
# Entry block | |
x = layers.Rescaling(1.0 / 255)(x) | |
x = layers.Conv2D(32, 3, strides=2, padding="same")(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Activation("relu")(x) | |
x = layers.Conv2D(64, 3, padding="same")(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Activation("relu")(x) | |
previous_block_activation = x # Set aside residual | |
for size in [128, 256, 512, 728]: | |
x = layers.Activation("relu")(x) | |
x = layers.SeparableConv2D(size, 3, padding="same")(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Activation("relu")(x) | |
x = layers.SeparableConv2D(size, 3, padding="same")(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.MaxPooling2D(3, strides=2, padding="same")(x) | |
# Project residual | |
residual = layers.Conv2D(size, 1, strides=2, padding="same")( | |
previous_block_activation | |
) | |
x = layers.add([x, residual]) # Add back residual | |
previous_block_activation = x # Set aside next residual | |
x = layers.SeparableConv2D(1024, 3, padding="same")(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Activation("relu")(x) | |
x = layers.GlobalAveragePooling2D()(x) | |
if num_classes == 2: | |
activation = "sigmoid" | |
units = 1 | |
else: | |
activation = "softmax" | |
units = num_classes | |
x = layers.Dropout(0.5)(x) | |
outputs = layers.Dense(units, activation=activation)(x) | |
return keras.Model(inputs, outputs) | |
model = make_model(input_shape=image_size + (3,), num_classes=2) | |
keras.utils.plot_model(model, show_shapes=True) | |
# Train the model | |
epochs = 50 | |
callbacks = [ | |
keras.callbacks.ModelCheckpoint("save_at_{epoch}.h5"), | |
] | |
model.compile( | |
optimizer=keras.optimizers.Adam(1e-3), | |
loss="binary_crossentropy", | |
metrics=["accuracy"], | |
) | |
model.fit( | |
train_ds, epochs=epochs, callbacks=callbacks, validation_data=val_ds, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment