Import tools

import tensorflow as tf
import tensorflow_hub as hub
print("TF version:", tf.__version__)
print("TF Hub version:", hub.__version__)
TF version: 2.3.0
TF Hub version: 0.10.0

Getting our data ready

Read csv file

import pandas as pd
labels_csv = pd.read_csv("/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/Dog_vs_cat.csv")
labels_csv.drop('Unnamed: 0',axis=1, inplace=True)
labels_csv
filename category
0 dog.9594.jpg 1
1 dog.9601.jpg 1
2 dog.9595.jpg 1
3 dog.9596.jpg 1
4 dog.96.jpg 1
... ... ...
25006 cat.10143.jpg 0
25007 cat.10142.jpg 0
25008 cat.10153.jpg 0
25009 cat.10150.jpg 0
25010 cat.10148.jpg 0

25011 rows × 2 columns

Shuffled DataFrames.

labels_csv = labels_csv.sample(frac = 1)
labels_csv
filename category
18208 cat.4922.jpg 0
472 dog.9184.jpg 1
15617 cat.7580.jpg 0
10547 dog.12107.jpg 1
13962 cat.8578.jpg 0
... ... ...
7820 dog.255.jpg 1
2677 dog.786.jpg 1
19737 cat.3836.jpg 0
22321 cat.12439.jpg 0
20540 cat.288.jpg 0

25011 rows × 2 columns

import matplotlib.pyplot as plt
labels_csv["category"].value_counts().plot.bar(figsize=(5, 5));
from IPython.display import Image
Image("/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.10.jpg")
filenames = ["/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/" + fname for fname in labels_csv["filename"]]

# Check the first 15
filenames[:15]
['/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.4922.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.9184.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.7580.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.12107.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.8578.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.3540.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.4413.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.6806.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.6837.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.22.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.7478.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.10287.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.8332.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.4007.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.5095.jpg']
Image(filenames[2509])
labels_csv["category"][2509]
1

let's prepare our labels.

import numpy as np
labels = labels_csv["category"].to_numpy() 
labels
array([0, 1, 0, ..., 0, 0, 0])
len(labels)
25011
if len(labels) == len(filenames):
  print("labels matches number of filenames!")
else:
  print("labels does not match number of filenames")
labels matches number of filenames!
unique_category = np.unique(labels)
len(unique_category)
2
unique_category
array([0, 1])

Turn label into an array of booleans

print(labels[0])
labels[0] == unique_category
0
array([ True, False])
boolean_labels = [label == unique_category for label in labels]
boolean_labels[:2]
[array([ True, False]), array([False,  True])]
len(boolean_labels)
25011
print(labels[0])
print(np.where(unique_category == labels[0]))
print(boolean_labels[0].argmax())
print(boolean_labels[0].astype(int))
0
(array([0]),)
0
[1 0]
filenames[:10]
['/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.4922.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.9184.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.7580.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.12107.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.8578.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.3540.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.4413.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.6806.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.6837.jpg',
 '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.22.jpg']

Creating our own validation set

X = filenames
y = boolean_labels
from sklearn.model_selection import train_test_split

# Into train and valid 
X_train, X_val, y_train, y_val = train_test_split(X,
                                                  y, 
                                                  test_size=0.2,
                                                  random_state=42)
len(X_train), len(X_val), len(y_train), len(y_val)
(20008, 5003, 20008, 5003)
X_train[:5],y_train[:5]
(['/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.3851.jpg',
  '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.9936.jpg',
  '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.10212.jpg',
  '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/dog.85.jpg',
  '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/train/cat.4980.jpg'],
 [array([False,  True]),
  array([ True, False]),
  array([False,  True]),
  array([False,  True]),
  array([ True, False])])

Preprocessing Images

Befor we do, let's see what image looks like in to tensors

from matplotlib.pyplot import imread
image = imread(filenames[42])
image.shape
(194, 320, 3)
tf.constant(image)
<tf.Tensor: shape=(194, 320, 3), dtype=uint8, numpy=
array([[[225, 210, 203],
        [226, 211, 204],
        [228, 213, 206],
        ...,
        [202, 189, 183],
        [214, 201, 195],
        [219, 204, 199]],

       [[222, 207, 200],
        [223, 208, 201],
        [224, 209, 202],
        ...,
        [199, 186, 180],
        [212, 199, 193],
        [209, 194, 189]],

       [[223, 208, 201],
        [224, 209, 202],
        [224, 209, 202],
        ...,
        [206, 193, 187],
        [220, 207, 201],
        [208, 193, 188]],

       ...,

       [[228, 213, 206],
        [228, 213, 206],
        [230, 215, 208],
        ...,
        [231, 222, 217],
        [225, 216, 211],
        [218, 209, 204]],

       [[224, 209, 202],
        [228, 213, 206],
        [232, 217, 210],
        ...,
        [224, 215, 208],
        [225, 216, 207],
        [227, 218, 209]],

       [[224, 209, 202],
        [228, 213, 206],
        [232, 217, 210],
        ...,
        [224, 215, 208],
        [225, 216, 207],
        [227, 218, 209]]], dtype=uint8)>

TURNING IMAGES INTO TENSOR

A Function for Preprocessing images:

  1. Take an image filepath as input
  2. Use Tensorflow to read the file and save it to a variable image
  3. Turn our image into Tensors
  4. Normalize our image
  5. Resize the images to be a shape of (224,224)
  6. Return the modified images
IMG_SIZE = 224

# Function
def process_image(image_path, image_size=IMG_SIZE):
  """
  Takes an image file path and turns the image into a Tensor.
  """
  # Read in an image file
  image = tf.io.read_file(image_path)
  # Turn the jpg image into numerical Tensor with 3 colour channel(RGB)
  image = tf.image.decode_jpeg(image,channels=3)
  # Convert the color channel values to (0-1) values
  image = tf.image.convert_image_dtype(image,tf.float32)
  # Resize the image to (224,224)
  image = tf.image.resize(image, size=[image_size,image_size])

  return image

Turning our data into Batches

def get_image_lable(image_path,label):
  """
  Takes an image file path name and the label,
  processes the image and return a tuple (image, label).
  """
  image = process_image(image_path)
  
  return image,label

Let's make a function to turn all of data into batches!

BATCH_SIZE = 32

# Function to convert data into batches
def create_data_batches(X,y=None, batch_size=BATCH_SIZE,valid_data=False):
  """
  Creates batches of data of image (X) and label (y) pairs.
  Shuffle the data if it's training data but doesn't shuffle if it's validation data.
  """
  # If data is valid dataset (NO SHUFFLE)
  if valid_data:
    print("Creating valid data batches.........")
    data = tf.data.Dataset.from_tensor_slices((tf.constant(X),
                                               tf.constant(y)))
    data_batch = data.map(get_image_lable).batch(batch_size)
    return data_batch

  else:
    print("Creating train data batches.........")
    # Turn filepaths and labels into Tensors
    data = tf.data.Dataset.from_tensor_slices((tf.constant(X),
                                               tf.constant(y)))
    # Shuffling pathname and labels before mapping image processor fun
    data = data.shuffle(buffer_size=len(X))
    data_batch = data.map(get_image_lable).batch(batch_size)

    return data_batch
train_data = create_data_batches(X_train, y_train)
val_data = create_data_batches(X_val, y_val, valid_data=True)
Creating train data batches.........
Creating valid data batches.........
train_data.element_spec, val_data.element_spec
((TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name=None),
  TensorSpec(shape=(None, 2), dtype=tf.bool, name=None)),
 (TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name=None),
  TensorSpec(shape=(None, 2), dtype=tf.bool, name=None)))

Visualizing Data Batches

import matplotlib.pyplot as plt
# Create fun for viewing in a data batch
def show_images(images, labels):
  """
  Displays a plot of 25 images and their labels from a data batch.
  """
  plt.figure(figsize=(20, 20))
  for i in range(25):
    # Subplot
    ax = plt.subplot(5,5,i+1)
    plt.imshow(images[i])
    plt.title(unique_category[labels[i].argmax()])
    plt.axis("Off")
train_images, train_labels = next(train_data.as_numpy_iterator())
train_images, train_labels
(array([[[[0.2826692 , 0.27675182, 0.30912226],
          [0.28703934, 0.28112197, 0.31349242],
          [0.2952971 , 0.28937972, 0.32175016],
          ...,
          [0.17186178, 0.16404086, 0.20467226],
          [0.1409928 , 0.133163  , 0.17379884],
          [0.14484434, 0.14870942, 0.1844739 ]],
 
         [[0.31613198, 0.29538617, 0.333674  ],
          [0.30875242, 0.2880066 , 0.32629442],
          [0.3241037 , 0.3033579 , 0.34164572],
          ...,
          [0.14443067, 0.13221769, 0.15652625],
          [0.0981044 , 0.08584315, 0.11016917],
          [0.17427143, 0.16930833, 0.19169979]],
 
         [[0.32277972, 0.28142816, 0.32776922],
          [0.35427544, 0.3129239 , 0.35926494],
          [0.36919445, 0.32784292, 0.37418395],
          ...,
          [0.2003182 , 0.18230036, 0.19426078],
          [0.1211253 , 0.10258538, 0.11506787],
          [0.16337338, 0.14483346, 0.15731597]],
 
         ...,
 
         [[0.5920565 , 0.57494986, 0.6840207 ],
          [0.59542924, 0.5783353 , 0.6873584 ],
          [0.6164389 , 0.5993577 , 0.708333  ],
          ...,
          [0.7857931 , 0.80540097, 0.91912645],
          [0.7983909 , 0.81799877, 0.93172425],
          [0.7966274 , 0.81623524, 0.9299607 ]],
 
         [[0.5510833 , 0.5305476 , 0.646339  ],
          [0.5436558 , 0.524637  , 0.63493735],
          [0.5932025 , 0.57419705, 0.6844491 ],
          ...,
          [0.79417616, 0.8201229 , 0.9309161 ],
          [0.79588056, 0.8217882 , 0.9325988 ],
          [0.7838864 , 0.8150447 , 0.92253506]],
 
         [[0.5902488 , 0.5667194 , 0.6765233 ],
          [0.58125216, 0.55772275, 0.66066813],
          [0.59609354, 0.5725641 , 0.67550063],
          ...,
          [0.77784693, 0.81559896, 0.9219692 ],
          [0.7797044 , 0.8174431 , 0.92381775],
          [0.78092784, 0.82698435, 0.9226055 ]]],
 
 
        [[[0.44143307, 0.39829582, 0.39045268],
          [0.43832287, 0.39518562, 0.38734248],
          [0.43936062, 0.39622337, 0.38838023],
          ...,
          [0.6614712 , 0.735981  , 0.24427053],
          [0.61897016, 0.69347996, 0.20176955],
          [0.7173941 , 0.791904  , 0.3001935 ]],
 
         [[0.416229  , 0.37309173, 0.3652486 ],
          [0.41362923, 0.37049195, 0.36264881],
          [0.41362923, 0.37049195, 0.36264881],
          ...,
          [0.67969424, 0.7469824 , 0.3040377 ],
          [0.604985  , 0.67227316, 0.22932845],
          [0.6605307 , 0.72781885, 0.28487417]],
 
         [[0.4107143 , 0.36757702, 0.35973388],
          [0.40811452, 0.36497724, 0.3571341 ],
          [0.40811452, 0.36497724, 0.3571341 ],
          ...,
          [0.48873878, 0.52800286, 0.15470313],
          [0.46664834, 0.504557  , 0.13133964],
          [0.5523329 , 0.5916963 , 0.2183906 ]],
 
         ...,
 
         [[0.257373  , 0.27105847, 0.06162212],
          [0.39397824, 0.41317147, 0.20155296],
          [0.5798493 , 0.6104076 , 0.3826898 ],
          ...,
          [0.29091948, 0.35425556, 0.15920989],
          [0.25120127, 0.31705973, 0.10619664],
          [0.31459087, 0.3833176 , 0.16046302]],
 
         [[0.31542486, 0.33775508, 0.11932267],
          [0.42254394, 0.46245956, 0.21355283],
          [0.70242745, 0.7582074 , 0.44450924],
          ...,
          [0.2555019 , 0.3261044 , 0.11227396],
          [0.29704627, 0.36061937, 0.1480565 ],
          [0.20160262, 0.26611367, 0.05258301]],
 
         [[0.61772764, 0.6373793 , 0.3941107 ],
          [0.74314606, 0.7904675 , 0.46802348],
          [0.52938443, 0.6214713 , 0.1596628 ],
          ...,
          [0.23504041, 0.28994235, 0.08209924],
          [0.207591  , 0.24310353, 0.0585277 ],
          [0.20691648, 0.23181117, 0.06309658]]],
 
 
        [[[0.8067808 , 0.5491867 , 0.7598499 ],
          [0.5959661 , 0.271777  , 0.5144344 ],
          [0.7109116 , 0.28240204, 0.55941516],
          ...,
          [0.6609296 , 0.7001453 , 0.6648512 ],
          [0.6842579 , 0.71184   , 0.68042374],
          [0.6211969 , 0.65124774, 0.6120756 ]],
 
         [[0.7346151 , 0.12982179, 0.45797306],
          [0.83824706, 0.22100466, 0.5535414 ],
          [0.7474404 , 0.10629252, 0.44568238],
          ...,
          [0.45346475, 0.49268043, 0.4573863 ],
          [0.62152267, 0.66073835, 0.62544423],
          [0.7129607 , 0.7469767 , 0.7064828 ]],
 
         [[0.6097017 , 0.10229574, 0.3921245 ],
          [0.56863743, 0.08694429, 0.35841337],
          [0.58433217, 0.08333191, 0.37190062],
          ...,
          [0.392608  , 0.43966678, 0.40045112],
          [0.64723563, 0.68653864, 0.65120083],
          [0.63717455, 0.6711905 , 0.63069665]],
 
         ...,
 
         [[0.35166317, 0.3477416 , 0.33989847],
          [0.36074054, 0.35681897, 0.34897584],
          [0.34611344, 0.33950457, 0.3397234 ],
          ...,
          [0.21258524, 0.23058246, 0.12174098],
          [0.21291845, 0.23091568, 0.12445551],
          [0.20145264, 0.2194499 , 0.11043367]],
 
         [[0.3351363 , 0.33121473, 0.3233716 ],
          [0.34640884, 0.34248728, 0.33464414],
          [0.33810344, 0.33149454, 0.33171338],
          ...,
          [0.2615026 , 0.2857153 , 0.13704497],
          [0.23887654, 0.26243013, 0.11680023],
          [0.21524014, 0.23950122, 0.09060777]],
 
         [[0.3070396 , 0.30311802, 0.29527488],
          [0.32539397, 0.3214724 , 0.31362927],
          [0.32797605, 0.32136717, 0.321586  ],
          ...,
          [0.26418078, 0.2877102 , 0.14534342],
          [0.25512934, 0.27865875, 0.13744017],
          [0.23413137, 0.25766078, 0.11520979]]],
 
 
        ...,
 
 
        [[[0.36886755, 0.35710284, 0.337495  ],
          [0.37024313, 0.35847843, 0.33887056],
          [0.6482143 , 0.6364496 , 0.61684173],
          ...,
          [0.22596239, 0.24023049, 0.25483152],
          [0.23179743, 0.2474837 , 0.25924838],
          [0.2436975 , 0.25938377, 0.27114847]],
 
         [[0.376213  , 0.36444828, 0.34484044],
          [0.3416942 , 0.3299295 , 0.31032163],
          [0.6254352 , 0.61367047, 0.5940626 ],
          ...,
          [0.24108844, 0.25535655, 0.26995757],
          [0.24645104, 0.2621373 , 0.273902  ],
          [0.24873951, 0.26442578, 0.2761905 ]],
 
         [[0.3669993 , 0.3552346 , 0.33562675],
          [0.33851543, 0.32675073, 0.30714288],
          [0.6753051 , 0.6635404 , 0.6439326 ],
          ...,
          [0.25061226, 0.26488036, 0.27948138],
          [0.2546969 , 0.27038318, 0.28214788],
          [0.25378153, 0.2694678 , 0.2812325 ]],
 
         ...,
 
         [[0.69682366, 0.5975066 , 0.6113621 ],
          [0.6795593 , 0.58971846, 0.6009705 ],
          [0.66809714, 0.60013   , 0.6008453 ],
          ...,
          [0.3054788 , 0.21627113, 0.2467259 ],
          [0.34534314, 0.23756042, 0.2680653 ],
          [0.3389354 , 0.22016795, 0.24848439]],
 
         [[0.67655396, 0.56196076, 0.57270765],
          [0.6486129 , 0.54638463, 0.55407786],
          [0.6345677 , 0.5559213 , 0.5547535 ],
          ...,
          [0.32925826, 0.22821364, 0.24691615],
          [0.36057922, 0.2431775 , 0.25678056],
          [0.35966367, 0.23585422, 0.25143814]],
 
         [[0.7109322 , 0.5883931 , 0.5986823 ],
          [0.66681445, 0.5537442 , 0.5611296 ],
          [0.59691626, 0.50954384, 0.5077681 ],
          ...,
          [0.33136725, 0.22392224, 0.23819034],
          [0.34379455, 0.22348174, 0.23081224],
          [0.35798317, 0.22577025, 0.23081224]]],
 
 
        [[[0.28135863, 0.23037826, 0.26959392],
          [0.27375028, 0.2227699 , 0.258064  ],
          [0.2710955 , 0.2201151 , 0.25477895],
          ...,
          [0.5006653 , 0.45752805, 0.44968492],
          [0.48627454, 0.4431373 , 0.43529415],
          [0.48627454, 0.4431373 , 0.43529415]],
 
         [[0.30496526, 0.25398487, 0.28927898],
          [0.3158937 , 0.26491332, 0.30017772],
          [0.30290478, 0.2519244 , 0.27937537],
          ...,
          [0.50978786, 0.4666506 , 0.45880747],
          [0.4941702 , 0.44711137, 0.44711137],
          [0.4941702 , 0.44711137, 0.44711137]],
 
         [[0.2945208 , 0.2435404 , 0.2735474 ],
          [0.31782216, 0.26684177, 0.2946807 ],
          [0.29444796, 0.24611112, 0.26563144],
          ...,
          [0.5009104 , 0.45777312, 0.44992998],
          [0.5005953 , 0.45353645, 0.454339  ],
          [0.5005953 , 0.45353645, 0.45882356]],
 
         ...,
 
         [[0.36579135, 0.31873253, 0.32657567],
          [0.37657672, 0.3295179 , 0.33736104],
          [0.37433967, 0.32759598, 0.32696572],
          ...,
          [0.61843264, 0.5988248 , 0.5831385 ],
          [0.62185025, 0.60264367, 0.58007824],
          [0.61859286, 0.6       , 0.5750001 ]],
 
         [[0.37738097, 0.33032215, 0.33816528],
          [0.3815976 , 0.33453876, 0.3423819 ],
          [0.3566018 , 0.3098581 , 0.30922785],
          ...,
          [0.6313036 , 0.61169577, 0.5960095 ],
          [0.61960787, 0.6       , 0.5843084 ],
          [0.61960787, 0.6       , 0.5867053 ]],
 
         [[0.35487074, 0.30781192, 0.31565505],
          [0.3587888 , 0.31172997, 0.3195731 ],
          [0.35075194, 0.30400825, 0.303378  ],
          ...,
          [0.6684691 , 0.6488612 , 0.63317496],
          [0.6535535 , 0.63133717, 0.6273979 ],
          [0.65505916, 0.6320339 , 0.6305214 ]]],
 
 
        [[[0.32352942, 0.31176472, 0.29215688],
          [0.33953083, 0.32776612, 0.30815828],
          [0.34856445, 0.33679974, 0.3171919 ],
          ...,
          [0.3016457 , 0.28203785, 0.26635158],
          [0.30957633, 0.2899685 , 0.27428222],
          [0.30957633, 0.2899685 , 0.27428222]],
 
         [[0.3147759 , 0.3030112 , 0.28340337],
          [0.33077732, 0.3190126 , 0.29940477],
          [0.33981094, 0.32804623, 0.3084384 ],
          ...,
          [0.3010178 , 0.28140995, 0.26572368],
          [0.3051996 , 0.28559175, 0.26990548],
          [0.3051996 , 0.28559175, 0.26990548]],
 
         [[0.30716038, 0.29539567, 0.27578783],
          [0.32316178, 0.31139708, 0.29178923],
          [0.3321954 , 0.3204307 , 0.30082285],
          ...,
          [0.2979478 , 0.27833995, 0.26265368],
          [0.29968488, 0.28007704, 0.26439077],
          [0.29968488, 0.28007704, 0.26439077]],
 
         ...,
 
         [[0.38116246, 0.34194675, 0.29488793],
          [0.3828408 , 0.3436251 , 0.29656628],
          [0.36612785, 0.32691216, 0.27985334],
          ...,
          [0.4471094 , 0.4353447 , 0.41573685],
          [0.48121503, 0.46552876, 0.45376405],
          [0.48121503, 0.46552876, 0.45376405]],
 
         [[0.37689126, 0.33767554, 0.29061672],
          [0.37715337, 0.33793765, 0.29087883],
          [0.36428103, 0.32506534, 0.27800652],
          ...,
          [0.4166144 , 0.4048497 , 0.38524187],
          [0.45939228, 0.443706  , 0.4319413 ],
          [0.48061773, 0.46493146, 0.45316675]],
 
         [[0.37647063, 0.3372549 , 0.2901961 ],
          [0.37647063, 0.3372549 , 0.2901961 ],
          [0.36439076, 0.32517508, 0.27811626],
          ...,
          [0.3915626 , 0.3797979 , 0.36019006],
          [0.45455205, 0.43886578, 0.42710108],
          [0.48025194, 0.46456566, 0.45280096]]]], dtype=float32),
 array([[False,  True],
        [False,  True],
        [ True, False],
        [ True, False],
        [False,  True],
        [ True, False],
        [False,  True],
        [ True, False],
        [ True, False],
        [ True, False],
        [ True, False],
        [ True, False],
        [ True, False],
        [False,  True],
        [ True, False],
        [ True, False],
        [ True, False],
        [ True, False],
        [False,  True],
        [ True, False],
        [ True, False],
        [False,  True],
        [False,  True],
        [ True, False],
        [ True, False],
        [ True, False],
        [False,  True],
        [ True, False],
        [ True, False],
        [False,  True],
        [ True, False],
        [ True, False]]))
len(train_images), len(train_labels)
(32, 32)
train_images, train_labels = next(train_data.as_numpy_iterator())
show_images(train_images,train_labels)
val_images, val_labels = next(val_data.as_numpy_iterator())
show_images(val_images, val_labels)

Building a model

Before we build a model--->

  • The input shape.
  • The output shape.
  • The URL of the model we want to use.
INPUT_SHAPE = [None, IMG_SIZE, IMG_SIZE, 3] # Batch, height, width, Colour_chanels

# Setup output shape of the model
OUTPUT_SHAPE = len(unique_category)

# Setup model URL
MODEL_URL = "https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/4"
def create_model(input_shape=INPUT_SHAPE,output_shape=OUTPUT_SHAPE, model_url=MODEL_URL):
  print("Building model with:", model_url)

  # Setup the model
  model = tf.keras.Sequential([
                               hub.KerasLayer(model_url),
                               tf.keras.layers.Dense(units=output_shape, 
                                                     activation="softmax")
  ])

  # Compile the model
  model.compile(
      loss = tf.keras.losses.BinaryCrossentropy(),
      optimizer = tf.keras.optimizers.Adam(),
      metrics = ["accuracy"]
  )

  # Build the model
  model.build(input_shape)

  return model
model = create_model()
model.summary()
Building model with: https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/4
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
keras_layer_4 (KerasLayer)   (None, 1001)              5432713   
_________________________________________________________________
dense_4 (Dense)              (None, 2)                 2004      
=================================================================
Total params: 5,434,717
Trainable params: 2,004
Non-trainable params: 5,432,713
_________________________________________________________________

Creating callbacks

TesnorBoard Callback

%load_ext tensorboard
import datetime
import os
# Create a function to build a TensorBoard callback
def create_tensorboard_callback():
  logdir = os.path.join("/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/log",
                        datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
  
  return tf.keras.callbacks.TensorBoard(logdir)

Early stopping callback

early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
                                                  patience = 3)

Training a model

NUM_EPOCHS = 100
print("GPU is on" if tf.config.list_physical_devices("GPU") else "No GPU :(")
GPU is on
def train_model():
  tensorboard = create_tensorboard_callback()
  
  # Fit the model
  model.fit(x=train_data,
            epochs= NUM_EPOCHS,
            validation_data=val_data,
            validation_freq = 1,
            callbacks = [tensorboard,early_stopping])
  return model
model = train_model()
Epoch 1/100
  1/626 [..............................] - ETA: 0s - loss: 1.7851 - accuracy: 0.3438WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
626/626 [==============================] - 11646s 19s/step - loss: 0.0721 - accuracy: 0.9751 - val_loss: 0.0298 - val_accuracy: 0.9890
Epoch 2/100
626/626 [==============================] - 90s 144ms/step - loss: 0.0358 - accuracy: 0.9884 - val_loss: 0.0285 - val_accuracy: 0.9894
Epoch 3/100
626/626 [==============================] - 88s 140ms/step - loss: 0.0309 - accuracy: 0.9905 - val_loss: 0.0334 - val_accuracy: 0.9896
Epoch 4/100
626/626 [==============================] - 88s 140ms/step - loss: 0.0297 - accuracy: 0.9906 - val_loss: 0.0371 - val_accuracy: 0.9884
Epoch 5/100
626/626 [==============================] - 89s 143ms/step - loss: 0.0280 - accuracy: 0.9909 - val_loss: 0.0353 - val_accuracy: 0.9876
Epoch 6/100
626/626 [==============================] - 88s 141ms/step - loss: 0.0261 - accuracy: 0.9913 - val_loss: 0.0321 - val_accuracy: 0.9900
Epoch 7/100
626/626 [==============================] - 87s 138ms/step - loss: 0.0248 - accuracy: 0.9919 - val_loss: 0.0396 - val_accuracy: 0.9892
Epoch 8/100
626/626 [==============================] - 86s 137ms/step - loss: 0.0241 - accuracy: 0.9913 - val_loss: 0.0367 - val_accuracy: 0.9884
Epoch 9/100
626/626 [==============================] - 87s 139ms/step - loss: 0.0211 - accuracy: 0.9928 - val_loss: 0.0419 - val_accuracy: 0.9890
%tensorboard --logdir /content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/log

Making and evaluating prediction using a trained model

predictions = model.predict(val_data, verbose=1)
predictions
157/157 [==============================] - 18s 114ms/step
array([[9.9999869e-01, 1.2679378e-06],
       [6.4851592e-06, 9.9999356e-01],
       [1.8989309e-05, 9.9998105e-01],
       ...,
       [1.0000000e+00, 1.2742490e-08],
       [1.0000000e+00, 1.9644544e-08],
       [1.0814135e-05, 9.9998915e-01]], dtype=float32)
predictions.shape
(5003, 2)
np.sum(predictions[0])
0.99999994
def make_prediction(prediction_probabilities):
  """
  Turns an array of prediction probabilities into a label.
  """

  return unique_category[np.argmax(prediction_probabilities)]
pred_label = make_prediction(predictions[17])
pred_label
0
val_data
<BatchDataset shapes: ((None, 224, 224, 3), (None, 2)), types: (tf.float32, tf.bool)>
def unbatchify(data):
  """
  Takes a batched dataset of (image, label) Tensors and reutrns 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(unique_category[np.argmax(label)])
  return images, labels

# Unbatchify the validation data
val_images, val_labels = unbatchify(val_data)
val_images[0], val_labels[0]
(array([[[0.3839508 , 0.46238217, 0.6074802 ],
         [0.3810609 , 0.45949227, 0.6045903 ],
         [0.37647063, 0.454902  , 0.6       ],
         ...,
         [0.21960786, 0.28788537, 0.40553245],
         [0.21960786, 0.28627452, 0.4039216 ],
         [0.21960786, 0.28627452, 0.4039216 ]],
 
        [[0.39075977, 0.46919113, 0.61428916],
         [0.38780484, 0.4662362 , 0.61133426],
         [0.38371852, 0.4621499 , 0.60724795],
         ...,
         [0.22029103, 0.28856856, 0.40621564],
         [0.21960786, 0.28627452, 0.4039216 ],
         [0.21960786, 0.28627452, 0.4039216 ]],
 
        [[0.39936978, 0.47780114, 0.6228992 ],
         [0.3961657 , 0.47459707, 0.61969507],
         [0.39247203, 0.4709034 , 0.6160014 ],
         ...,
         [0.220478  , 0.28875554, 0.40640262],
         [0.21960786, 0.28627452, 0.4039216 ],
         [0.21960786, 0.28627452, 0.4039216 ]],
 
        ...,
 
        [[0.4504261 , 0.43473983, 0.3988155 ],
         [0.4474612 , 0.4317749 , 0.39630637],
         [0.4474387 , 0.4317524 , 0.3964583 ],
         ...,
         [0.7306667 , 0.7157211 , 0.68042696],
         [0.7375876 , 0.7186452 , 0.68443644],
         [0.7516807 , 0.72422963, 0.6928571 ]],
 
        [[0.44408268, 0.43231797, 0.41110635],
         [0.45273113, 0.44096643, 0.41951722],
         [0.4501751 , 0.4384104 , 0.4135161 ],
         ...,
         [0.7335602 , 0.7217955 , 0.70082134],
         [0.73665965, 0.72489494, 0.7004757 ],
         [0.73665965, 0.72489494, 0.70023835]],
 
        [[0.44408268, 0.43231797, 0.41271013],
         [0.45273113, 0.44096643, 0.4213586 ],
         [0.4501751 , 0.4384104 , 0.41880256],
         ...,
         [0.7254081 , 0.7136434 , 0.69403553],
         [0.7264005 , 0.7146358 , 0.69502795],
         [0.7264005 , 0.7146358 , 0.69502795]]], dtype=float32), 0)
def plot_pred(prediction_probabilities, labels, images, n=1):
  """
  View the prediction, ground truth and image for sample n
  """
  pred_prob, true_label, image = prediction_probabilities[n], labels[n], images[n]

  # Get the pred label
  pred_label = make_prediction(pred_prob)

  # Plot image & remove ticks
  plt.imshow(image)
  plt.xticks([])
  plt.yticks([])

  # Change the colour of the title depending on if the prediction is right or wrong
  if pred_label == true_label:
    color = "green"
  else:
    color = "red"
  
  # Change plot title to be predicted, probability of prediction and truth label
  plt.title("{} {:2.0f}% {}".format(pred_label,
                                    np.max(pred_prob)*100,
                                    true_label),
                                    color=color)
plot_pred(prediction_probabilities=predictions,
          labels=val_labels,
          images=val_images,
          n=15)
def plot_pred_conf(prediction_probabilities, labels, n=1):
  """
  Plus the top 10 highest prediction confidences along with the truth label for sample n.
  """
  pred_prob, true_label = prediction_probabilities[n], labels[n]

  # Get the predicted label
  pred_label = make_prediction(pred_prob)

  # Find the top 10 prediction confidence indexes
  top_10_pred_indexes = pred_prob.argsort()[-10:][::-1]
  # Find the top 10 prediction confidence values
  top_10_pred_values = pred_prob[top_10_pred_indexes]
  # Find the top 10 prediction labels
  top_10_pred_labels = unique_category[top_10_pred_indexes]

  # Setup plot
  top_plot = plt.bar(np.arange(len(top_10_pred_labels)),
                     top_10_pred_values,
                     color="grey")
  plt.xticks(np.arange(len(top_10_pred_labels)),
             labels=top_10_pred_labels,
             rotation="vertical")
  
  # Change color of true label
  if np.isin(true_label, top_10_pred_labels):
    top_plot[np.argmax(top_10_pred_labels == true_label)].set_color("green")
  else:
    pass
plot_pred_conf(prediction_probabilities=predictions,
               labels=val_labels,
               n=9)
i_multiplier = 20
num_rows = 5
num_cols = 5
num_images = num_rows*num_cols
plt.figure(figsize=(10*num_cols, 5*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_pred(prediction_probabilities=predictions,
            labels=val_labels,
            images=val_images,
            n=i+i_multiplier)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_pred_conf(prediction_probabilities=predictions,
                 labels=val_labels,
                 n=i+i_multiplier)
plt.tight_layout(h_pad=1.0)
plt.show()

Saving and reloading a trained model

def save_model(model, suffix=None):
  """
  Saves a given model in a models directory and appends a suffix (string).
  """
  # Create a model directory pathname with current time
  modeldir = "/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/"
  model_path = modeldir + "-" + suffix + ".h5" # save format of model
  print(f"Saving model to: {model_path}...")
  model.save(model_path)
  return model_path
save_model(model, suffix="mobilenetv2-Adam")
Saving model to: /content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/-mobilenetv2-Adam.h5...
'/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/-mobilenetv2-Adam.h5'
model.evaluate(val_data)
157/157 [==============================] - 18s 116ms/step - loss: 0.0419 - accuracy: 0.9890
[0.0419415719807148, 0.9890065789222717]

Predict on custom data

test = '/content/drive/MyDrive/dog.jpg'
test = imread(test)
test = tf.image.convert_image_dtype(test,tf.float32)
test = tf.image.resize(test, size=[224,224])
test = np.expand_dims(test,axis=0)
test.shape
(1, 224, 224, 3)
pred = model.predict(test)
pred
array([[0.01689671, 0.9831033 ]], dtype=float32)
pred_label = make_prediction(pred)
pred_label
1
test1 = '/content/drive/MyDrive/cat.jpg'
test1 = imread(test1)
test1 = tf.image.convert_image_dtype(test1,tf.float32)
test1 = tf.image.resize(test1, size=[224,224])
test1 = np.expand_dims(test1,axis=0)
pred1 = model.predict(test1)
pred1
array([[1.0000000e+00, 6.8222934e-09]], dtype=float32)
pred_label = make_prediction(pred1)
pred_label
0

Testing Fun

def test_data(path):
  demo = imread(path)
  demo = tf.image.convert_image_dtype(demo,tf.float32)
  demo = tf.image.resize(demo,size=[224,224])
  demo = np.expand_dims(demo,axis=0)

  pred = model.predict(demo)
  result = unique_category[np.argmax(pred)]

  return result
path = '/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/test/cat.jpg'
path1 ='/content/drive/MyDrive/COLAB_PROJECT/1.CNN/Dog_vs_cat/test/dog.jpg'
test_data(path)
0
test_data(path1)
1