Deep Learning

Practice Projects

P4: Style Recognition

Step 0. Style and Libraries

Let's choose a style of the Jupyter notebook and import the software libraries.

The command hide_code will display or hide the code cells.

In [ ]:
%%html
<style>
@import url('https://fonts.googleapis.com/css?family=Orbitron|Roboto');
body {background-color: aliceblue;} 
a {color: #4876ff; font-family: 'Roboto';} 
h1 {color: #348ABD; font-family: 'Orbitron'; text-shadow: 4px 4px 4px #ccc;} 
h2, h3 {color: slategray; font-family: 'Roboto'; text-shadow: 4px 4px 4px #ccc;}
h4 {color: #348ABD; font-family: 'Orbitron';}
span {text-shadow: 4px 4px 4px #ccc;}
div.output_prompt, div.output_area pre {color: slategray;}
div.input_prompt, div.output_subarea {color: #4876ff;}      
div.output_stderr pre {background-color: aliceblue;}  
div.output_stderr {background-color: slategrey;}                        
</style>
<script>
code_show = true; 
function code_display() {
    if (code_show) {
        $('div.input').each(function(id) {
            if (id == 0 || $(this).html().indexOf('hide_code') > -1) {$(this).hide();}
        });
        $('div.output_prompt').css('opacity', 0);
    } else {
        $('div.input').each(function(id) {$(this).show();});
        $('div.output_prompt').css('opacity', 1);
    };
    code_show = !code_show;
} 
$(document).ready(code_display);
</script>
<form action="javascript: code_display()">
<input style="color: #348ABD; background: aliceblue; opacity: 0.8;" \ 
type="submit" value="Click to display or hide code cells">
</form> 
In [ ]:
hide_code = ''
import numpy as np 
import pandas as pd
import tensorflow as tf

from PIL import ImageFile
from tqdm import tqdm
import h5py
import cv2

import matplotlib.pylab as plt
from matplotlib import cm
import seaborn as sns
%matplotlib inline

from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier

from keras.utils import to_categorical
from keras.preprocessing import image as keras_image
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
from keras.preprocessing.image import ImageDataGenerator

from keras.models import Sequential, load_model, Model
from keras.layers import Input, BatchNormalization
from keras.layers import Dense, LSTM, GlobalAveragePooling1D, GlobalAveragePooling2D
from keras.layers import Activation, Flatten, Dropout
from keras.layers import Conv2D, MaxPooling2D, GlobalMaxPooling2D
from keras.layers.advanced_activations import PReLU, LeakyReLU

from keras.applications.inception_v3 import InceptionV3, preprocess_input
import scipy
from scipy import misc
In [ ]:
hide_code
plt.style.use('seaborn-whitegrid')

# Plot a fitting history for neural networks
def history_plot(fit_history, n):
    plt.figure(figsize=(18, 12))
    
    plt.subplot(211)
    plt.plot(fit_history.history['loss'][n:], color='slategray', label = 'train')
    plt.plot(fit_history.history['val_loss'][n:], color='#4876ff', label = 'valid')
    plt.xlabel("Epochs")
    plt.ylabel("Loss")
    plt.legend()
    plt.title('Loss Function');  
    
    plt.subplot(212)
    plt.plot(fit_history.history['acc'][n:], color='slategray', label = 'train')
    plt.plot(fit_history.history['val_acc'][n:], color='#4876ff', label = 'valid')
    plt.xlabel("Epochs")
    plt.ylabel("Accuracy")    
    plt.legend()
    plt.title('Accuracy');

Step 1. Load and Explore the Data

For this project, have made the database of photos sorted by products and brands.

The main dataset (style.zip) is 2184 color images (150x150x3) with 7 brands and 10 products, and the file with labels style.csv.

Photo files are in the .png format and the labels are integers and values.

Run the following cell to download the dataset.

In [ ]:
hide_code
# Function for processing an image
def image_to_tensor(img_path):
    img = keras_image.load_img("data/" + img_path, target_size=(150, 150))
    x = keras_image.img_to_array(img)
    return np.expand_dims(x, axis=0)
# Function for creating the data tensor
def data_to_tensor(img_paths):
    list_of_tensors = [image_to_tensor(img_path) for img_path in tqdm(img_paths)]
    return np.vstack(list_of_tensors)

ImageFile.LOAD_TRUNCATED_IMAGES = True 
In [ ]:
hide_code
# Load and display the data
data = pd.read_csv("data/style.csv")
data.head()

Visualize distributions of variables to have an imagination of the database.

In [ ]:
hide_code
# TODO: Plot the product distribution
In [ ]:
hide_code
# TODO: Plot the product distribution grouped by brand

Print out the brand_name and product_name unique values.

In [ ]:
hide_code
# Print unique values of brand names
set(data['brand_name'])
In [ ]:
hide_code
# Print unique values of product names
set(data['product_name'])

Let's create tensors of variables and display some examples of images.

In [ ]:
hide_code
# Create tensors
brands = data['brand_label'].values
products = data['product_label'].values
images = data_to_tensor(data['file']);
In [ ]:
hide_code
# Print the shape 
print ('Image shape:', images.shape)
print ('Brand shape', brands.shape)
print ('Product shape', products.shape)
In [ ]:
hide_code
# Read from files and display images using OpenCV
def display_images(img_path, ax):
    img = cv2.imread("data/" + img_path)
    ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    
fig = plt.figure(figsize=(18, 6))
for i in range(10):
    ax = fig.add_subplot(2, 5, i + 1, xticks=[], yticks=[], 
                         title=data['brand_name'][i*218]+' || '+data['product_name'][i*218])
    display_images(data['file'][i*218], ax)

Step 2. Save and Load the Data

The data tensors can be saved in the appropriate format of files .h5.

In [ ]:
hide_code
# Create the tensor file
with h5py.File('StyleColorImages.h5', 'w') as f:
    f.create_dataset('images', data = images)
    f.create_dataset('brands', data = brands)
    f.create_dataset('products', data = products)
    f.close()

The next time it is possible to start here with neural network's experiments.

In [ ]:
hide_code
# Read the h5 file
f = h5py.File('StyleColorImages.h5', 'r')

# List all groups
keys = list(f.keys())
keys
In [ ]:
hide_code
# Create tensors and targets
brands = np.array(f[keys[0]])
images = np.array(f[keys[1]])
products = np.array(f[keys[2]])

print ('Image shape:', images.shape)
print ('Brand shape', brands.shape)
print ('Product shape', products.shape)

Step 3. Implement Preprocess Functions

Normalize and Gray Scale

In the cell below, normalize the image tensors, and return them as a normalized numpy array.

In [ ]:
hide_code
# Normalize tensors
images = images.astype('float32')/255
In [ ]:
hide_code
# Read and display a tensor using Matplotlib
print('Product: ', data['product_name'][500])
print('Brand: ', data['brand_name'][500])
plt.figure(figsize=(3,3))
plt.imshow(images[500]);

Create tensors of grayscaled images and display their shape.

In [ ]:
hide_code
# Grayscaled tensors
gray_images = np.dot(images[...,:3], [0.299, 0.587, 0.114])
print ('Grayscaled Tensor shape:', gray_images.shape)
In [ ]:
hide_code
# Read and display a tensor using Matplotlib
print('Product: ', data['product_name'][500])
print('Brand: ', data['brand_name'][500])
plt.figure(figsize=(3,3))
plt.imshow(gray_images[500], cmap=cm.bone);

One-hot Encode

Now we'll implement the one-hot encoding function to_categorical.

In [ ]:
hide_code
# Print the brand unique values
print(set(brands))
In [ ]:
hide_code
# Print the product unique values
print(set(products))
In [ ]:
hide_code
# One-hot encode the brands
cat_brands = to_categorical(brands, 7)
cat_brands.shape
In [ ]:
hide_code
# One-hot encode the products
cat_products = to_categorical(products, 10)
cat_products.shape

Multi-Label Target

In [ ]:
hide_code
# Create multi-label targets
targets = np.concatenate((cat_brands, cat_products), axis=1)
targets.shape

Split

Apply the function train_test_split and split the data into training and testing sets. Set up the size of the testing set - 20%.

Color Images, Brand Target

In [ ]:
hide_code
# Split the data
x_train, x_test, y_train, y_test = train_test_split(images, cat_brands, 
                                                    test_size = 0.2, 
                                                    random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test)/2)
x_valid, y_valid = x_test[:n], y_test[:n]
x_test, y_test = x_test[n:], y_test[n:]
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train.shape)
print ("Training target's shape", y_train.shape)
print ("Validating tensor's shape:", x_valid.shape)
print ("Validating target's shape", y_valid.shape)
print ("Testing tensor's shape:", x_test.shape)
print ("Testing target's shape", y_test.shape)

Color Images, Product Target

In [ ]:
hide_code
# Split the data
x_train2, x_test2, y_train2, y_test2 = train_test_split(images, cat_products, 
                                                        test_size = 0.2, 
                                                        random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test2)/2)
x_valid2, y_valid2 = x_test2[:n], y_test2[:n]
x_test2, y_test2 = x_test2[n:], y_test2[n:]
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train2.shape)
print ("Training target's shape", y_train2.shape)
print ("Validating tensor's shape:", x_valid2.shape)
print ("Validating target's shape", y_valid2.shape)
print ("Testing tensor's shape:", x_test2.shape)
print ("Testing target's shape", y_test2.shape)

Color Images, Multi-Label Target

In [ ]:
hide_code
# Split the data
x_train3, x_test3, y_train3, y_test3 = train_test_split(images, targets, 
                                                        test_size = 0.2, 
                                                        random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test3)/2)
x_valid3, y_valid3 = x_test3[:n], y_test3[:n]
x_test3, y_test3 = x_test3[n:], y_test3[n:]
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train3.shape)
print ("Training target's shape", y_train3.shape)
print ("Validating tensor's shape:", x_valid3.shape)
print ("Validating target's shape", y_valid3.shape)
print ("Testing tensor's shape:", x_test3.shape)
print ("Testing target's shape", y_test3.shape)
In [ ]:
hide_code
# Create a list of targets
y_train3_list = [y_train3[:, :7], y_train3[:, 7:]]
y_test3_list = [y_test3[:, :7], y_test3[:, 7:]]
y_valid3_list = [y_valid3[:, :7], y_valid3[:, 7:]]

Grayscaled Images, Brand Target

In [ ]:
hide_code
# Split the data
x_train4, x_test4, y_train4, y_test4 = train_test_split(gray_images, cat_brands, 
                                                        test_size = 0.2, 
                                                        random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test4)/2)
x_valid4, y_valid4 = x_test4[:n], y_test4[:n]
x_test4, y_test4 = x_test4[n:], y_test4[n:]
In [ ]:
hide_code
# Reshape the grayscaled data
x_train4, x_test4, x_valid4 = \
x_train4.reshape(-1, 150, 150, 1), x_test4.reshape(-1, 150, 150, 1), x_valid4.reshape(-1, 150, 150, 1)
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train4.shape)
print ("Training target's shape", y_train4.shape)
print ("Validating tensor's shape:", x_valid4.shape)
print ("Validating target's shape", y_valid4.shape)
print ("Testing tensor's shape:", x_test4.shape)
print ("Testing target's shape", y_test4.shape)

Grayscaled Images, Product Target

In [ ]:
hide_code
# Split the data
x_train5, x_test5, y_train5, y_test5 = train_test_split(gray_images, cat_products, 
                                                        test_size = 0.2, 
                                                        random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test5)/2)
x_valid5, y_valid5 = x_test5[:n], y_test5[:n]
x_test5, y_test5 = x_test5[n:], y_test5[n:]
In [ ]:
hide_code
# Reshape the grayscaled data
x_train5, x_test5, x_valid5 = \
x_train5.reshape(-1, 150, 150, 1), x_test5.reshape(-1, 150, 150, 1), x_valid5.reshape(-1, 150, 150, 1)
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train5.shape)
print ("Training target's shape", y_train5.shape)
print ("Validating tensor's shape:", x_valid5.shape)
print ("Validating target's shape", y_valid5.shape)
print ("Testing tensor's shape:", x_test5.shape)
print ("Testing target's shape", y_test5.shape)

Grayscaled Images, Multi-Label Target

In [ ]:
hide_code
# Split the data
x_train6, x_test6, y_train6, y_test6 = train_test_split(gray_images, targets, 
                                                        test_size = 0.2, 
                                                        random_state = 1)
# Divide the test set into test and valid subsets
n = int(len(x_test6)/2)
x_valid6, y_valid6 = x_test6[:n], y_test6[:n]
x_test6, y_test6 = x_test6[n:], y_test6[n:]
In [ ]:
hide_code
# Reshape the grayscaled data
x_train6, x_test6, x_valid6 = \
x_train6.reshape(-1, 150, 150, 1), x_test6.reshape(-1, 150, 150, 1), x_valid6.reshape(-1, 150, 150, 1)
In [ ]:
hide_code
# Print the shape
print ("Training tensor's shape:", x_train6.shape)
print ("Training target's shape", y_train6.shape)
print ("Validating tensor's shape:", x_valid6.shape)
print ("Validating target's shape", y_valid6.shape)
print ("Testing tensor's shape:", x_test6.shape)
print ("Testing target's shape", y_test6.shape)
In [ ]:
hide_code
# Create a list of targets
y_train6_list = [y_train6[:, :7], y_train6[:, 7:]]
y_test6_list = [y_test6[:, :7], y_test6[:, 7:]]
y_valid6_list = [y_valid6[:, :7], y_valid6[:, 7:]]

Step 4. Create One-Label Classification Models

We should have an accuracy

  • greater than 14.3% for the first target (brand) and

  • greater than 10% for the second target (product).

Color Images, Brand Target

In [ ]:
hide_code
def cb_model():
    model = Sequential()
    # TODO: Define a model architecture


    
    # TODO: Compile the model

    return model

cb_model = cb_model()
In [ ]:
hide_code
# Create callbacks
cb_checkpointer = ModelCheckpoint(filepath='cb_model.styles.hdf5', 
                                  verbose=2, save_best_only=True)
cb_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                    patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
cb_history = cb_model.fit(x_train, y_train, 
                          epochs=30, batch_size=16, verbose=2,
                          validation_data=(x_valid, y_valid),
                          callbacks=[cb_checkpointer,cb_lr_reduction])
In [ ]:
hide_code
# Plot the training history
history_plot(cb_history, 0)
In [ ]:
hide_code
# Load the model with the best validation accuracy
cb_model.load_weights('cb_model.styles.hdf5')
# Calculate classification accuracy on the testing set
cb_score = cb_model.evaluate(x_test, y_test)
cb_score

Color Images, Product Target

In [ ]:
hide_code
def cp_model():
    model = Sequential()
    # TODO: Define a model architecture


    # TODO: Compile the model
    
    return model

cp_model = cp_model()
In [ ]:
hide_code
# Create callbacks
cp_checkpointer = ModelCheckpoint(filepath='cp_model.styles.hdf5', 
                                  verbose=2, save_best_only=True)
cp_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                    patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
cp_history = cp_model.fit(x_train2, y_train2, 
                          epochs=30, batch_size=16, verbose=2,
                          validation_data=(x_valid2, y_valid2),
                          callbacks=[cp_checkpointer,cp_lr_reduction])
In [ ]:
hide_code
# Plot the training history
history_plot(cp_history, 0)
In [ ]:
hide_code
# Load the model with the best validation accuracy
cp_model.load_weights('cp_model.styles.hdf5')
# Calculate classification accuracy on the testing set
cp_score = cp_model.evaluate(x_test2, y_test2)
cp_score

Grayscaled Images, Brand Target

In [ ]:
hide_code
def gray_cb_model():
    model = Sequential()
    
    # TODO: Define a model architecture

    
    # TODO: Compile the model

    return model

gray_cb_model = gray_cb_model()
In [ ]:
hide_code
# Create callbacks
gray_cb_checkpointer = ModelCheckpoint(filepath='gray_cb_model.styles.hdf5', 
                                       verbose=2, save_best_only=True)
gray_cb_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                         patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
gray_cb_history = gray_cb_model.fit(x_train4, y_train4, 
                                    epochs=30, batch_size=16, verbose=2,
                                    validation_data=(x_valid4, y_valid4),
                                    callbacks=[gray_cb_checkpointer])
In [ ]:
hide_code
# Plot the training history
history_plot(gray_cb_history, 0)
In [ ]:
hide_code
# Load the model with the best validation accuracy
gray_cb_model.load_weights('gray_cb_model.styles.hdf5')
# Calculate classification accuracy on the testing set
gray_cb_score = gray_cb_model.evaluate(x_test4, y_test4)
gray_cb_score

Grayscaled Images, Product Target

In [ ]:
hide_code
def gray_cp_model():
    model = Sequential()
    
    # TODO: Define a model architecture

    
    # TODO: Compile the model

    return model

gray_cp_model = gray_cp_model()
In [ ]:
hide_code
# Create callbacks
gray_cp_checkpointer = ModelCheckpoint(filepath='gray_cp_model.styles.hdf5', 
                                       verbose=2, save_best_only=True)
gray_cp_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                         patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
gray_cp_history = gray_cp_model.fit(x_train5, y_train5, 
                                    epochs=30, batch_size=16, verbose=2,
                                    validation_data=(x_valid5, y_valid5),
                                    callbacks=[gray_cp_checkpointer,gray_cp_lr_reduction])
In [ ]:
hide_code
# Plot the training history
history_plot(gray_cp_history, 0)
In [ ]:
hide_code
# Load the model with the best validation accuracy
gray_cp_model.load_weights('gray_cp_model.styles.hdf5')
# Calculate classification accuracy on the testing set
gray_cp_score = gray_cp_model.evaluate(x_test5, y_test5)
gray_cp_score

Step 5. Create Multi-Label Classification Models

Color Images, Multi-Label Target

In [ ]:
hide_code
def multi_model():    
    model_input = Input(shape=(150, 150, 3))
    x = BatchNormalization()(model_input)
    # TODO: Define a model architecture

    
    y1 = Dense(7, activation='softmax')(x)
    y2 = Dense(10, activation='softmax')(x)
    
    model = Model(inputs=model_input, outputs=[y1, y2])
    
    # TODO: Compile the model

    return model

multi_model = multi_model()
In [ ]:
hide_code
# Create callbacks
multi_checkpointer = ModelCheckpoint(filepath='multi_model.styles.hdf5', 
                                     verbose=2, save_best_only=True)
multi_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                       patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
multi_history = multi_model.fit(x_train3, y_train3_list, 
                                validation_data=(x_valid3, y_valid3_list), 
                                epochs=30, batch_size=16, verbose=0, 
                                callbacks=[multi_checkpointer])
In [ ]:
hide_code
# Load the model with the best validation accuracy
multi_model.load_weights('multi_model.styles.hdf5')
# Calculate classification accuracy on the testing set
multi_scores = multi_model.evaluate(x_test3, y_test3_list, verbose=0)

print("Scores: \n" , (multi_scores))
print("First label. Accuracy: %.2f%%" % (multi_scores[3]*100))
print("Second label. Accuracy: %.2f%%" % (multi_scores[4]*100))

Grayscaled Images, Multi-Label Target

In [ ]:
hide_code
def gray_multi_model():    
    model_input = Input(shape=(150, 150, 1))
    x = BatchNormalization()(model_input)
    # TODO: Define a model architecture
 
    
    y1 = Dense(7, activation='softmax')(x)
    y2 = Dense(10, activation='softmax')(x)
       
    model = Model(inputs=model_input, outputs=[y1, y2])
    # TODO: Compile the model
   
    return model

gray_multi_model = gray_multi_model()
In [ ]:
hide_code
# Create callbacks
gray_multi_checkpointer = ModelCheckpoint(filepath='gray_multi_model.styles.hdf5', 
                                          verbose=2, save_best_only=True)
gray_multi_lr_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                            patience=5, verbose=2, factor=0.2)
In [ ]:
hide_code
# Train the model
gray_multi_history = gray_multi_model.fit(x_train6, y_train6_list, 
                                          validation_data=(x_valid6, y_valid6_list), 
                                          epochs=30, batch_size=16, verbose=0, 
                                          callbacks=[gray_multi_checkpointer,
                                                     gray_multi_lr_reduction])
In [ ]:
hide_code
# Load the model with the best validation accuracy
gray_multi_model.load_weights('gray_multi_model.styles.hdf5')
# Calculate classification accuracy on the testing set
gray_multi_scores = gray_multi_model.evaluate(x_test6, y_test6_list, verbose=0)

print("Scores: \n" , (gray_multi_scores))
print("First label. Accuracy: %.2f%%" % (gray_multi_scores[3]*100))
print("Second label. Accuracy: %.2f%%" % (gray_multi_scores[4]*100))