tensorflow-keras-cpu-gpu/03. Popular image classific...

10 KiB

In [1]:
import os.path
import pickle

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

from jupyter_progressbar import ProgressBar
import numpy as np

from keras.models import Sequential
from keras.layers import Dense, Flatten, GlobalAveragePooling2D
from keras.optimizers import SGD
from keras import backend as K
from keras.applications.inception_v3 import preprocess_input as preprocess, InceptionV3

import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (20, 10)
matplotlib.rcParams['font.size'] = 24
matplotlib.rcParams['lines.linewidth'] = 5
matplotlib.rcParams['lines.markersize'] = 20

import tensorflow as tf
from tensorflow.python.client import device_lib

import time
from matplotlib import pyplot
from collections import defaultdict
from ipy_table import make_table, set_row_style, set_column_style
from jupyter_progressbar import ProgressBar

# Disable progressbar VGG-batches
ProgressBar = lambda x: x
Using TensorFlow backend.
In [2]:
devices = device_lib.list_local_devices()

make_table([["name", "type"]] + [
    [device.name, device.device_type]
    for device in devices
])
set_row_style(0, bold=True)
Out[2]:
nametype
/device:CPU:0CPU
/device:GPU:0GPU
In [3]:
with open('creepycrawly_and_cats.p3', 'rb') as f:
    X, y = pickle.load(f)
classes = ['creepy crawly', 'cat']
In [4]:
import numpy
from skimage.transform import resize

def resize_for_model(X, model):
    target = tuple([x.value for x in model.input.get_shape()][1:3])
    if target[0] is None or target[1] is None:
        return X
    result = numpy.zeros((X.shape[0], target[0], target[1], X.shape[3]), dtype=X.dtype)
    
    for i in range(X.shape[0]):
        result[i] = resize(X[i], target + (X.shape[3], ))
    return result
In [5]:
results = defaultdict(dict)
for device in devices:
    from keras.applications.inception_v3 import InceptionV3, preprocess_input, decode_predictions
    
    with tf.device(device.name):
        model = InceptionV3(weights='imagenet')
        X_ = preprocess_input(resize_for_model(X, model))
        t0 = time.time()
        preds = model.predict(X_, verbose=0)
        t1 = time.time()
    
    results[device.name]['inceptionv3'] = t1 - t0
    K.clear_session()
    
    from keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions
    with tf.device(device.name):
        model = ResNet50(weights='imagenet')
        X_ = preprocess_input(resize_for_model(X, model))
        t0 = time.time()
        preds = model.predict(X_, verbose=0)
        t1 = time.time()
    
    results[device.name]['resnet50'] = t1 - t0
    K.clear_session()

    vgg_batch_size = 2
    
    from keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
    with tf.device(device.name):
        model = VGG16(weights='imagenet', include_top=True)
        X_ = preprocess_input(resize_for_model(X, model))
        t0 = time.time()
        for start, end in zip(
            range(0, len(X), vgg_batch_size),
            ProgressBar(range(vgg_batch_size, len(X), vgg_batch_size))
        ):
            model.predict(X_[start:end], verbose=0)
        t1 = time.time()
    
    results[device.name]['vgg16'] = t1 - t0
    K.clear_session()
    
    from keras.applications.vgg19 import VGG19, preprocess_input, decode_predictions
    
    with tf.device(device.name):
        model = VGG19(weights='imagenet', include_top=True)
        X_ = preprocess_input(resize_for_model(X, model))
        t0 = time.time()
        for start, end in zip(
            range(0, len(X), vgg_batch_size),
            ProgressBar(range(vgg_batch_size, len(X), vgg_batch_size))
        ):
            model.predict(X_[start:end], verbose=0)
        t1 = time.time()
    
    results[device.name]['vgg19'] = t1 - t0
    K.clear_session()
In [6]:
model_names = list(next(iter(results.values())).keys())

make_table([["device"] + model_names] + [
    [device] + [result[model_name] for model_name in model_names]
    for device, result in results.items()
])
set_column_style(0, bold=True, align='right')
set_row_style(0, bold=True, align='right')
Out[6]:
deviceresnet50vgg19inceptionv3vgg16
/device:GPU:059.2201156.987515.0459129.3934
/device:CPU:0605.16311857.012689.15971445.7997