import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
!curl -O https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_5340.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 786M 100 786M 0 0 118M 0 0:00:06 0:00:06 --:--:-- 125M 0 0:00:10 --:--:-- 0:00:10 76.7M
!unzip -q kagglecatsanddogs_5340.zip
!ls
CDLA-Permissive-2.0.pdf __notebook_source__.ipynb model.png
PetImages kagglecatsanddogs_5340.zip 'readme[1].txt'
!ls PetImages
Cat Dog
import os
num_skipped = 0
for folder_name in ("Cat", "Dog"):
folder_path = os.path.join("PetImages", 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)
Deleted 1590 images
image_size = (160, 160)
batch_size = 128
train_ds, val_ds = tf.keras.utils.image_dataset_from_directory(
"PetImages",
validation_split=0.25,
subset="both",
seed=1337,
image_size=image_size,
batch_size=batch_size,
)
Found 23410 files belonging to 2 classes.
Using 17558 files for training.
Using 5852 files for validation
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
]
)
# Apply `data_augmentation` to the training images.
train_ds = train_ds.map(
lambda img, label: (data_augmentation(img), label),
num_parallel_calls=tf.data.AUTOTUNE,
)
# Prefetching samples in GPU memory helps maximize GPU utilization.
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.prefetch(tf.data.AUTOTUNE)
inputs = keras.Input(shape=(160, 160, 3))
x = layers.Rescaling(1.0 / 255)(inputs)
x = layers.Conv2D(32, 3, strides=2, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
previous_block_activation = x
for size in [64, 128, 256, 512]:
x = layers.Conv2D(size, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
x = layers.Conv2D(size, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
x = layers.MaxPooling2D(3, strides=2, padding="same")(x)
residual = layers.Conv2D(size, 1, strides=2, padding="same")(
previous_block_activation
)
x = layers.add([x, residual]) # Add back residual
previous_block_activation = x
x = layers.Conv2D(1024, 3, padding="same")(x)
x = layers.BatchNormalization()(x)
x = layers.Activation("relu")(x)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(2, activation="softmax")(x)
model = keras.Model(inputs, outputs)
model.summary()
Model: "model_1"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_8 (InputLayer) [(None, 160, 160, 3 0 []
)]
rescaling_3 (Rescaling) (None, 160, 160, 3) 0 ['input_8[0][0]']
conv2d_35 (Conv2D) (None, 80, 80, 32) 896 ['rescaling_3[0][0]']
batch_normalization_18 (BatchN (None, 80, 80, 32) 128 ['conv2d_35[0][0]']
ormalization)
activation_18 (Activation) (None, 80, 80, 32) 0 ['batch_normalization_18[0][0]']
conv2d_36 (Conv2D) (None, 80, 80, 64) 18496 ['activation_18[0][0]']
batch_normalization_19 (BatchN (None, 80, 80, 64) 256 ['conv2d_36[0][0]']
ormalization)
activation_19 (Activation) (None, 80, 80, 64) 0 ['batch_normalization_19[0][0]']
conv2d_37 (Conv2D) (None, 80, 80, 64) 36928 ['activation_19[0][0]']
batch_normalization_20 (BatchN (None, 80, 80, 64) 256 ['conv2d_37[0][0]']
ormalization)
activation_20 (Activation) (None, 80, 80, 64) 0 ['batch_normalization_20[0][0]']
max_pooling2d_17 (MaxPooling2D (None, 40, 40, 64) 0 ['activation_20[0][0]']
)
conv2d_38 (Conv2D) (None, 40, 40, 64) 2112 ['activation_18[0][0]']
add_7 (Add) (None, 40, 40, 64) 0 ['max_pooling2d_17[0][0]',
'conv2d_38[0][0]']
conv2d_39 (Conv2D) (None, 40, 40, 128) 73856 ['add_7[0][0]']
batch_normalization_21 (BatchN (None, 40, 40, 128) 512 ['conv2d_39[0][0]']
ormalization)
activation_21 (Activation) (None, 40, 40, 128) 0 ['batch_normalization_21[0][0]']
conv2d_40 (Conv2D) (None, 40, 40, 128) 147584 ['activation_21[0][0]']
batch_normalization_22 (BatchN (None, 40, 40, 128) 512 ['conv2d_40[0][0]']
ormalization)
activation_22 (Activation) (None, 40, 40, 128) 0 ['batch_normalization_22[0][0]']
max_pooling2d_18 (MaxPooling2D (None, 20, 20, 128) 0 ['activation_22[0][0]']
)
conv2d_41 (Conv2D) (None, 20, 20, 128) 8320 ['add_7[0][0]']
add_8 (Add) (None, 20, 20, 128) 0 ['max_pooling2d_18[0][0]',
'conv2d_41[0][0]']
conv2d_42 (Conv2D) (None, 20, 20, 256) 295168 ['add_8[0][0]']
batch_normalization_23 (BatchN (None, 20, 20, 256) 1024 ['conv2d_42[0][0]']
ormalization)
activation_23 (Activation) (None, 20, 20, 256) 0 ['batch_normalization_23[0][0]']
conv2d_43 (Conv2D) (None, 20, 20, 256) 590080 ['activation_23[0][0]']
batch_normalization_24 (BatchN (None, 20, 20, 256) 1024 ['conv2d_43[0][0]']
ormalization)
activation_24 (Activation) (None, 20, 20, 256) 0 ['batch_normalization_24[0][0]']
max_pooling2d_19 (MaxPooling2D (None, 10, 10, 256) 0 ['activation_24[0][0]']
)
conv2d_44 (Conv2D) (None, 10, 10, 256) 33024 ['add_8[0][0]']
add_9 (Add) (None, 10, 10, 256) 0 ['max_pooling2d_19[0][0]',
'conv2d_44[0][0]']
conv2d_45 (Conv2D) (None, 10, 10, 512) 1180160 ['add_9[0][0]']
batch_normalization_25 (BatchN (None, 10, 10, 512) 2048 ['conv2d_45[0][0]']
ormalization)
activation_25 (Activation) (None, 10, 10, 512) 0 ['batch_normalization_25[0][0]']
conv2d_46 (Conv2D) (None, 10, 10, 512) 2359808 ['activation_25[0][0]']
batch_normalization_26 (BatchN (None, 10, 10, 512) 2048 ['conv2d_46[0][0]']
ormalization)
activation_26 (Activation) (None, 10, 10, 512) 0 ['batch_normalization_26[0][0]']
max_pooling2d_20 (MaxPooling2D (None, 5, 5, 512) 0 ['activation_26[0][0]']
)
conv2d_47 (Conv2D) (None, 5, 5, 512) 131584 ['add_9[0][0]']
add_10 (Add) (None, 5, 5, 512) 0 ['max_pooling2d_20[0][0]',
'conv2d_47[0][0]']
conv2d_48 (Conv2D) (None, 5, 5, 1024) 4719616 ['add_10[0][0]']
batch_normalization_27 (BatchN (None, 5, 5, 1024) 4096 ['conv2d_48[0][0]']
ormalization)
activation_27 (Activation) (None, 5, 5, 1024) 0 ['batch_normalization_27[0][0]']
global_average_pooling2d_1 (Gl (None, 1024) 0 ['activation_27[0][0]']
obalAveragePooling2D)
dropout_5 (Dropout) (None, 1024) 0 ['global_average_pooling2d_1[0][0
]']
dense_5 (Dense) (None, 2) 2050 ['dropout_5[0][0]']
==================================================================================================
Total params: 9,611,586
Trainable params: 9,605,634
Non-trainable params: 5,952
__________________________________________________________________________________________________
epochs = 20
model.compile(
optimizer=keras.optimizers.Adam(1e-3),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
model.fit(
train_ds,
epochs=epochs,
validation_data=val_ds,
)
Epoch 1/20
Corrupt JPEG data: 2226 extraneous bytes before marker 0xd9
71/138 [==============>...............] - ETA: 30s - loss: 0.8919 - accuracy: 0.5826
Corrupt JPEG data: 228 extraneous bytes before marker 0xd9
80/138 [================>.............] - ETA: 26s - loss: 0.8709 - accuracy: 0.5844
Warning: unknown JFIF revision number 0.00
99/138 [====================>.........] - ETA: 17s - loss: 0.8284 - accuracy: 0.5950
Corrupt JPEG data: 128 extraneous bytes before marker 0xd9
Corrupt JPEG data: 65 extraneous bytes before marker 0xd9
104/138 [=====================>........] - ETA: 15s - loss: 0.8211 - accuracy: 0.5969
Corrupt JPEG data: 396 extraneous bytes before marker 0xd9
106/138 [======================>.......] - ETA: 14s - loss: 0.8178 - accuracy: 0.5980
Corrupt JPEG data: 239 extraneous bytes before marker 0xd9
138/138 [==============================] - ETA: 0s - loss: 0.7849 - accuracy: 0.6080
Corrupt JPEG data: 252 extraneous bytes before marker 0xd9
Corrupt JPEG data: 1153 extraneous bytes before marker 0xd9
Corrupt JPEG data: 162 extraneous bytes before marker 0xd9
Corrupt JPEG data: 214 extraneous bytes before marker 0xd9
Corrupt JPEG data: 99 extraneous bytes before marker 0xd9
Corrupt JPEG data: 1403 extraneous bytes before marker 0xd9
138/138 [==============================] - 81s 507ms/step - loss: 0.7849 - accuracy: 0.6080 - val_loss: 1.0104 - val_accuracy: 0.4925
Epoch 2/20
···
137/138 [============================>.] - ETA: 0s - loss: 0.0418 - accuracy: 0.9854
Corrupt JPEG data: 252 extraneous bytes before marker 0xd9
Corrupt JPEG data: 1153 extraneous bytes before marker 0xd9
Corrupt JPEG data: 162 extraneous bytes before marker 0xd9
Corrupt JPEG data: 214 extraneous bytes before marker 0xd9
Corrupt JPEG data: 99 extraneous bytes before marker 0xd9
Corrupt JPEG data: 1403 extraneous bytes before marker 0xd9
138/138 [==============================] - 69s 493ms/step - loss: 0.0418 - accuracy: 0.9854 - val_loss: 0.1075 - val_accuracy: 0.9636
epochs = 10
model.compile(
optimizer=keras.optimizers.Adam(1e-5),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
model.fit(
train_ds,
epochs=epochs,
validation_data=val_ds,
)
img = keras.preprocessing.image.load_img(
"PetImages/Cat/6779.jpg", target_size=image_size
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create batch axis
predictions = model.predict(img_array)
score = predictions
print(f"This image is {100 * (1 - score):.2f}% cat and {100 * score:.2f}% dog.")
array([[0.9912566 , 0.00874343]], dtype=float32)