In [ ]:
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

Deep Learning Design Patterns - Code Labs

Lab Exercise #4 - Get Familiar with Data Preprocessing

Prerequistes:

1. Familiar with Python
2. Completed Chapter III: Training Foundation

Objectives:

1. Reading and Resizing Images
2. Assembling images into datasets
3. Setting the datatype
4. Normalizing/Standardizing images

Setup:

Install the additional relevant packages to get started with Keras/OpenCV, and then import them.


In [ ]:
# Install OpenCV computer vision package
!pip install -U opencv-python

# Import OpenCV 
import cv2
# We will also be using the numpy package in this code lab
import numpy as np

print(cv2.__version__)

Reading/Resizing Images

Let's read in an image and then resize it for input vector (for CNN) as 128x128.

You fill in the blanks (replace the ??), make sure it passes the Python interpreter, and then verify it's correctness with the summary output.

You will need to:

1. Set the parameter for reading an image in as color (RGB)

In [ ]:
from urllib.request import urlopen

# Let's read in the image as a color image
url = "https://github.com/GoogleCloudPlatform/keras-idiomatic-programmer/blob/master/books/deep-learning-design-patterns/Workshops/Novice/apple.jpg?raw=true"
request = urlopen(url)
img_array = np.asarray(bytearray(request.read()), dtype=np.uint8)
# HINT: the parameter value for a color image
image = cv2.imdecode(img_array, cv2.IMREAD_??)

# Let's verify we read it in correctly. We should see (584, 612, 3)
print(image.shape)

Resize it to 128 x 128

Okay, we see that the image is 584 (height) x 612 (width). Hum, that's not square. We could simply resize it to 128 x 128. But if we do that, the image will be skewed. Why? Because the original height and width are not the same, and if we resize them as-is to the same length, we will distort the aspect ratio,

So, let's refit the image into a square frame and then resize it.

You will need to:

1. Set the padding for the top and bottom.

In [ ]:
# Let's calculate the difference between width and height -- this should output 28
pad = (612 - 584)
print("pad size", pad)

# Split the padding evenly between the top and bottom
# HINT: even means half.
top = pad // ??
bottom = pad // ??
left = 0
right = 0

# Let's now make a copy of the image with the padded border.
# cv2.BORDER_CONSTANT means use a constant value for the padded border.
# [0, 0, 0] is the constant value (all black pixels)
color = [0, 0, 0]
image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, 
                               value=color)

# This should output (612, 612, 3)
print("padded image", image.shape)

In [ ]:
# Let's resize the image now to 128 x 128
# HINT: The tuple parameter is height x width
image = cv2.resize(image, (128, 128))

# This should output (128, 128, 3)
print("resized image", image.shape)

Assemblying into a dataset.

Let's read in a group of images, resize them to the same size and assembly into a dataset (i.e., a single numpy multidimensional array).

You will need to:

1. Specify the numpy method to convert a list to a numpy array.

In [ ]:
# Let's build a dataset of four images. We will start by using a list to append each image
# as it is read in.
images = []
for _ in range(4):
    # Let's pretend we are reading in different images and resizing them,
    # but instead we will just reuse our image from above.
    images.append(image)

# convert the list of images to a numpy multidimensional array
# HINT: use the method that converts list to numpy array
images = np.??(images)

# This should output (4, 128, 128, 3, where the 4 indicates this is a batch of 4 images.
print("dataset", images.shape)

Setting the Datatype

Next, we will set the data type of the pixel data to a single precision floating point value. That's a FLOAT32, which means 32 bits (which is 4 bytes).

You will need to:

1. Specify the data type for a 32-bit float.

In [ ]:
# Set the datatype to single precision float (FLOAT32)
# HINT: It is lowercased.
images = images.astype(np.??)

# This should output: 4
print("bytes per pixel", images.itemsize)

Normalizing/Standardizing the Pixel Data

Finally, we will standardize the pixel data:

1. Calculate the mean and standard deviation using numpy methods
2. Substract the mean from images and then divide by the standard deviation

You will need to:

1. Subtract the standard deviation

In [ ]:
# Calculate the mean value across all the pixels
mean = np.mean(images)
# Calculate the corresponding standard deviation
std  = np.std(images)

# Subtract the mean and divide by the standard deviation
# HINT: you calculate the standard deviation above.
n_images = (images - mean) / ??

# Let's print the before and after values:
# You should see: 177.9258 3.1789154e-07
print(mean, np.mean(n_images))

End of Lab Exercise