<jupyter_start><jupyter_text>Training Set<jupyter_code>import os
import numpy as np
# loiding the training data
cats_path = os.listdir("../input/dogs-cats-images/dataset/training_set/cats/")
dogs_path = os.listdir("../input/dogs-cats-images/dataset/training_set/dogs/")
cats_full_path = ["../input/dogs-cats-images/dataset/training_set/cats/" + fname for fname in cats_path]
dogs_full_path = ["../input/dogs-cats-images/dataset/training_set/dogs/" + fname for fname in dogs_path]
X = cats_full_path + dogs_full_path
cats_labels = [0]*len(cats_full_path)
dogs_labels = [1]*len(dogs_full_path)
y = cats_labels + dogs_labels
from IPython.display import display, Image
# showing an image example
Image(cats_full_path[7])
len(X), len(y)<jupyter_output><empty_output><jupyter_text>Spliting the Data<jupyter_code>from sklearn.model_selection import train_test_split

# creating a validation set from train set
X_train, X_val, y_train, y_val = train_test_split(X,
                                                  y, 
                                                  test_size=0.2,
                                                  random_state=42, shuffle=True, stratify=y)<jupyter_output><empty_output><jupyter_text>Convert images to tensors<jupyter_code>import tensorflow as tf
# Check GPU 
print("GPU available" if tf.config.list_physical_devices("GPU") else "not available");
# image size
IMG_SIZE = 200

def process_image(image_path):
    """
    Convert an image file path and turns it into a Tensor.
    """
    # Read an image from path
    image = tf.io.read_file(image_path)
    # Decode the jpeg image into numerical Tensor with 3 colour channels (Red, Green, Blue)
    image = tf.image.decode_jpeg(image, channels=3)
    # Convert the colour channel values from 0-225 to 0-1 values
    image = tf.image.convert_image_dtype(image, tf.float32)
    # Resize the image to our desired size IMG_SIZE
    image = tf.image.resize(image, size=[IMG_SIZE, IMG_SIZE])
    return image
# function to return a tuple (image, label)
def get_image_label(image_path, label):
    """
    Takes an image file path name and the associated label,
    processes the image and returns a tuple of (image, label).
    """
    image = process_image(image_path)
    return image, label
# batch size of 32 is a good default
BATCH_SIZE = 32

# function to turn data into batches
def create_data_batches(x, y, batch_size=BATCH_SIZE):
    """
    Creates batches of data out of image (x) and label (y) pairs.
    """
    print("Creating data batches...")
    # Turn filepaths and labels into Tensors
    data = tf.data.Dataset.from_tensor_slices((tf.constant(x), # filepaths
                                               tf.constant(y))) # labels  
    # Create (image, label) tuples (this also turns the image path into a preprocessed image)
    data = data.map(get_image_label)
    # Turn the data into batches
    data_batch = data.batch(BATCH_SIZE)
    return data_batch
# Create training and validation data batches
train_data = create_data_batches(X_train, y_train)
val_data = create_data_batches(X_val, y_val)
# function which builds our model
def create_model():
    # building the model
    model = tf.keras.models.Sequential([
    # building our CNN 
    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),

    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    
    # Flatten the results to feed into a DNN
    tf.keras.layers.Flatten(),
    # 512 neuron hidden layer
    tf.keras.layers.Dense(512, activation='relu'),
    # Only 1 output neuron. It will contain a value from 0-1 where 0 for 'Cat' and 1 for 'Dog' 
    tf.keras.layers.Dense(1, activation='sigmoid')
    ])

    model.compile(
        loss=tf.keras.losses.binary_crossentropy,
        optimizer=tf.keras.optimizers.Adam(), 
        metrics='accuracy'
    )
    
    return model
# Creating our model 
model = create_model()
model.summary()
# Create early stopping (callback function) (once our model stops improving, stop training)
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
                                                  patience=3) # stops after 3 rounds of no improvements
# number of epochs
NUM_EPOCHS = 20
# function to train and return a trained model
def train_model():
    """
    Trains a given model and returns the trained version.
    """
    # Create a model
    model = create_model()

    history = model.fit(
        train_data,
        epochs=NUM_EPOCHS,
        validation_data=val_data,
        callbacks= [early_stopping])
  
    return model, history
# Fit the model to the data
model, history = train_model()
# model accuracy
test_data = create_data_batches(X_val, y_val)
model.evaluate(test_data)<jupyter_output>Creating data batches...
50/50 [==============================] - 2s 46ms/step - loss: 0.6401 - accuracy: 0.7788<jupyter_text>Evaluating model accuracy<jupyter_code>import matplotlib.pyplot as plt
# Accuracy Evaluation
plt.plot(history.history['accuracy'], label='Train Acc')
plt.plot(history.history['val_accuracy'], label='Val Acc')
plt.xlabel('Number Of Epochs')
plt.ylabel('Accuracy %')
plt.title('Accuracy Evaluation')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Evaluating model loss<jupyter_code># summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Loss Evaluation')
plt.ylabel('Loss %')
plt.xlabel('Number Of Epochs')
plt.legend(['Train Loss', 'Val Loss'], loc='lower left')
plt.show()<jupyter_output><empty_output><jupyter_text>Visualizing the predections<jupyter_code># Make predictions on the validation data (not used to train on)
predictions = model.predict(val_data, verbose=1) # verbose shows us how long there is to go
# Check the shape of predictions
predictions.shape
# Turn prediction probabilities into their respective label (easier to understand)
def get_pred_label(pred_probs):
    """
    Turns an array of prediction probabilities into a label.
    """
    return 0 if pred_probs<.5 else 1

# Get a predicted label based on an array of prediction probabilities
pred_label = get_pred_label(predictions[0])
pred_label
# Create a function to unbatch a batched dataset
def unbatchify(data):
    """
    Takes a batched dataset of (image, label) Tensors and returns separate arrays
    of images and labels.
    """
    images = []
    labels = []
    # Loop through unbatched data
    for image, label in data.unbatch().as_numpy_iterator():
        images.append(image)
        labels.append(label)
    return images, labels

# Unbatchify the validation data
val_images, val_labels = unbatchify(val_data)
val_images[0], val_labels[0]
def plot_pred(pred_probs, labels, images):
    """
    View the prediction, ground truth label and image for a random sample n.
    """
    n = np.random.randint(0,len(images))    
    pred_prob, true_label, image = pred_probs[n], labels[n], images[n]
    # Get the pred label
    pred_label = get_pred_label(pred_prob)
  
    # Plot image & remove ticks
    plt.imshow(image)
    plt.xticks([])
    plt.yticks([])

    # Change the color of the title depending on if the prediction is right or wrong
    if pred_label == true_label:
        color = "green"
    else:
        color = "red"

    plt.title("pred=> {} with prob= {:2.0f}% : label= ({})".format(pred_label,
                                      pred_prob[0]*100,
                                      true_label),
                                      color=color)
# View an example prediction, original image and truth label
plot_pred(pred_probs=predictions,
          labels=val_labels,
          images=val_images)<jupyter_output><empty_output><jupyter_text>Evaluating The Test Data<jupyter_code># loiding the test data
test_cats_path = os.listdir("../input/dogs-cats-images/dataset/test_set/cats/")
test_dogs_path = os.listdir("../input/dogs-cats-images/dataset/test_set/dogs/")
test_cats_full_path = ["../input/dogs-cats-images/dataset/test_set/cats/" + fname for fname in cats_path]
test_dogs_full_path = ["../input/dogs-cats-images/dataset/test_set/dogs/" + fname for fname in dogs_path]
# creating test feature
X_test = cats_full_path + dogs_full_path
test_cats_labels = [0]*len(cats_full_path)
test_dogs_labels = [1]*len(dogs_full_path)
# creating test label
y_test = test_cats_labels + test_dogs_labels
# Create test
test_data = create_data_batches(X_test, y_test)
model.evaluate(test_data)<jupyter_output>Creating data batches...
250/250 [==============================] - 12s 47ms/step - loss: 0.2923 - accuracy: 0.8901
{'fraction_non_alphanumeric': 0.1153252480705623, 'fraction_numerical': 0.01565600882028666, 'mean_word_length': 3.5582914572864324, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '82630', 'license': 'MIT', 'n_tokens_mistral': 3066, 'n_tokens_neox': 2892, 'n_words': 753, 'path': 'cats-dogs-cnn-tensorflow.ipynb', 'repo_name': 'djendara/Cats-Dogs-CNN-TensorFlow', 'size': '9070'}