Computer Vision Lab Guide
Computer Vision Lab Guide
GREATER NOIDA-201306
(An Autonomous Institute)
1|Page
INDEX
2|Page
Program 1. Building a simple convolutional neural network for spam classification
# This Python 3 environment comes with many helpful analytics libraries installed
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input
directory
import os
print(os.listdir("../input"))
# Any results you write to the current directory are saved as output.
['spam.csv']
3|Page
x_raw = []
y_raw = []
909
0
60
tokenizer = Tokenizer()
tokenizer.fit_on_texts(x_raw)
sequences = tokenizer.texts_to_sequences(x_raw)
vocab_size = len(tokenizer.word_index)+1
print(vocab_size)
8734
# divide sum of length of all sequences by number of all sequences to find
averge length of each sequence
sum([len(x) for x in sequences]) // len(sequences)
14
pad = 'post'
max_len = 25
embedding_size = 100
batch_size = 20
sequences = pad_sequences(sequences, maxlen=max_len, padding=pad,
truncating=pad)
sequences.shape
LSTM MODEL
In [7]:
linkcode
model = Sequential()
model.add(Embedding(input_dim=vocab_size, output_dim=embedding_size,
input_length=max_len))
model.add(Dropout(0.8))
4|Page
model.add(LSTM(140, return_sequences=False))
model.add(Dropout(0.8))
model.add(Dense(1, activation='sigmoid', name='Classification'))
model.summary()
WARNING:tensorflow:From /opt/conda/lib/python3.6/site-
packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from
tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be
removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 -
keep_prob`.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 25, 100) 873400
_________________________________________________________________
dropout_1 (Dropout) (None, 25, 100) 0
_________________________________________________________________
lstm_1 (LSTM) (None, 140) 134960
_________________________________________________________________
dropout_2 (Dropout) (None, 140) 0
_________________________________________________________________
Classification (Dense) (None, 1) 141
=================================================================
Total params: 1,008,501
Trainable params: 1,008,501
Non-trainable params: 0
model.compile(optimizer='adam', loss='binary_crossentropy',
metrics=['accuracy'])
#save_best = ModelCheckpoint('SpamDetection.hdf', save_best_only=True,
monitor='val_acc', mode='max')
# callback_early_stopping = EarlyStopping(monitor='val_loss', patience=5,
verbose=1)
In [9]:
linkcode
# Uses Automatic Verification Datasets (fastest option)
# model.fit(X_train, y_train, epochs=n_epochs, batch_size=batch_size,
validation_split=0.1, callbacks=[callback_early_stopping])
n_epochs = 10
results = model.fit(X_train, y_train, epochs=n_epochs, batch_size=batch_size,
validation_split=0.2, verbose=1)
WARNING:tensorflow:From /opt/conda/lib/python3.6/site-
packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from
tensorflow.python.ops.math_ops) is deprecated and will be removed in a
future version.
Instructions for updating:
Use tf.cast instead.
Train on 3568 samples, validate on 892 samples
Epoch 1/10
5|Page
3568/3568 [==============================] - 10s 3ms/step - loss: 0.0347 -
acc: 0.9947 - val_loss: 3.0947e-07 - val_acc: 1.0000
Epoch 2/10
In [10]:
linkcode
# model.load_weights(filepath='SpamDetection.hdf')
eval_ = model.evaluate(X_test, y_test)
print(eval_[0], eval_[1]) # loss / accuracy
1115/1115 [==============================] - 0s 367us/step
1.0138004321915118e-07 1.0
In [11]:
def plot_model(result):
acc = result.history['acc']
val_acc = result.history['val_acc']
loss = result.history['loss']
val_loss = result.history['val_loss']
x = range(1, len(acc)+1)
plt.figure(figsize=(12, 5))
plt.subplot(1,2,1)
plt.plot(x, acc, 'b', label='Training acc')
6|Page
plt.plot(x, val_acc, 'r', label= 'Validation acc')
plt.legend()
plt.subplot(1,2,2)
plt.plot(x, loss, 'b', label='Training loss')
plt.plot(x, val_loss, 'r', label='validation loss')
plt.legend()
plot_model(results)
model1 = Sequential()
model1.add(Embedding(input_dim=vocab_size, output_dim=embedding_size,
input_length=max_len))
model1.add(Dropout(0.8))
model1.add(GRU(140, return_sequences=False))
model1.add(Dropout(0.86))
model1.add(Dense(1, activation='sigmoid', name='Classification'))
model1.summary()
model1.compile(optimizer='adam', loss='binary_crossentropy',
metrics=['accuracy'])
results1 = model1.fit(X_train, y_train, epochs=n_epochs,
batch_size=batch_size, validation_split=0.2)
plot_model(results1)
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_2 (Embedding) (None, 25, 100) 873400
_________________________________________________________________
dropout_3 (Dropout) (None, 25, 100) 0
_________________________________________________________________
gru_1 (GRU) (None, 140) 101220
7|Page
_________________________________________________________________
dropout_4 (Dropout) (None, 140) 0
_________________________________________________________________
Classification (Dense) (None, 1) 141
=================================================================
Total params: 974,761
Trainable params: 974,761
Non-trainable params: 0
_________________________________________________________________
Train on 3568 samples, validate on 892 samples
Epoch 1/10
3568/3568 [==============================] - 9s 3ms/step - loss: 0.0473 -
acc: 0.9891 - val_loss: 2.8143e-07 - val_acc: 1.0000
Epoch 2/10
3568/3568 [==============================] - 8s 2ms/step - loss: 5.6320e-05
- acc: 1.0000 - val_loss: 1.7271e-07 - val_acc: 1.0000
Epoch 3/10
3568/3568 [==============================] - 8s 2ms/step - loss: 3.3764e-05
- acc: 1.0000 - val_loss: 1.4434e-07 - val_acc: 1.0000
Epoch 4/10
3568/3568 [==============================] - 8s 2ms/step - loss: 3.0541e-05
- acc: 1.0000 - val_loss: 1.1887e-07 - val_acc: 1.0000
Epoch 5/10
3568/3568 [==============================] - 8s 2ms/step - loss: 2.4430e-05
- acc: 1.0000 - val_loss: 1.0496e-07 - val_acc: 1.0000
Epoch 6/10
3568/3568 [==============================] - 8s 2ms/step - loss: 2.6485e-05
- acc: 1.0000 - val_loss: 1.0443e-07 - val_acc: 1.0000
Epoch 7/10
3568/3568 [==============================] - 8s 2ms/step - loss: 2.8745e-05
- acc: 1.0000 - val_loss: 1.0069e-07 - val_acc: 1.0000
Epoch 8/10
3568/3568 [==============================] - 8s 2ms/step - loss: 1.5913e-05
- acc: 1.0000 - val_loss: 1.0045e-07 - val_acc: 1.0000
Epoch 9/10
3568/3568 [==============================] - 8s 2ms/step - loss: 1.7154e-05
- acc: 1.0000 - val_loss: 1.0037e-07 - val_acc: 1.0000
Epoch 10/10
3568/3568 [==============================] - 8s 2ms/step - loss: 1.5264e-05
- acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
1115/1115 [==============================] - 0s 335us/step
1.0000002248489182e-07 1.0
8|Page
Program 2. Building a simple convolutional neural network for image classification
# Import TensorFlow
import tensorflow as tf
plt.figure(figsize=(8,8))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i])
# The CIFAR labels happen to be arrays,
#which is why we need the extra index
plt.xlabel(class_names[train_labels[i][0]])
plt.show()
9|Page
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32,
3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 64) 36928
=================================================================
Total params: 56,320
Trainable params: 56,320
Non-trainable params: 0
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 64) 36928
_________________________________________________________________
flatten (Flatten) (None, 1024) 0
_________________________________________________________________
dense (Dense) (None, 64) 65600
_________________________________________________________________
dense_1 (Dense) (None, 10) 650
=================================================================
Total params: 122,570
Trainable params: 122,570
10 | P a g e
Non-trainable params: 0
_________________________________________________________________
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
11 | P a g e
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
12 | P a g e
Program 3. Implementing different types of pooling layers and comparing their effects on
network performance
binder.bind(globals())
import numpy as np
import tensorflow as tf
plt.rc('figure', autolayout=True)
plt.rc('image', cmap='magma')
# Read image
image_path = '../input/computer-vision-resources/car_illus.jpg'
image = tf.io.read_file(image_path)
image = tf.io.decode_jpeg(image, channels=1)
image = tf.image.resize(image, size=[400, 400])
# Embossing kernel
kernel = tf.constant([
[-2, -1, 0],
[-1, 1, 1],
[0, 1, 2],
])
image_filter = tf.nn.conv2d(
input=image,
filters=kernel,
strides=1,
padding='VALID')
image_detect = tf.nn.relu(image_filter)
13 | P a g e
# Show what we have so far
plt.figure(figsize=(12, 6))
plt.subplot(131)
plt.imshow(tf.squeeze(image), cmap='gray')
plt.axis('off')
plt.title('Input')
plt.subplot(132)
plt.imshow(tf.squeeze(image_filter))
plt.axis('off')
plt.title('Filter')
plt.subplot(133)
plt.imshow(tf.squeeze(image_detect))
plt.axis('off')
plt.title('Detect')
plt.show();
strides=(2, 2),
padding='SAME',
)
14 | P a g e
plt.axis('off')
plt.title("Condense (MaxPool)")
plt.show();
REPEATS = 4
image = tf.squeeze(image)
plt.figure(figsize=(16, 4))
plt.subplot(1, REPEATS+1, 1)
plt.axis('off')
for i in range(REPEATS):
15 | P a g e
image = tf.reshape(image, [1, *image.shape, 1])
image = tf.squeeze(image)
plt.axis('off')
q_2.solution()
plt.figure(figsize=(18, 2))
plt.subplot(gs[i])
plt.axis('off')
plt.show()
16 | P a g e
feature_maps_tf = [tf.reshape(feature_map, [1, *feature_map.shape, 1])
global_avg_pool = tf.keras.layers.GlobalAvgPool2D()
img = np.array(pooled_maps)[:,:,0].T
plt.axis('off')
plt.show();
# Load VGG16
pretrained_base = tf.keras.models.load_model(
'../input/cv-course-models/cv-course-models/vgg16-pretrained-base',
)
model = keras.Sequential([
pretrained_base,
# Attach a global average pooling layer after the base
layers.GlobalAvgPool2D(),
])
# Load dataset
ds = image_dataset_from_directory(
'../input/car-or-truck/train',
labels='inferred',
label_mode='binary',
image_size=[128, 128],
interpolation='nearest',
batch_size=1,
shuffle=True,
)
17 | P a g e
ds_iter = iter(ds)
car = next(ds_iter)
plt.figure(figsize=(8, 4))
plt.subplot(121)
plt.imshow(tf.squeeze(car[0]))
plt.axis('off')
plt.title(["Car", "Truck"][label])
plt.subplot(122)
plt.imshow(car_features)
plt.title('Pooled Feature Maps')
plt.axis('off')
plt.show();
18 | P a g e
Program 4. Training a CNN model on a large-scale image classification dataset using cloud-
based GPU acceleration.
You'll need to choose a cloud platform (e.g., AWS, Google Cloud, Azure) and provision a GPU-
accelerated instance. Here, we'll assume you're using Google Colab for simplicity, but the process is
similar on other platforms:
Set the runtime type to "GPU" by going to Runtime -> Change runtime type.
train_datagen = ImageDataGenerator(
rescale=1.0/255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
train_generator = train_datagen.flow_from_directory(
'path_to_train_data',
target_size=(224, 224),
batch_size=32,
class_mode='categorical'
)
Step 3: Build the CNN Model
Define your CNN model using a deep learning framework like TensorFlow or PyTorch. Below is an
example using TensorFlow and the Keras API:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
MaxPooling2D((2, 2)),
Conv2D(64, (3, 3), activation='relu'),
MaxPooling2D((2, 2)),
19 | P a g e
Conv2D(128, (3, 3), activation='relu'),
MaxPooling2D((2, 2)),
Flatten(),
Dense(512, activation='relu'),
Dropout(0.5),
Dense(num_classes, activation='softmax')
])
Compile the model with a suitable optimizer and loss function and then train it on your data:
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(
train_generator,
epochs=10, # Adjust as needed
steps_per_epoch=len(train_generator),
verbose=1
)
model.save('my_model.h5')
20 | P a g e
OUTPUT
21 | P a g e
8 1.094560 1.054756 0.897006 01:29
9 0.889135 1.874039 0.889522 01:30
10 0.922833 0.993172 0.873129 01:30
11 1.075472 0.505854 0.904847 01:30
12 0.880544 1.152409 0.903421 01:29
13 0.948685 0.579885 0.908767 01:29
14 0.899647 4.366896 0.711689 01:30
15 1.108699 1.961280 0.892374 01:28
16 0.901288 0.625867 0.907698 01:29
17 0.689079 3.617636 0.872416 01:30
18 0.530735 0.456810 0.907341 01:28
19 0.805070 0.463680 0.915538 01:30
20 0.774058 0.893849 0.915895 01:31
21 0.581867 0.590447 0.906272 01:31
22 0.486774 0.639138 0.922666 01:30
23 0.482500 0.359934 0.919815 01:30
24 0.449640 21.844734 0.829294 01:30
25 0.326962 0.478932 0.924448 01:29
26 0.301796 0.600344 0.915182 01:29
27 0.270193 0.612086 0.913756 01:29
28 0.298829 0.291706 0.926230 01:29
29 0.233580 0.258509 0.920884 01:29
30 0.228145 0.269283 0.926230 01:29
31 0.212270 0.298909 0.927299 01:29
32 0.179242 0.326935 0.927655 01:29
33 0.185605 0.218010 0.931219 01:28
34 0.179383 0.349236 0.928724 01:28
35 0.166706 0.221297 0.934783 01:29
36 0.163385 0.212441 0.933001 01:29
37 0.141837 0.209331 0.934783 01:29
38 0.155481 0.211586 0.934426 01:29
39 0.151176 0.230446 0.933713 01:29
Hyper Parameter
22 | P a g e
epoch train_loss valid_loss accuracy time
23 | P a g e
Training Loss
epoch train_loss valid_loss accuracy time
Confusion Matrix
24 | P a g e
Program 5. Building a simple convolutional neural network for Cats-v-dogs classification
import numpy as np
import pandas as pd
from keras.preprocessing.image import ImageDataGenerator, load_img
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import random
import os
print(os.listdir("../input"))
['train', 'test1', 'sampleSubmission.csv']
Define Constants
FAST_RUN = False
IMAGE_WIDTH=128
IMAGE_HEIGHT=128
IMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)
IMAGE_CHANNELS=3
filenames = os.listdir("../input/train/train")
categories = []
for filename in filenames:
category = filename.split('.')[0]
if category == 'dog':
categories.append(1)
else:
categories.append(0)
df = pd.DataFrame({
'filename': filenames,
'category': categories
})
df.head()
filename category
0 cat.8572.jpg 0
1 dog.11754.jpg 1
2 cat.3314.jpg 0
3 dog.11723.jpg 1
4 dog.4602.jpg 1
df.tail()
25 | P a g e
category
filename
24995 cat.9040.jpg 0
24996 dog.5406.jpg 1
24997 cat.6371.jpg 0
24998 dog.2213.jpg 1
24999 cat.10115.jpg 0
sample = random.choice(filenames)
image = load_img("../input/train/train/"+sample)
plt.imshow(image)
26 | P a g e
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation,
BatchNormalization
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH,
IMAGE_HEIGHT, IMAGE_CHANNELS)))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax')) # 2 because we have cat and dog classes
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.summary()
27 | P a g e
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 -
keep_prob`.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 126, 126, 32) 896
_________________________________________________________________
batch_normalization_1 (Batch (None, 126, 126, 32) 128
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 63, 63, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 63, 63, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 61, 61, 64) 18496
_________________________________________________________________
batch_normalization_2 (Batch (None, 61, 61, 64) 256
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 30, 30, 64) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 30, 30, 64) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 28, 28, 128) 73856
_________________________________________________________________
batch_normalization_3 (Batch (None, 28, 28, 128) 512
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 14, 14, 128) 0
_________________________________________________________________
dropout_3 (Dropout) (None, 14, 14, 128) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 25088) 0
_________________________________________________________________
dense_1 (Dense) (None, 512) 12845568
_________________________________________________________________
batch_normalization_4 (Batch (None, 512) 2048
_________________________________________________________________
dropout_4 (Dropout) (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 2) 1026
=================================================================
Total params: 12,942,786
Trainable params: 12,941,314
Non-trainable params: 1,472
_________________________________________________________________
Callbacks
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
earlystop = EarlyStopping(patience=10)
Learning Rate Reduction
28 | P a g e
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc',
patience=2,
verbose=1,
factor=0.5, min_lr=0.00001)
callbacks = [earlystop, learning_rate_reduction]
Prepare data
total_train = train_df.shape[0]
total_validate = validate_df.shape[0]
29 | P a g e
batch_size=15
Traning Generator
train_datagen = ImageDataGenerator(
rotation_range=15,
rescale=1./255,
shear_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
width_shift_range=0.1,
height_shift_range=0.1
)
train_generator = train_datagen.flow_from_dataframe(
train_df,
"../input/train/train/",
x_col='filename',
y_col='category',
target_size=IMAGE_SIZE,
class_mode='categorical',
batch_size=batch_size
)
validation_datagen = ImageDataGenerator(rescale=1./255)
validation_generator = validation_datagen.flow_from_dataframe(
validate_df,
"../input/train/train/",
x_col='filename',
y_col='category',
target_size=IMAGE_SIZE,
class_mode='categorical',
batch_size=batch_size
)
example_df = train_df.sample(n=1).reset_index(drop=True)
example_generator = train_datagen.flow_from_dataframe(
example_df,
"../input/train/train/",
x_col='filename',
y_col='category',
target_size=IMAGE_SIZE,
class_mode='categorical'
)
plt.figure(figsize=(12, 12))
for i in range(0, 15):
30 | P a g e
plt.subplot(5, 3, i+1)
for X_batch, Y_batch in example_generator:
image = X_batch[0]
plt.imshow(image)
break
plt.tight_layout()
plt.show()
Fit Model
epochs=3 if FAST_RUN else 50
history = model.fit_generator(
train_generator,
31 | P a g e
epochs=epochs,
validation_data=validation_generator,
validation_steps=total_validate//batch_size,
steps_per_epoch=total_train//batch_size,
callbacks=callbacks
)
Epoch 1/50
Save Model
model.save_weights("model.h5")
Virtualize Training
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))
ax1.plot(history.history['loss'], color='b', label="Training loss")
ax1.plot(history.history['val_loss'], color='r', label="validation loss")
ax1.set_xticks(np.arange(1, epochs, 1))
32 | P a g e
ax1.set_yticks(np.arange(0, 1, 0.1))
33 | P a g e
Prepare Testing Data
test_filenames = os.listdir("../input/test1/test1")
test_df = pd.DataFrame({
'filename': test_filenames
})
nb_samples = test_df.shape[0]
Predict
predict = model.predict_generator(test_generator,
steps=np.ceil(nb_samples/batch_size))
34 | P a g e
sample_test = test_df.head(18)
sample_test.head()
plt.figure(figsize=(12, 24))
35 | P a g e
Program 6. Fine-tuning a pre-trained CNN for a specific image recognition task
Fine-tuning a pre-trained Convolutional Neural Network (CNN) for a specific image recognition
task is a common practice in deep learning. This process allows you to leverage the knowledge
learned by a pre-trained model on a large dataset and adapt it to your specific task, which often
requires a smaller dataset.
# import stuff
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import seaborn as sns
from PIL import Image
from IPython.display import Image, display
import os
from sklearn.metrics import confusion_matrix
from sklearn.datasets import load_files
from sklearn.model_selection import train_test_split
import tensorflow_hub as hub
from keras.utils import to_categorical
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from tensorflow.keras.optimizers import Adam, RMSprop, SGD
from tensorflow.keras.applications import ResNet50, VGG16, VGG19, MobileNetV2
from tensorflow.keras.applications.resnet50 import preprocess_input as prepro_res50
from tensorflow.keras.applications.vgg19 import preprocess_input as prepro_vgg19
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Dense, Flatten, GlobalAveragePooling2D,
BatchNormalization, Dropout, MaxPool2D, MaxPooling2D
# Let's implement it
input_shape = (224, 224, 3)
36 | P a g e
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(128, (3, 3), activation='relu', padding='same'),
Conv2D(128, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Flatten(), # Convert 3D matrices
into 1D vector
Dense(4096, activation='relu'), # Add Fully-connected
layers
Dense(4096, activation='relu'),
Dense(1000, activation='softmax') # Final Fully-
connected layer for predictions
])
my_VGG16.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
conv2d_1 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
conv2d_3 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 56, 56, 128) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
conv2d_5 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
conv2d_6 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 28, 28, 256) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
37 | P a g e
conv2d_8 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
conv2d_9 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 14, 14, 512) 0
_________________________________________________________________
conv2d_10 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
conv2d_11 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
conv2d_12 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
dense (Dense) (None, 4096) 102764544
_________________________________________________________________
dense_1 (Dense) (None, 4096) 16781312
_________________________________________________________________
dense_2 (Dense) (None, 1000) 4097000
=================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
_________________________________________________________________
38 | P a g e
Load & explore data
path_data = '../input/flowers-recognition/flowers/flowers/'
print(os.listdir(path_data))
['../input/flowers-recognition/flowers/flowers/tulip',
'../input/flowers-recognition/flowers/flowers/daisy',
'../input/flowers-recognition/flowers/flowers/rose',
'../input/flowers-recognition/flowers/flowers/dandelion',
'../input/flowers-recognition/flowers/flowers/sunflower']
data_dir = '../input/flowers-recognition/flowers/flowers/'
39 | P a g e
# remove eventual .pyc or .py files
(4323, 1)
species
0 3
1 0
2 1
3 4
4 4
# associate names to species number
df['flower'] = df['species'].astype('category')
df['flower'].cat.categories = labels
40 | P a g e
df.head()
flower
species
0 3 sunflower
1 0 daisy
2 1 dandelion
3 4 tulip
4 4 tulip
fig, ax = plt.subplots()
ax = sns.countplot(x="flower", data=df)
ax.set(ylabel='Count', title='Flower species distribution')
ax.tick_params(axis='x', rotation=15)
image_size = 224 # standard value for Transfer learning usecase (MobileNet, ResNet50, VGG16,
VGG19)
X = np.array(read_and_prep_images(X))
print(X.shape) # (4323, 224, 224, 3) = (num_images, height_size, width_size, depth=RGB)
41 | P a g e
# Let's have a look at 6 randomly picked flowers.
In [13]:
linkcode
N = 18 # flowers to display
fig, axes = plt.subplots(3, 6, figsize=(16,6))
for ax, j in zip(axes.flat, np.random.randint(0, len(X), N)):
ax.imshow(X[j].astype(np.uint8))
ax.set(title=f'Flower: {labels[y[j]]}', xticks=[], yticks=[])
fig.tight_layout()
Label encoding
num_classes = len(np.unique(y))
print(f'Number of classes: {num_classes} --> {labels}')
y = to_categorical(y, num_classes)
print(y.shape)
(4323, 5)
42 | P a g e
Xval, Xtest, yval, ytest = train_test_split(Xtest, ytest, test_size=0.5,
shuffle=True, random_state=28)
print(f'Train dataset: {Xtrain.shape[0]}')
print(f'Validation dataset: {Xval.shape[0]}')
print(f'Test dataset: {Xtest.shape[0]}')
base_model.trainable = False
#base_model.summary()
base_model.output_shape
(None, 7, 7, 1280)
model = Sequential([base_model,
GlobalAveragePooling2D(),
Dense(num_classes, activation='softmax')
])
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
mobilenetv2_1.00_224 (Model) (None, 7, 7, 1280) 2257984
_________________________________________________________________
global_average_pooling2d (Gl (None, 1280) 0
43 | P a g e
_________________________________________________________________
dense_3 (Dense) (None, 5) 6405
=================================================================
# Optimizer
opt = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
# Compilation
model.compile(optimizer=opt,
loss='categorical_crossentropy',
metrics=['accuracy'])
Data augmentation
image_size = 224
batch_size = 32
path = '../input/flowers-recognition/flowers/flowers/'
train_datagen = ImageDataGenerator(
rescale=1./255, # rescale pixel values [0,255] to [0,1]
horizontal_flip=True, # random horizontal flip
width_shift_range=0.2, # random shift images horizontally (fraction of
total width)
44 | P a g e
height_shift_range=0.2, # random shift images vertically (fraction of
total height)
test_datagen = ImageDataGenerator(
rescale=1./255)
#validation_split=0.2)
train_gen = train_datagen.flow(
Xtrain, ytrain,
batch_size=batch_size,
shuffle=False) # already applied
valid_gen = test_datagen.flow(
Xval, yval,
batch_size=batch_size,
shuffle=False)
Feature extraction
batch_size = 32
epochs_0 = 40
steps_per_epoch = len(train_gen.x) // train_gen.batch_size
validation_steps = len(valid_gen.x) // valid_gen.batch_size
history = model.fit(
train_gen,
steps_per_epoch=len(Xtrain) // batch_size, # or batch_size=32
epochs=epochs_0 ,
validation_data=valid_gen,
validation_steps=len(Xval) // batch_size,
callbacks=callbacks)
45 | P a g e
101/101 [==============================] - 36s 358ms/step - loss: 0.5385 -
accuracy: 0.8044 - val_loss: 0.7646 - val_accuracy: 0.7109
Epoch 3/40
100/101 [============================>.] - ETA: 0s - loss: 0.4721 -
accuracy: 0.8357
Epoch 00003: val_accuracy improved from 0.75195 to 0.79492, saving model to
flower_best_weights.hdf5
101/101 [==============================] - 37s 363ms/step - loss: 0.4719 -
accuracy: 0.8361 - val_loss: 0.5152 - val_accuracy: 0.7949
Epoch 4/40
100/101 [============================>.] - ETA: 0s - loss: 0.4363 -
accuracy: 0.8531
Epoch 00004: val_accuracy did not improve from 0.79492
101/101 [==============================] - 36s 356ms/step - loss: 0.4339 -
accuracy: 0.8539 - val_loss: 0.6437 - val_accuracy: 0.7461
Epoch 5/40
100/101 [============================>.] - ETA: 0s - loss: 0.4123 -
accuracy: 0.8540
Epoch 00005: val_accuracy did not improve from 0.79492
101/101 [==============================] - 37s 364ms/step - loss: 0.4111 -
accuracy: 0.8542 - val_loss: 0.5558 - val_accuracy: 0.7832
Epoch 6/40
100/101 [============================>.] - ETA: 0s - loss: 0.3909 -
accuracy: 0.8656
Epoch 00006: val_accuracy did not improve from 0.79492
46 | P a g e
Epoch 00010: val_accuracy did not improve from 0.79883
Epoch 00010: ReduceLROnPlateau reducing learning rate to
0.0004900000232737511.
101/101 [==============================] - 37s 371ms/step - loss: 0.3367 -
accuracy: 0.8875 - val_loss: 0.5881 - val_accuracy: 0.7734
Epoch 11/40
100/101 [============================>.] - ETA: 0s - loss: 0.3310 -
accuracy: 0.8861
Epoch 00011: val_accuracy did not improve from 0.79883
101/101 [==============================] - 35s 349ms/step - loss: 0.3302 -
accuracy: 0.8863 - val_loss: 0.5418 - val_accuracy: 0.7910
Epoch 12/40
100/101 [============================>.] - ETA: 0s - loss: 0.3198 -
accuracy: 0.8902
Epoch 00012: val_accuracy did not improve from 0.79883
101/101 [==============================] - 37s 361ms/step - loss: 0.3222 -
accuracy: 0.8891 - val_loss: 0.5605 - val_accuracy: 0.7930
Epoch 13/40
100/101 [============================>.] - ETA: 0s - loss: 0.3161 -
accuracy: 0.8949
Epoch 00013: val_accuracy did not improve from 0.79883
47 | P a g e
Epoch 18/40
48 | P a g e
100/101 [============================>.] - ETA: 0s - loss: 0.2799 -
accuracy: 0.9012
Epoch 00025: val_accuracy did not improve from 0.81641
49 | P a g e
101/101 [==============================] - 36s 361ms/step - loss: 0.2690 -
accuracy: 0.9034 - val_loss: 0.5001 - val_accuracy: 0.8066
Epoch 33/40
50 | P a g e
101/101 [==============================] - 36s 360ms/step - loss: 0.2611 -
accuracy: 0.9115 - val_loss: 0.5215 - val_accuracy: 0.8066
Epoch 40/40
plot_history(history, loss_max=1)
51 | P a g e
datagen = ImageDataGenerator(
rescale=1./255)
eval_datagen = datagen.flow(
Xtest, ytest,
batch_size=batch_size,
shuffle=False) # since shuffle was already during splitting into train, valid, test
# Evaluation on the test dataset
loss, acc = model.evaluate_generator(eval_datagen, verbose=0)
print(f'Test loss: {loss:.2f}')
print(f'Test accuracy: {acc*100:.2f}%')
Fine tuning
base_model.trainable = True
# Let's take a look to see how many layers are in the base model
print(f'Number of layers in the base model: {len(base_model.layers)}')
Number of layers in the base model: 155
# Fine-tune from this layer onwards
fine_tuning = 100
# Compilation
model.compile(optimizer=opt,
loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
mobilenetv2_1.00_224 (Model) (None, 7, 7, 1280) 2257984
_________________________________________________________________
global_average_pooling2d (Gl (None, 1280) 0
_________________________________________________________________
dense_3 (Dense) (None, 5) 6405
=================================================================
Total params: 2,264,389
Trainable params: 1,868,997
Non-trainable params: 395,392
52 | P a g e
_________________________________________________________________
fine_tuned_epochs = 40
53 | P a g e
100/101 [============================>.] - ETA: 0s - loss: 0.0295 -
accuracy: 0.9921
Epoch 00045: val_accuracy did not improve from 0.86328
101/101 [==============================] - 37s 363ms/step - loss: 0.0300 -
accuracy: 0.9919 - val_loss: 0.6663 - val_accuracy: 0.8359
Epoch 46/80
54 | P a g e
101/101 [==============================] - 37s 368ms/step - loss: 0.0042 -
accuracy: 0.9991 - val_loss: 0.5849 - val_accuracy: 0.8828
Epoch 53/80
100/101 [============================>.] - ETA: 0s - loss: 0.0041 -
accuracy: 0.9987
Epoch 00053: val_accuracy did not improve from 0.88281
101/101 [==============================] - 38s 374ms/step - loss: 0.0040 -
accuracy: 0.9988 - val_loss: 0.6574 - val_accuracy: 0.8770
Epoch 54/80
100/101 [============================>.] - ETA: 0s - loss: 0.0025 -
accuracy: 0.9997
Epoch 00054: val_accuracy improved from 0.88281 to 0.88477, saving model to
flower_best_weights.hdf5
101/101 [==============================] - 37s 361ms/step - loss: 0.0025 -
accuracy: 0.9997 - val_loss: 0.5772 - val_accuracy: 0.8848
Epoch 55/80
100/101 [============================>.] - ETA: 0s - loss: 0.0046 -
accuracy: 0.9987
Epoch 00055: val_accuracy did not improve from 0.88477
101/101 [==============================] - 36s 361ms/step - loss: 0.0045 -
accuracy: 0.9988 - val_loss: 0.6961 - val_accuracy: 0.8750
Epoch 56/80
100/101 [============================>.] - ETA: 0s - loss: 0.0027 -
accuracy: 0.9994
Epoch 00056: val_accuracy did not improve from 0.88477
101/101 [==============================] - 35s 351ms/step - loss: 0.0027 -
accuracy: 0.9994 - val_loss: 0.6988 - val_accuracy: 0.8789
Epoch 57/80
100/101 [============================>.] - ETA: 0s - loss: 0.0029 -
accuracy: 0.9997
Epoch 00057: val_accuracy did not improve from 0.88477
Epoch 00057: ReduceLROnPlateau reducing learning rate to 2.400999692326877e-
05.
101/101 [==============================] - 37s 362ms/step - loss: 0.0029 -
accuracy: 0.9997 - val_loss: 0.7334 - val_accuracy: 0.8711
Epoch 58/80
100/101 [============================>.] - ETA: 0s - loss: 0.0021 -
accuracy: 0.9997
Epoch 00058: val_accuracy improved from 0.88477 to 0.89062, saving model to
flower_best_weights.hdf5
101/101 [==============================] - 36s 361ms/step - loss: 0.0020 -
accuracy: 0.9997 - val_loss: 0.6130 - val_accuracy: 0.8906
Epoch 59/80
100/101 [============================>.] - ETA: 0s - loss: 0.0018 -
accuracy: 0.9997
Epoch 00059: val_accuracy improved from 0.89062 to 0.89258, saving model to
flower_best_weights.hdf5
101/101 [==============================] - 36s 354ms/step - loss: 0.0018 -
accuracy: 0.9997 - val_loss: 0.6082 - val_accuracy: 0.8926
Epoch 60/80
55 | P a g e
100/101 [============================>.] - ETA: 0s - loss: 0.0017 -
accuracy: 0.9994
Epoch 00060: val_accuracy did not improve from 0.89258
101/101 [==============================] - 37s 361ms/step - loss: 0.0018 -
accuracy: 0.9994 - val_loss: 0.6781 - val_accuracy: 0.8730
Epoch 61/80
100/101 [============================>.] - ETA: 0s - loss: 0.0029 -
accuracy: 0.9991
Epoch 00061: val_accuracy did not improve from 0.89258
101/101 [==============================] - 36s 358ms/step - loss: 0.0029 -
accuracy: 0.9991 - val_loss: 0.7306 - val_accuracy: 0.8711
Epoch 62/80
100/101 [============================>.] - ETA: 0s - loss: 0.0021 -
accuracy: 0.9994
Epoch 00062: val_accuracy did not improve from 0.89258
Epoch 00062: ReduceLROnPlateau reducing learning rate to
1.6806997336971108e-05.
101/101 [==============================] - 36s 355ms/step - loss: 0.0021 -
accuracy: 0.9994 - val_loss: 0.6980 - val_accuracy: 0.8730
Epoch 63/80
100/101 [============================>.] - ETA: 0s - loss: 0.0020 -
accuracy: 0.9994
Epoch 00063: val_accuracy did not improve from 0.89258
101/101 [==============================] - 37s 367ms/step - loss: 0.0020 -
accuracy: 0.9994 - val_loss: 0.6438 - val_accuracy: 0.8809
Epoch 64/80
100/101 [============================>.] - ETA: 0s - loss: 0.0012 -
accuracy: 1.0000
Epoch 00064: val_accuracy did not improve from 0.89258
101/101 [==============================] - 35s 348ms/step - loss: 0.0012 -
accuracy: 1.0000 - val_loss: 0.6148 - val_accuracy: 0.8809
Epoch 65/80
100/101 [============================>.] - ETA: 0s - loss: 7.6357e-04 -
accuracy: 1.0000
Epoch 00065: val_accuracy did not improve from 0.89258
Epoch 00065: ReduceLROnPlateau reducing learning rate to
1.1764897499233484e-05.
101/101 [==============================] - 36s 355ms/step - loss: 7.5680e-04
- accuracy: 1.0000 - val_loss: 0.6370 - val_accuracy: 0.8828
Epoch 66/80
100/101 [============================>.] - ETA: 0s - loss: 6.3722e-04 -
accuracy: 1.0000
Epoch 00066: val_accuracy did not improve from 0.89258
101/101 [==============================] - 36s 357ms/step - loss: 6.3511e-04
- accuracy: 1.0000 - val_loss: 0.5862 - val_accuracy: 0.8887
Epoch 67/80
100/101 [============================>.] - ETA: 0s - loss: 8.4205e-04 -
accuracy: 1.0000
Epoch 00067: val_accuracy did not improve from 0.89258
101/101 [==============================] - 36s 358ms/step - loss: 8.4151e-04
- accuracy: 1.0000 - val_loss: 0.5716 - val_accuracy: 0.8828
56 | P a g e
Epoch 68/80
100/101 [============================>.] - ETA: 0s - loss: 0.0016 -
accuracy: 0.9994
Epoch 00068: val_accuracy did not improve from 0.89258
Epoch 00068: ReduceLROnPlateau reducing learning rate to 1e-05.
101/101 [==============================] - 36s 358ms/step - loss: 0.0016 -
accuracy: 0.9994 - val_loss: 0.5808 - val_accuracy: 0.8848
Epoch 69/80
100/101 [============================>.] - ETA: 0s - loss: 0.0015 -
accuracy: 0.9994
Epoch 00069: val_accuracy improved from 0.89258 to 0.89453, saving model to
flower_best_weights.hdf5
57 | P a g e
101/101 [==============================] - 37s 367ms/step - loss: 5.4117e-04
- accuracy: 1.0000 - val_loss: 0.5313 - val_accuracy: 0.9004
Epoch 76/80
100/101 [============================>.] - ETA: 0s - loss: 0.0011 -
accuracy: 0.9997
Epoch 00076: val_accuracy did not improve from 0.90430
101/101 [==============================] - 37s 364ms/step - loss: 0.0011 -
accuracy: 0.9997 - val_loss: 0.5502 - val_accuracy: 0.8965
Epoch 77/80
100/101 [============================>.] - ETA: 0s - loss: 7.7876e-04 -
accuracy: 1.0000
Epoch 00077: val_accuracy did not improve from 0.90430
101/101 [==============================] - 37s 367ms/step - loss: 7.7230e-04
- accuracy: 1.0000 - val_loss: 0.5353 - val_accuracy: 0.9004
Epoch 78/80
100/101 [============================>.] - ETA: 0s - loss: 5.9856e-04 -
accuracy: 1.0000
Epoch 00078: val_accuracy did not improve from 0.90430
101/101 [==============================] - 36s 356ms/step - loss: 5.9405e-04
- accuracy: 1.0000 - val_loss: 0.5443 - val_accuracy: 0.9004
Epoch 79/80
100/101 [============================>.] - ETA: 0s - loss: 3.5312e-04 -
accuracy: 1.0000
Epoch 00079: val_accuracy did not improve from 0.90430
101/101 [==============================] - 35s 351ms/step - loss: 3.5570e-04
- accuracy: 1.0000 - val_loss: 0.5413 - val_accuracy: 0.9023
Epoch 80/80
100/101 [============================>.] - ETA: 0s - loss: 8.2249e-04 -
accuracy: 0.9997
Epoch 00080: val_accuracy did not improve from 0.90430
101/101 [==============================] - 37s 366ms/step - loss: 8.1458e-04
- accuracy: 0.9997 - val_loss: 0.5577 - val_accuracy: 0.8984
58 | P a g e
ax1.plot(acc, label='Training')
ax1.plot(val_acc, label='Validation')
ax1.plot([initial_epochs-1,initial_epochs-1],
plt.ylim(), label='fine-tuning', ls='--')
ax1.legend(loc='lower right')
ax1.set(ylabel='Accuracy', title='Training - Validation Accuracy',
ylim=([0.4,1.005]))
ax2.plot(loss, label='Training')
ax2.plot(val_loss, label='Validation')
ax2.plot([initial_epochs-1,initial_epochs-1],
[0,1] , label='fine-tuning', ls='--')
ax2.legend(loc='upper right')
Confusion matrix
import seaborn as sns
from sklearn import metrics
pred = model.predict(eval_datagen, verbose=1)
# get most likely class
y_pred = pred.argmax(axis=1)
y_true = ytest.argmax(axis=1)
print(metrics.classification_report(y_true, y_pred))
# confusion matrix
mat = metrics.confusion_matrix(y_true, y_pred)
df_mat = pd.DataFrame(mat, index=labels, columns=labels)
plt.figure(figsize=(8,6))
59 | P a g e
sns.heatmap(df_mat, annot=True, fmt='d', cmap=plt.cm.Reds)
#plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
17/17 [==============================] - 1s 76ms/step
precision recall f1-score support
Prediction vizualisations
N = 20 # flowers to display
fig, axes = plt.subplots(4, 5, figsize=(20,12))
for i, ax in enumerate(axes.flat):
ax.imshow(Xtest[i].astype(np.uint8))
ax.set(xticks=[], yticks=[])
true = y_true[i]
prediction = y_pred[i]
ax.set_xlabel(f'Predict: {labels[prediction]}\n True: {labels[true]}',
60 | P a g e
color='black' if true == prediction else 'red')
#fig.tight_layout()
fig.suptitle('Predicted flowers; Incorrect Labels in Red', size=14)
61 | P a g e
Program 7. Building a simple convolutional neural network for transfer learning using
finetuning.
1. Feature Extraction: Use the representations learned by a previous network to extract meaningful
features from new samples. You simply add a new classifier, which will be trained from scratch,
on top of the pretrained model so that you can repurpose the feature maps learned previously
for the dataset.
You do not need to (re)train the entire model. The base convolutional network already contains
features that are generically useful for classifying pictures. However, the final, classification part
of the pretrained model is specific to the original classification task, and subsequently specific to
the set of classes on which the model was trained.
2. Fine-Tuning: Unfreeze a few of the top layers of a frozen model base and jointly train both the
newly-added classifier layers and the last layers of the base model. This allows us to "fine-tune"
the higher-order feature representations in the base model in order to make them more relevant
for the specific task.
Data preprocessing
_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
BATCH_SIZE = 32
IMG_SIZE = (160, 160)
train_dataset = tf.keras.utils.image_dataset_from_directory(train_dir,
shuffle=True,
batch_size=BATCH_SIZE,
image_size=IMG_SIZE)
62 | P a g e
Found 2000 files belonging to 2 classes.
validation_dataset = tf.keras.utils.image_dataset_from_directory(validation_dir,
shuffle=True,
batch_size=BATCH_SIZE,
image_size=IMG_SIZE)
class_names = train_dataset.class_names
plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
63 | P a g e
val_batches = tf.data.experimental.cardinality(validation_dataset)
test_dataset = validation_dataset.take(val_batches // 5)
validation_dataset = validation_dataset.skip(val_batches // 5)
print('Number of validation batches: %d' % tf.data.experimental.cardinality(validation_dataset))
print('Number of test batches: %d' % tf.data.experimental.cardinality(test_dataset))
AUTOTUNE = tf.data.AUTOTUNE
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
validation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE)
test_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE)
64 | P a g e
preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input
rescale = tf.keras.layers.Rescaling(1./127.5, offset=-1)
Create the base model from the pre-trained convnets
# Create the base model from the pre-trained model MobileNet V2
IMG_SHAPE = IMG_SIZE + (3,)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
include_top=False,
weights='imagenet')
(32, 5, 5, 1280)
Feature extraction
base_model.trainable = False
# Let's take a look at the base model architecture
base_model.summary()
Model: "mobilenetv2_1.00_160"
____________________________________________________________________________
______________________
Layer (type) Output Shape Param # Connected
to
============================================================================
======================
input_1 (InputLayer) [(None, 160, 160, 3) 0
____________________________________________________________________________
______________________
Conv1 (Conv2D) (None, 80, 80, 32) 864
input_1[0][0]
____________________________________________________________________________
______________________
bn_Conv1 (BatchNormalization) (None, 80, 80, 32) 128 Conv1[0][0]
____________________________________________________________________________
______________________
Conv1_relu (ReLU) (None, 80, 80, 32) 0
bn_Conv1[0][0]
____________________________________________________________________________
______________________
expanded_conv_depthwise (Depthw (None, 80, 80, 32) 288
Conv1_relu[0][0]
65 | P a g e
____________________________________________________________________________
______________________
expanded_conv_depthwise_BN (Bat (None, 80, 80, 32) 128
expanded_conv_depthwise[0][0]
____________________________________________________________________________
______________________
expanded_conv_depthwise_relu (R (None, 80, 80, 32) 0
expanded_conv_depthwise_BN[0][0]
____________________________________________________________________________
______________________
expanded_conv_project (Conv2D) (None, 80, 80, 16) 512
expanded_conv_depthwise_relu[0][0
____________________________________________________________________________
______________________
expanded_conv_project_BN (Batch (None, 80, 80, 16) 64
expanded_conv_project[0][0]
____________________________________________________________________________
______________________
block_1_expand (Conv2D) (None, 80, 80, 96) 1536
expanded_conv_project_BN[0][0]
____________________________________________________________________________
______________________
66 | P a g e
block_1_project_BN (BatchNormal (None, 40, 40, 24) 96
block_1_project[0][0]
____________________________________________________________________________
______________________
block_2_expand (Conv2D) (None, 40, 40, 144) 3456
block_1_project_BN[0][0]
____________________________________________________________________________
______________________
block_2_expand_BN (BatchNormali (None, 40, 40, 144) 576
block_2_expand[0][0]
____________________________________________________________________________
______________________
block_2_project_BN[0][0]
____________________________________________________________________________
______________________
block_3_expand (Conv2D) (None, 40, 40, 144) 3456
block_2_add[0][0]
____________________________________________________________________________
______________________
block_3_expand_BN (BatchNormali (None, 40, 40, 144) 576
block_3_expand[0][0]
____________________________________________________________________________
______________________
67 | P a g e
block_3_expand_relu (ReLU) (None, 40, 40, 144) 0
block_3_expand_BN[0][0]
____________________________________________________________________________
______________________
block_3_pad (ZeroPadding2D) (None, 41, 41, 144) 0
block_3_expand_relu[0][0]
____________________________________________________________________________
______________________
block_3_depthwise (DepthwiseCon (None, 20, 20, 144) 1296
block_3_pad[0][0]
____________________________________________________________________________
______________________
block_3_depthwise_BN (BatchNorm (None, 20, 20, 144) 576
block_3_depthwise[0][0]
____________________________________________________________________________
______________________
68 | P a g e
____________________________________________________________________________
______________________
block_4_project (Conv2D) (None, 20, 20, 32) 6144
block_4_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_4_project_BN (BatchNormal (None, 20, 20, 32) 128
block_4_project[0][0]
____________________________________________________________________________
______________________
block_4_add (Add) (None, 20, 20, 32) 0
block_3_project_BN[0][0]
block_4_project_BN[0][0]
____________________________________________________________________________
______________________
69 | P a g e
block_5_add (Add) (None, 20, 20, 32) 0
block_4_add[0][0]
block_5_project_BN[0][0]
____________________________________________________________________________
______________________
block_6_expand (Conv2D) (None, 20, 20, 192) 6144
block_5_add[0][0]
____________________________________________________________________________
______________________
block_6_expand_BN (BatchNormali (None, 20, 20, 192) 768
block_6_expand[0][0]
____________________________________________________________________________
______________________
block_6_expand_relu (ReLU) (None, 20, 20, 192) 0
block_6_expand_BN[0][0]
____________________________________________________________________________
______________________
block_6_pad (ZeroPadding2D) (None, 21, 21, 192) 0
block_6_expand_relu[0][0]
____________________________________________________________________________
______________________
block_6_depthwise (DepthwiseCon (None, 10, 10, 192) 1728
block_6_pad[0][0]
____________________________________________________________________________
______________________
block_6_depthwise_BN (BatchNorm (None, 10, 10, 192) 768
block_6_depthwise[0][0]
____________________________________________________________________________
______________________
block_6_depthwise_relu (ReLU) (None, 10, 10, 192) 0
block_6_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_6_project (Conv2D) (None, 10, 10, 64) 12288
block_6_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_6_project_BN (BatchNormal (None, 10, 10, 64) 256
block_6_project[0][0]
____________________________________________________________________________
______________________
block_7_expand (Conv2D) (None, 10, 10, 384) 24576
block_6_project_BN[0][0]
____________________________________________________________________________
______________________
block_7_expand_BN (BatchNormali (None, 10, 10, 384) 1536
block_7_expand[0][0]
____________________________________________________________________________
______________________
block_7_expand_relu (ReLU) (None, 10, 10, 384) 0
block_7_expand_BN[0][0]
70 | P a g e
____________________________________________________________________________
______________________
block_7_depthwise (DepthwiseCon (None, 10, 10, 384) 3456
block_7_expand_relu[0][0]
____________________________________________________________________________
______________________
block_7_depthwise_BN (BatchNorm (None, 10, 10, 384) 1536
block_7_depthwise[0][0]
____________________________________________________________________________
______________________
block_7_depthwise_relu (ReLU) (None, 10, 10, 384) 0
block_7_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_7_project (Conv2D) (None, 10, 10, 64) 24576
block_7_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_7_project_BN (BatchNormal (None, 10, 10, 64) 256
block_7_project[0][0]
____________________________________________________________________________
______________________
block_7_project_BN[0][0]
____________________________________________________________________________
______________________
block_8_expand (Conv2D) (None, 10, 10, 384) 24576
block_7_add[0][0]
____________________________________________________________________________
______________________
71 | P a g e
block_8_depthwise_relu (ReLU) (None, 10, 10, 384) 0
block_8_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_8_project (Conv2D) (None, 10, 10, 64) 24576
block_8_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_8_project_BN (BatchNormal (None, 10, 10, 64) 256
block_8_project[0][0]
____________________________________________________________________________
______________________
block_8_add (Add) (None, 10, 10, 64) 0
block_7_add[0][0]
block_8_project_BN[0][0]
____________________________________________________________________________
______________________
block_9_expand (Conv2D) (None, 10, 10, 384) 24576
block_8_add[0][0]
____________________________________________________________________________
______________________
block_9_expand_BN (BatchNormali (None, 10, 10, 384) 1536
block_9_expand[0][0]
____________________________________________________________________________
______________________
72 | P a g e
____________________________________________________________________________
______________________
block_9_add (Add) (None, 10, 10, 64) 0
block_8_add[0][0]
block_9_project_BN[0][0]
____________________________________________________________________________
______________________
block_10_expand (Conv2D) (None, 10, 10, 384) 24576
block_9_add[0][0]
____________________________________________________________________________
______________________
block_10_expand_BN (BatchNormal (None, 10, 10, 384) 1536
block_10_expand[0][0]
____________________________________________________________________________
______________________
block_10_expand_relu (ReLU) (None, 10, 10, 384) 0
block_10_expand_BN[0][0]
____________________________________________________________________________
______________________
block_10_depthwise (DepthwiseCo (None, 10, 10, 384) 3456
block_10_expand_relu[0][0]
____________________________________________________________________________
______________________
block_10_depthwise_BN (BatchNor (None, 10, 10, 384) 1536
block_10_depthwise[0][0]
____________________________________________________________________________
______________________
73 | P a g e
block_11_expand_relu (ReLU) (None, 10, 10, 576) 0
block_11_expand_BN[0][0]
____________________________________________________________________________
______________________
block_11_depthwise (DepthwiseCo (None, 10, 10, 576) 5184
block_11_expand_relu[0][0]
____________________________________________________________________________
______________________
block_11_depthwise_BN (BatchNor (None, 10, 10, 576) 2304
block_11_depthwise[0][0]
____________________________________________________________________________
______________________
block_11_depthwise_relu (ReLU) (None, 10, 10, 576) 0
block_11_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_11_project (Conv2D) (None, 10, 10, 96) 55296
block_11_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_11_project_BN (BatchNorma (None, 10, 10, 96) 384
block_11_project[0][0]
____________________________________________________________________________
______________________
block_11_add (Add) (None, 10, 10, 96) 0
block_10_project_BN[0][0]
block_11_project_BN[0][0]
____________________________________________________________________________
______________________
block_12_expand (Conv2D) (None, 10, 10, 576) 55296
block_11_add[0][0]
____________________________________________________________________________
______________________
block_12_expand_BN (BatchNormal (None, 10, 10, 576) 2304
block_12_expand[0][0]
____________________________________________________________________________
______________________
block_12_expand_relu (ReLU) (None, 10, 10, 576) 0
block_12_expand_BN[0][0]
____________________________________________________________________________
______________________
block_12_depthwise (DepthwiseCo (None, 10, 10, 576) 5184
block_12_expand_relu[0][0]
____________________________________________________________________________
______________________
block_12_depthwise_BN (BatchNor (None, 10, 10, 576) 2304
block_12_depthwise[0][0]
____________________________________________________________________________
______________________
block_12_depthwise_relu (ReLU) (None, 10, 10, 576) 0
block_12_depthwise_BN[0][0]
74 | P a g e
____________________________________________________________________________
______________________
block_12_project (Conv2D) (None, 10, 10, 96) 55296
block_12_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_12_project_BN (BatchNorma (None, 10, 10, 96) 384
block_12_project[0][0]
____________________________________________________________________________
______________________
block_12_add (Add) (None, 10, 10, 96) 0
block_11_add[0][0]
block_12_project_BN[0][0]
____________________________________________________________________________
______________________
block_13_expand (Conv2D) (None, 10, 10, 576) 55296
block_12_add[0][0]
____________________________________________________________________________
______________________
block_13_expand_BN (BatchNormal (None, 10, 10, 576) 2304
block_13_expand[0][0]
____________________________________________________________________________
______________________
block_13_expand_relu (ReLU) (None, 10, 10, 576) 0
block_13_expand_BN[0][0]
____________________________________________________________________________
______________________
block_13_pad (ZeroPadding2D) (None, 11, 11, 576) 0
block_13_expand_relu[0][0]
____________________________________________________________________________
______________________
block_13_depthwise (DepthwiseCo (None, 5, 5, 576) 5184
block_13_pad[0][0]
____________________________________________________________________________
______________________
block_13_depthwise_BN (BatchNor (None, 5, 5, 576) 2304
block_13_depthwise[0][0]
____________________________________________________________________________
______________________
block_13_depthwise_relu (ReLU) (None, 5, 5, 576) 0
block_13_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_13_project (Conv2D) (None, 5, 5, 160) 92160
block_13_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_13_project_BN (BatchNorma (None, 5, 5, 160) 640
block_13_project[0][0]
____________________________________________________________________________
______________________
75 | P a g e
block_14_expand (Conv2D) (None, 5, 5, 960) 153600
block_13_project_BN[0][0]
____________________________________________________________________________
______________________
block_14_expand_BN (BatchNormal (None, 5, 5, 960) 3840
block_14_expand[0][0]
____________________________________________________________________________
______________________
block_14_expand_relu (ReLU) (None, 5, 5, 960) 0
block_14_expand_BN[0][0]
____________________________________________________________________________
______________________
block_14_depthwise (DepthwiseCo (None, 5, 5, 960) 8640
block_14_expand_relu[0][0]
____________________________________________________________________________
______________________
block_14_depthwise_BN (BatchNor (None, 5, 5, 960) 3840
block_14_depthwise[0][0]
____________________________________________________________________________
______________________
block_14_depthwise_relu (ReLU) (None, 5, 5, 960) 0
block_14_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_14_project (Conv2D) (None, 5, 5, 160) 153600
block_14_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_14_project_BN (BatchNorma (None, 5, 5, 160) 640
block_14_project[0][0]
____________________________________________________________________________
______________________
block_14_add (Add) (None, 5, 5, 160) 0
block_13_project_BN[0][0]
block_14_project_BN[0][0]
____________________________________________________________________________
______________________
block_15_expand (Conv2D) (None, 5, 5, 960) 153600
block_14_add[0][0]
____________________________________________________________________________
______________________
block_15_expand_BN (BatchNormal (None, 5, 5, 960) 3840
block_15_expand[0][0]
____________________________________________________________________________
______________________
block_15_expand_relu (ReLU) (None, 5, 5, 960) 0
block_15_expand_BN[0][0]
____________________________________________________________________________
______________________
block_15_depthwise (DepthwiseCo (None, 5, 5, 960) 8640
block_15_expand_relu[0][0]
76 | P a g e
____________________________________________________________________________
______________________
block_15_depthwise_BN (BatchNor (None, 5, 5, 960) 3840
block_15_depthwise[0][0]
____________________________________________________________________________
______________________
block_15_depthwise_relu (ReLU) (None, 5, 5, 960) 0
block_15_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_15_project (Conv2D) (None, 5, 5, 160) 153600
block_15_depthwise_relu[0][0]
____________________________________________________________________________
______________________
block_15_project_BN (BatchNorma (None, 5, 5, 160) 640
block_15_project[0][0]
____________________________________________________________________________
______________________
block_15_add (Add) (None, 5, 5, 160) 0
block_14_add[0][0]
block_15_project_BN[0][0]
____________________________________________________________________________
______________________
block_16_expand (Conv2D) (None, 5, 5, 960) 153600
block_15_add[0][0]
____________________________________________________________________________
______________________
block_16_expand_BN (BatchNormal (None, 5, 5, 960) 3840
block_16_expand[0][0]
____________________________________________________________________________
______________________
block_16_expand_relu (ReLU) (None, 5, 5, 960) 0
block_16_expand_BN[0][0]
____________________________________________________________________________
______________________
block_16_depthwise (DepthwiseCo (None, 5, 5, 960) 8640
block_16_expand_relu[0][0]
____________________________________________________________________________
______________________
block_16_depthwise_BN (BatchNor (None, 5, 5, 960) 3840
block_16_depthwise[0][0]
____________________________________________________________________________
______________________
block_16_depthwise_relu (ReLU) (None, 5, 5, 960) 0
block_16_depthwise_BN[0][0]
____________________________________________________________________________
______________________
block_16_project (Conv2D) (None, 5, 5, 320) 307200
block_16_depthwise_relu[0][0]
____________________________________________________________________________
______________________
77 | P a g e
block_16_project_BN (BatchNorma (None, 5, 5, 320) 1280
block_16_project[0][0]
____________________________________________________________________________
______________________
Conv_1 (Conv2D) (None, 5, 5, 1280) 409600
block_16_project_BN[0][0]
____________________________________________________________________________
______________________
Conv_1_bn (BatchNormalization) (None, 5, 5, 1280) 5120
Conv_1[0][0]
____________________________________________________________________________
______________________
out_relu (ReLU) (None, 5, 5, 1280) 0
Conv_1_bn[0][0]
============================================================================
======================
Total params: 2,257,984
Trainable params: 0
Non-trainable params: 2,257,984
____________________________________________________________________________
______________________
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
feature_batch_average = global_average_layer(feature_batch)
print(feature_batch_average.shape)
(32, 1280)
prediction_layer = tf.keras.layers.Dense(1)
prediction_batch = prediction_layer(feature_batch_average)
print(prediction_batch.shape)
(32, 1)
inputs = tf.keras.Input(shape=(160, 160, 3))
x = data_augmentation(inputs)
x = preprocess_input(x)
x = base_model(x, training=False)
x = global_average_layer(x)
x = tf.keras.layers.Dropout(0.2)(x)
outputs = prediction_layer(x)
model = tf.keras.Model(inputs, outputs)
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
78 | P a g e
model.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 160, 160, 3)] 0
_________________________________________________________________
sequential (Sequential) (None, 160, 160, 3) 0
_________________________________________________________________
tf.math.truediv (TFOpLambda) (None, 160, 160, 3) 0
_________________________________________________________________
tf.math.subtract (TFOpLambda (None, 160, 160, 3) 0
_________________________________________________________________
mobilenetv2_1.00_160 (Functi (None, 5, 5, 1280) 2257984
_________________________________________________________________
global_average_pooling2d (Gl (None, 1280) 0
_________________________________________________________________
dropout (Dropout) (None, 1280) 0
_________________________________________________________________
dense (Dense) (None, 1) 1281
=================================================================
Total params: 2,259,265
Trainable params: 1,281
Non-trainable params: 2,257,984
_________________________________________________________________
len(model.trainable_variables)
2
initial_epochs = 10
history = model.fit(train_dataset,
epochs=initial_epochs,
validation_data=validation_dataset)
Epoch 1/10
63/63 [==============================] - 8s 65ms/step - loss: 0.6895 -
accuracy: 0.6015 - val_loss: 0.4956 - val_accuracy: 0.7562
Epoch 2/10
63/63 [==============================] - 5s 69ms/step - loss: 0.5121 -
accuracy: 0.7130 - val_loss: 0.3692 - val_accuracy: 0.8527
Epoch 3/10
63/63 [==============================] - 5s 75ms/step - loss: 0.4247 -
accuracy: 0.7875 - val_loss: 0.2849 - val_accuracy: 0.8960
79 | P a g e
Epoch 4/10
63/63 [==============================] - 5s 76ms/step - loss: 0.3649 -
accuracy: 0.8265 - val_loss: 0.2332 - val_accuracy: 0.9270
Epoch 5/10
63/63 [==============================] - 4s 64ms/step - loss: 0.3107 -
accuracy: 0.8625 - val_loss: 0.2021 - val_accuracy: 0.9394
Epoch 6/10
63/63 [==============================] - 5s 68ms/step - loss: 0.2742 -
accuracy: 0.8810 - val_loss: 0.1724 - val_accuracy: 0.9468
Epoch 7/10
63/63 [==============================] - 4s 63ms/step - loss: 0.2677 -
accuracy: 0.8840 - val_loss: 0.1631 - val_accuracy: 0.9517
Epoch 8/10
63/63 [==============================] - 4s 64ms/step - loss: 0.2456 -
accuracy: 0.8950 - val_loss: 0.1372 - val_accuracy: 0.9616
Epoch 9/10
63/63 [==============================] - 4s 62ms/step - loss: 0.2198 -
accuracy: 0.9070 - val_loss: 0.1344 - val_accuracy: 0.9629
Epoch 10/10
63/63 [==============================] - 5s 73ms/step - loss: 0.2127 -
accuracy: 0.9040 - val_loss: 0.1207 - val_accuracy: 0.9691
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0,1.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
80 | P a g e
Fine tuning
base_model.trainable = True
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))
81 | P a g e
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 160, 160, 3)] 0
_________________________________________________________________
history_fine = model.fit(train_dataset,
epochs=total_epochs,
initial_epoch=history.epoch[-1],
validation_data=validation_dataset)
Epoch 10/20
63/63 [==============================] - 12s 97ms/step - loss: 0.1640 -
accuracy: 0.9320 - val_loss: 0.0554 - val_accuracy: 0.9851
Epoch 11/20
63/63 [==============================] - 5s 77ms/step - loss: 0.1153 -
accuracy: 0.9515 - val_loss: 0.0567 - val_accuracy: 0.9839
Epoch 12/20
63/63 [==============================] - 6s 82ms/step - loss: 0.1119 -
accuracy: 0.9560 - val_loss: 0.0510 - val_accuracy: 0.9876
Epoch 13/20
63/63 [==============================] - 5s 70ms/step - loss: 0.1050 -
accuracy: 0.9570 - val_loss: 0.0473 - val_accuracy: 0.9790
Epoch 14/20
63/63 [==============================] - 5s 73ms/step - loss: 0.0940 -
accuracy: 0.9640 - val_loss: 0.0730 - val_accuracy: 0.9728
Epoch 15/20
63/63 [==============================] - 5s 71ms/step - loss: 0.0835 -
accuracy: 0.9675 - val_loss: 0.0499 - val_accuracy: 0.9777
Epoch 16/20
82 | P a g e
63/63 [==============================] - 5s 71ms/step - loss: 0.0790 -
accuracy: 0.9680 - val_loss: 0.0455 - val_accuracy: 0.9864
Epoch 17/20
63/63 [==============================] - 5s 78ms/step - loss: 0.0745 -
accuracy: 0.9745 - val_loss: 0.0476 - val_accuracy: 0.9851
Epoch 18/20
acc += history_fine.history['accuracy']
val_acc += history_fine.history['val_accuracy']
loss += history_fine.history['loss']
val_loss += history_fine.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.ylim([0.8, 1])
plt.plot([initial_epochs-1,initial_epochs-1],
plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.ylim([0, 1.0])
plt.plot([initial_epochs-1,initial_epochs-1],
plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
83 | P a g e
Evaluation and prediction
loss, accuracy = model.evaluate(test_dataset)
print('Test accuracy :', accuracy)
6/6 [==============================] - 1s 46ms/step - loss: 0.0307 -
accuracy: 0.9792
Test accuracy : 0.9791666865348816
plt.figure(figsize=(10, 10))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image_batch[i].astype("uint8"))
plt.title(class_names[predictions[i]])
plt.axis("off")
84 | P a g e
Predictions:
[0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1]
Labels:
[0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1]
85 | P a g e
Program 8. Building a simple convolutional neural network for transfer learning using feature
extraction.
Code snippet:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
y_train_onehot = to_categorical(y_train, 10)
y_test_onehot = to_categorical(y_test, 10)
Data Visualization
plt.figure(figsize=(10, 5))
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(x_train[i])
plt.title(class_names[int(y_train[i])])
plt.axis('off')
plt.tight_layout()
plt.show()
Feature extraction:
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(32, 32, 3))
x_train_features = base_model.predict(x_train)
86 | P a g e
x_test_features = base_model.predict(x_test))
Top Model:
top_model = Sequential([
Flatten(input_shape=x_train_features.shape[1:]),
Dense(256, activation='relu'),
Dense(10, activation='softmax')
])
Training:
history = top_model.fit(
x_train_features, y_train_onehot,
batch_size=32, epochs=10,
validation_data=(x_test_features, y_test_onehot)
)
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 559s 357ms/step
313/313 ━━━━━━━━━━━━━━━━━━━━ 110s 351ms/step
Epoch 1/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 6s 3ms/step - accuracy: 0.4769 - loss:
1.4913 - val_accuracy: 0.5689 - val_loss: 1.2278
Epoch 2/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - accuracy: 0.5896 - loss:
1.1739 - val_accuracy: 0.5853 - val_loss: 1.1795
Epoch 3/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - accuracy: 0.6106 - loss:
1.1009 - val_accuracy: 0.5856 - val_loss: 1.1885
Epoch 4/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - accuracy: 0.6336 - loss:
1.0479 - val_accuracy: 0.6085 - val_loss: 1.1156
Epoch 5/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 6s 4ms/step - accuracy: 0.6484 - loss:
1.0018 - val_accuracy: 0.6080 - val_loss: 1.1316
Epoch 6/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 10s 4ms/step - accuracy: 0.6628 - loss:
0.9586 - val_accuracy: 0.6120 - val_loss: 1.1110
Epoch 7/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 9s 3ms/step - accuracy: 0.6785 - loss:
0.9238 - val_accuracy: 0.6133 - val_loss: 1.1131
Epoch 8/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - accuracy: 0.6872 - loss:
0.8882 - val_accuracy: 0.6163 - val_loss: 1.1147
Epoch 9/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 8s 3ms/step - accuracy: 0.6970 - loss:
0.8606 - val_accuracy: 0.6202 - val_loss: 1.1100
87 | P a g e
Epoch 10/10
1563/1563 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - accuracy: 0.7123 - loss:
0.8262 - val_accuracy: 0.6218 - val_loss: 1.1035
313/313 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.6168 - loss:
1.1039
Evaluation:
loss, accuracy = top_model.evaluate(x_test_features, y_test_onehot)
print(f'Test loss: {loss}')
print(f'Test accuracy: {accuracy}')
Results Visualization
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout()
plt.show()
88 | P a g e
Confusion Matrix:
y_pred = np.argmax(top_model.predict(x_test_features), axis=1)
y_true = np.argmax(y_test_onehot, axis=1)
cm = confusion_matrix(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=class_names)
disp.plot(cmap='viridis', xticks_rotation='vertical')
plt.title('Confusion Matrix')
plt.show()
Results
1. Test Accuracy:
Achieved an accuracy of approximately 0.6218000054359436 on the test dataset.
2. Confusion Matrix Insights:
Highlighted the classes where the model performed well and those with misclassifications.
3. Training Loss and Accuracy:
The training and validation curves converged, indicating the model successfully learned the
task without overfitting.
Conclusion
Using pre-trained models like VGG16 for feature extraction is effective for small datasets like CIFAR-
10. The custom classifier achieved good accuracy and provided clear visualizations of its performance,
making it a robust method for transfer learning tasks.
89 | P a g e
Program 9. Building a CNN model for object detection using a pre-trained architecture like
YOLO.
Dependencies
import tensorflow as tf
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from IPython.display import display
from seaborn import color_palette
import cv2
Model hyperparameters
_BATCH_NORM_DECAY = 0.9
_BATCH_NORM_EPSILON = 1e-05
_LEAKY_RELU = 0.1
_ANCHORS = [(10, 13), (16, 30), (33, 23),
(30, 61), (62, 45), (59, 119),
(116, 90), (156, 198), (373, 326)]
_MODEL_SIZE = (416, 416)
Model definition
def batch_norm(inputs, training, data_format):
"""Performs a batch normalization using a standard set of parameters."""
return tf.layers.batch_normalization(
inputs=inputs, axis=1 if data_format == 'channels_first' else 3,
momentum=_BATCH_NORM_DECAY, epsilon=_BATCH_NORM_EPSILON,
scale=True, training=training)
if data_format == 'channels_first':
else:
padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end],
[pad_beg, pad_end], [0, 0]])
return padded_inputs
90 | P a g e
def conv2d_fixed_padding(inputs, filters, kernel_size, data_format, strides=1):
"""Strided 2-D convolution with explicit padding."""
if strides > 1:
inputs = fixed_padding(inputs, kernel_size, data_format)
return tf.layers.conv2d(
inputs=inputs, filters=filters, kernel_size=kernel_size,
strides=strides, padding=('SAME' if strides == 1 else 'VALID'),
use_bias=False, data_format=data_format)
inputs = conv2d_fixed_padding(
inputs, filters=filters, kernel_size=1, strides=strides,
data_format=data_format)
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=_LEAKY_RELU)
inputs = conv2d_fixed_padding(
inputs, filters=2 * filters, kernel_size=3, strides=strides,
data_format=data_format)
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=_LEAKY_RELU)
inputs += shortcut
return inputs
data_format=data_format)
91 | P a g e
for _ in range(2):
inputs = darknet53_residual_block(inputs, filters=64,
training=training,
data_format=data_format)
for _ in range(8):
inputs = darknet53_residual_block(inputs, filters=128,
training=training,
data_format=data_format)
route1 = inputs
for _ in range(8):
inputs = darknet53_residual_block(inputs, filters=256,
training=training,
data_format=data_format)
route2 = inputs
for _ in range(4):
inputs = darknet53_residual_block(inputs, filters=512,
training=training,
data_format=data_format)
Convolution layers
def yolo_convolution_block(inputs, filters, training, data_format):
"""Creates convolution operations layer used after Darknet."""
inputs = conv2d_fixed_padding(inputs, filters=filters, kernel_size=1,
data_format=data_format)
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=_LEAKY_RELU)
92 | P a g e
data_format=data_format)
Detection layers
def yolo_layer(inputs, n_classes, anchors, img_size, data_format):
n_anchors = len(anchors)
shape = inputs.get_shape().as_list()
x = tf.range(grid_shape[0], dtype=tf.float32)
y = tf.range(grid_shape[1], dtype=tf.float32)
x_offset, y_offset = tf.meshgrid(x, y)
x_offset = tf.reshape(x_offset, (-1, 1))
93 | P a g e
y_offset = tf.reshape(y_offset, (-1, 1))
x_y_offset = tf.concat([x_offset, y_offset], axis=-1)
x_y_offset = tf.tile(x_y_offset, [1, n_anchors])
x_y_offset = tf.reshape(x_y_offset, [1, -1, 2])
box_centers = tf.nn.sigmoid(box_centers)
box_centers = (box_centers + x_y_offset) * strides
confidence = tf.nn.sigmoid(confidence)
classes = tf.nn.sigmoid(classes)
return inputs
Upsample layer
if data_format == 'channels_first':
new_height = out_shape[3]
new_width = out_shape[2]
else:
new_height = out_shape[2]
new_width = out_shape[1]
if data_format == 'channels_first':
return inputs
def build_boxes(inputs):
"""Computes top left and bottom right points of the boxes."""
94 | P a g e
top_left_x = center_x - width / 2
top_left_y = center_y - height / 2
bottom_right_x = center_x + width / 2
bottom_right_y = center_y + height / 2
boxes_dict = dict()
for cls in range(n_classes):
mask = tf.equal(boxes[:, 5], cls)
mask_shape = mask.get_shape()
if mask_shape.ndims != 0:
class_boxes = tf.boolean_mask(boxes, mask)
boxes_coords, boxes_conf_scores, _ = tf.split(class_boxes,
[4, 1, -1],
axis=-1)
boxes_conf_scores = tf.reshape(boxes_conf_scores, [-1])
indices = tf.image.non_max_suppression(boxes_coords,
boxes_conf_scores,
max_output_size,
iou_threshold)
class_boxes = tf.gather(class_boxes, indices)
boxes_dict[cls] = class_boxes[:, :5]
boxes_dicts.append(boxes_dict)
return boxes_dicts
class Yolo_v3:
"""Yolo v3 model class."""
if not data_format:
if tf.test.is_built_with_cuda():
data_format = 'channels_first'
else:
data_format = 'channels_last'
95 | P a g e
self.n_classes = n_classes
self.model_size = model_size
self.max_output_size = max_output_size
self.iou_threshold = iou_threshold
self.confidence_threshold = confidence_threshold
self.data_format = data_format
anchors=_ANCHORS[6:9],
img_size=self.model_size,
data_format=self.data_format)
96 | P a g e
data_format=self.data_format)
inputs = tf.concat([inputs, route1], axis=axis)
route, inputs = yolo_convolution_block(
inputs, filters=128, training=training,
data_format=self.data_format)
inputs = build_boxes(inputs)
boxes_dicts = non_max_suppression(
inputs, n_classes=self.n_classes,
max_output_size=self.max_output_size,
iou_threshold=self.iou_threshold,
confidence_threshold=self.confidence_threshold)
return boxes_dicts
imgs = []
imgs = np.concatenate(imgs)
return imgs
def load_class_names(file_name):
"""Returns a list of class names read from `file_name`."""
with open(file_name, 'r') as f:
class_names = f.read().splitlines()
return class_names
97 | P a g e
(img.size[0] / model_size[0], img.size[1] / model_size[1])
for cls in range(len(class_names)):
boxes = boxes_dict[cls]
if np.size(boxes) != 0:
color = colors[cls]
for box in boxes:
xy, confidence = box[:4], box[4]
xy = [xy[i] * resize_factor[i % 2] for i in range(4)]
x0, y0 = xy[0], xy[1]
thickness = (img.size[0] + img.size[1]) // 200
for t in np.linspace(0, 1, thickness):
xy[0], xy[1] = xy[0] + t, xy[1] + t
xy[2], xy[3] = xy[2] - t, xy[3] - t
draw.rectangle(xy, outline=tuple(color))
text = '{} {:.1f}%'.format(class_names[cls],
confidence * 100)
text_size = draw.textsize(text, font=font)
draw.rectangle(
[x0, y0 - text_size[1], x0 + text_size[0], y0],
fill=tuple(color))
draw.text((x0, y0 - text_size[1]), text, fill='black',
font=font)
display(img)
98 | P a g e
batch_size = len(img_names)
batch = load_images(img_names, model_size=_MODEL_SIZE)
class_names = load_class_names('../input/coco.names')
n_classes = len(class_names)
max_output_size = 10
iou_threshold = 0.5
confidence_threshold = 0.5
model_vars = tf.global_variables(scope='yolo_v3_model')
assign_ops = load_weights(model_vars, '../input/yolov3.weights')
99 | P a g e
Video processing
100 | P a g e
Program 10. Exploring different activation functions and comparing their effects on network
performance.
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import SGD
import numpy as np
Activation functions
Linear
clf = Sequential()
clf.add(Dense(3, activation='linear', input_shape=(1,), name='hidden'))
clf.add(Dense(3, activation='softmax', name='out'))
clf.compile(loss='categorical_crossentropy', optimizer=SGD(),
metrics=['accuracy'])
Epoch 1/10
1000/1000 [==============================] - 0s 400us/step - loss: 0.7590 -
acc: 0.7520
Epoch 2/10
1000/1000 [==============================] - 0s 79us/step - loss: 0.6491 -
acc: 0.8150
Epoch 3/10
1000/1000 [==============================] - 0s 75us/step - loss: 0.5746 -
acc: 0.8520
Epoch 4/10
1000/1000 [==============================] - 0s 78us/step - loss: 0.5208 -
acc: 0.8690
Epoch 5/10
1000/1000 [==============================] - 0s 77us/step - loss: 0.4805 -
acc: 0.8800
101 | P a g e
Epoch 6/10
1000/1000 [==============================] - 0s 73us/step - loss: 0.4500 -
acc: 0.8830
Epoch 7/10
1000/1000 [==============================] - 0s 77us/step - loss: 0.4266 -
acc: 0.8870
Epoch 8/10
1000/1000 [==============================] - 0s 75us/step - loss: 0.4083 -
acc: 0.8880
Epoch 9/10
1000/1000 [==============================] - 0s 76us/step - loss: 0.3936 -
acc: 0.8920
Epoch 10/10
1000/1000 [==============================] - 0s 77us/step - loss: 0.3817 -
acc: 0.8920
<keras.callbacks.History at 0x7f36a4fa9e10>
Logistic (sigmoid)
Non-linear activation functions come in many shapes. The most general class of non-linear activation
function is so-called sigmoid functions, which are distinguishable by having an S-shaped value curve.
102 | P a g e
fig = plt.figure(figsize=(12, 8))
plt.plot(range(len(clf.history.history['acc'])), clf.history.history['acc'],
linewidth=4)
import seaborn as sns; sns.despine()
plt.title("Sigmoid Activation Accuracy Per Epoch", fontsize=20)
pass
Tanh
An alternative to the logistic function is arctan or "tanh". This curve has different properties:
103 | P a g e
clf.compile(loss='categorical_crossentropy', optimizer=SGD(),
metrics=['accuracy'])
def relu(x):
return 0 if x <= 0 else x
104 | P a g e
clf = Sequential()
clf.add(Dense(3, activation='relu', input_shape=(1,), name='hidden'))
clf.add(Dense(3, activation='softmax', name='out'))
clf.compile(loss='categorical_crossentropy', optimizer=SGD(),
metrics=['accuracy'])
105 | P a g e
Program 11. Write a program to Build an Artificial Neural Network by implementing the
Back propagation algorithm and test the same using appropriate data sets.
import os
print(os.listdir("../input/"))
# Any results you write to the current directory are saved as output.
Model Creating
# create the model
model = Sequential()
model.add(Dense(100, input_dim=255, init='uniform', activation='relu'))
model.add(Dense(100, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
106 | P a g e
model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=10,
batch_size=5)#, verbose=0)
Out[4]:
Evaluation
# evaluate the model
scores = model.evaluate(X_test, Y_test) #29.27
print("Accuracy: %.2f%%" % (scores[1]*100))
1459/1459 [==============================] - 0s 23us/step
Accuracy: 29.95%
107 | P a g e
Program 12. Implement a program for Basic image operations
# Importing modules
import cv2
import numpy as np
import matplotlib.pyplot as plt
def show(img):
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img, cmap='gray')
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
#This function will plot two images side by side
def plot_image(image_1, image_2,title_1="Orignal",title_2="New Image"):
plt.figure(figsize=(10,10))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image_1, cv2.COLOR_BGR2RGB))
plt.title(title_1)
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(image_2, cv2.COLOR_BGR2RGB))
plt.title(title_2)
plt.show()
print(page_image)
[[[ 20 39 82]
[ 21 40 83]
[ 21 40 83]
...
[105 127 155]
[107 129 157]
[111 133 161]]
108 | P a g e
[[ 20 39 82]
[ 21 40 83]
[ 21 40 83]
...
[[ 21 40 83]
[ 21 40 83]
[ 21 40 83]
...
[104 127 153]
[105 128 154]
[107 130 156]]
...
[[ 69 80 110]
[ 69 80 110]
[ 69 80 110]
...
[169 160 163]
[169 160 163]
[168 159 162]]
[[ 69 80 110]
[ 69 80 110]
[ 69 80 110]
...
[170 161 164]
[169 160 163]
[169 160 163]]
[[ 69 80 110]
[ 69 80 110]
[ 69 80 110]
...
[170 161 164]
[169 160 163]
[169 160 163]]]
# Checkin the Type of Image
print("Type of image is {}".format(type(page_image)))
print(len(page_image))
960
print(len(page_image[0]))
1280
print(len(page_image[0][0]))
3
109 | P a g e
#Dimension for image
print("Dimension for image is {}".format(page_image.shape))
Dimension for image is (960, 1280, 3)
print(page_image.dtype)
uint8
print(page_image.size)
3686400
page_image.max()
255
page_image.min()
0
length=page_image.shape[0]
width=page_image.shape[1]
channels=page_image.shape[2]
new_image=cv2.cvtColor(lenna, cv2.COLOR_BGR2RGB)
plt.imshow(new_image)
plt.show()
110 | P a g e
# get grayscale image
def get_grayscale(image):
return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image_gray=get_grayscale(new_image)
show(image_gray)
image_gray.shape
(330, 330)
plt.imshow(image_gray, cmap='gray')
plt.show()
111 | P a g e
Indexing
rows = 256
show(lenna[0:rows, :, :])
columns = 256
show(lenna[:,0:columns,:])
Cropping an Image
"""
Cropping image where following
Start Row (y1)
Start Column(x1)
End row(y1+h)
End columns(x1+w)
"""
##################################
"""
def crop_np(image):
y=375
x=300
h=425
w=645
112 | P a g e
return cropped_img
"""
def cropping(image):
height, width = image.shape[:2]
# Let's get the starting pixel coordiantes (top left of cropping rectangle)
start_row, start_col = int(height * .31), int(width * 0.17)
return cropped
crop_image=cropping(page_image)
113 | P a g e
image_g[:, :, [0, 2]]=0
f, axes = plt.subplots(1, 4, figsize = (15,15))
images= [flowers, image_b, image_r, image_g]
i = 0
for ax in axes:
if i==0:
ax.imshow(cv2.cvtColor(images[i], cv2.COLOR_BGR2RGB))
else:
ax.imshow(images[i])
i+=1
Copying Images
A = lenna.copy()
show(A)
Manipulating Images
cat = cv2.imread(path+r"/cat.png")
show(cat)
114 | P a g e
width, height,C=cat.shape
print('width, height, C',width, height, C)
array_flip = np.zeros((width, height,C),dtype=np.uint8)
for i,row in enumerate(cat):
array_flip[width-1-i,:,:]=row
show(array_flip)
115 | P a g e
im_flip = cv2.rotate(cat, 0)
show(im_flip)
flip =
{"ROTATE_90_CLOCKWISE":cv2.ROTATE_90_CLOCKWISE,"ROTATE_90_COUNTERCLOCKWISE":cv2.
ROTATE_90_COUNTERCLOCKWISE,"ROTATE_180":cv2.ROTATE_180}
116 | P a g e
117 | P a g e
Image Smoothing
# Get the number of rows and columns in the image
rows, cols,_= lenna.shape
# Creates values using a normal distribution with a mean of 0 and standard
deviation of 15, the values are converted to unit8 which means the values are
between 0 and 255
noise = np.random.normal(0,15,(rows,cols,3)).astype(np.uint8)
# Add the noise to the image
noisy_image = lenna + noise
# Plots the original image and the image with noise using the function defined at
the top
plot_image(lenna, noisy_image, title_1="Orignal",title_2="Image Plus Noise")
118 | P a g e
def mean_blur(img, kernel=(5, 5)):
return blur
In [55]:
linkcode
image_mean=mean_blur(noisy_image, (5, 5))
119 | P a g e
120 | P a g e