%matplotlib inline
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session, get_session
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.9
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))
import sys
sys.path.append('/mnt/raid/cheetahs/modules/')
from inception.inception_resnet_v2 import InceptionResNetV2, preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Dense, Dropout, Input, concatenate
from keras.models import Model
from keras.optimizers import Nadam
from scipy.ndimage.interpolation import rotate
from sklearn.metrics import precision_recall_curve, classification_report, accuracy_score, confusion_matrix
import pandas as pd
import numpy as np
import itertools
import matplotlib.pyplot as plt
# Monkey-patch keras DirectoryIterator to also return filename
import keras
from keras_util.util import DirectoryIteratorWithFname
keras.preprocessing.image.DirectoryIterator = DirectoryIteratorWithFname
# Config
data_path = '/mnt/raid/cheetahs/data/train/'
val_data_path = '/mnt/raid/cheetahs/data/val/'
batch_size = 32
# Load and parse ImageNet class labels
classes = open('/mnt/raid/cheetahs/modules/imagenet_classes', 'r').readlines()
def strip(c):
key, value = c.split(':')
key = key.strip()
key = key.split('{')[-1]
value = value.split("'")[1].strip()
return int(key), value
classes = dict([strip(c) for c in classes])
izw_classes = ('unknown', 'cheetah', 'leopard')
metadata = pd.read_hdf('/mnt/raid/cheetahs/modules/metadata.hdf5')
metadata.head()
# Crop camera metainformation from images
def preprocess(data, rotate_range=None):
for x, y, fns in data:
batch_metadata = []
for fname in fns:
fname_splitted = fname.split('_')
index = fname_splitted[0]
rest = '_'.join(fname_splitted[1:]).split('.jpeg')[0]
f_metadata = metadata.iloc[int(index)]
batch_metadata.append((
f_metadata.ambient_temp,
f_metadata.hour))
# optionally use metadata
temperatures = np.array(batch_metadata).astype(np.float32)
x = x[:, 10:-10, 10:-10, :]
if rotate_range is not None:
for idx in range(batch_size):
x[idx] = rotate(x[idx], np.random.random() * rotate_range * 2 - rotate_range,
mode='reflect', reshape=False).astype(np.int64)
yield [preprocess_input(x), temperatures], y
# Augment train data with horizontal flips, scale to ImageNet input size
generator = ImageDataGenerator(horizontal_flip=True)
val_generator = ImageDataGenerator(horizontal_flip=False)
train_gen = preprocess(generator.flow_from_directory(
data_path,
target_size=(299+20, 299+20),
classes=izw_classes,
batch_size=batch_size), rotate_range=10)
val_gen = preprocess(val_generator.flow_from_directory(
val_data_path,
target_size=(299+20, 299+20),
classes=izw_classes,
batch_size=batch_size))
# Test data loader
plt.figure(figsize=(7, 7))
plt.imshow(1 - ((next(train_gen)[0][0][0] / 2) + .5) * 255, vmin=0, vmax=255)
# Load pretrained model
#
# http://arxiv.org/abs/1602.07261
#
# Inception-v4, Inception-ResNet and the Impact of Residual Connections
# on Learning
#
# Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
model = InceptionResNetV2()
# Test pretrained model on IZW data
batch, true_labels = next(val_gen)
fig, axes = plt.subplots(16, 2, figsize=(14, (14 / 2) * 16))
for idx, (image, label, true_label) in enumerate(zip(batch[0], model.predict(batch[0]), true_labels)):
r, c = divmod(idx, 2)
axes[r, c].imshow(1 - ((image / 2) + .5) * 255, vmin=0, vmax=255)
axes[r, c].set_title('P: {} ({:.1f}%) - L: {}'.format(
classes[label.argmax()],
label[label.argmax()] * 100,
izw_classes[true_label.argmax()]))
axes[r, c].grid('off')
axes[r, c].set_axis_off()