In [1]:
from __future__ import print_function
#Basic libraries
import numpy as np
import tensorflow as tf
import time
from os import listdir
from os.path import isfile, join
import random
#Show images
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 20) # size of images
plt.rcParams['image.interpolation'] = 'nearest' # show exact image
# Select GPU
import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="0"
data_path = '/home/ubuntu/data/training/image/cifar10/'
print('Tensorflow version: ', tf.__version__)
In [2]:
with open(data_path+'labels.txt') as f:
categories = f.read().splitlines()
print(categories)
In [3]:
# Examine the data
fig = plt.figure()
n=0
for i, category in enumerate(categories):
filelist = [f for f in listdir(join(data_path, 'train', category)) if isfile(join(data_path, 'train', category, f))]
random.shuffle(filelist) # Randomize images
for f in filelist[:5]:
n += 1
a = fig.add_subplot(10,5,n)
a.set_title(category)
img = plt.imread(join(data_path, 'train', category, f))
plt.imshow(img)
In [4]:
from tensorflow.contrib.keras import models, layers, optimizers, callbacks, preprocessing, regularizers
In [5]:
# Based on https://gist.github.com/JefferyRPrice/c1ecc3d67068c8d9b3120475baba1d7e
def residual_layer(input_tensor, nb_in_filters=64, nb_bottleneck_filters=16, filter_sz=3, stage=0, reg=0.0):
# batchnorm-relu-conv, from nb_in_filters to nb_bottleneck_filters via 1x1 conv
if stage>1: # first activation is just after conv1
x = layers.BatchNormalization(axis=-1, name='bn'+ str(stage)+'a')(input_tensor)
x = layers.Activation('relu', name='relu'+str(stage)+'a')(x)
else:
x = input_tensor
x = layers.Conv2D(nb_bottleneck_filters, (1, 1),
kernel_initializer='glorot_normal',
kernel_regularizer=regularizers.l2(reg),
use_bias=False,
name='conv'+str(stage)+'a')(x)
# batchnorm-relu-conv, from nb_bottleneck_filters to nb_bottleneck_filters via FxF conv
x = layers.BatchNormalization(axis=-1, name='bn'+ str(stage)+'b')(x)
x = layers.Activation('relu', name='relu'+str(stage)+'b')(x)
x = layers.Conv2D(nb_bottleneck_filters, (filter_sz, filter_sz),
padding='same',
kernel_initializer='glorot_normal',
kernel_regularizer=regularizers.l2(reg),
use_bias = False,
name='conv'+str(stage)+'b')(x)
# batchnorm-relu-conv, from nb_in_filters to nb_bottleneck_filters via 1x1 conv
x = layers.BatchNormalization(axis=-1, name='bn'+ str(stage)+'c')(x)
x = layers.Activation('relu', name='relu'+str(stage)+'c')(x)
x = layers.Conv2D(nb_in_filters, (1, 1),
kernel_initializer='glorot_normal',
kernel_regularizer=regularizers.l2(reg),
name='conv'+str(stage)+'c')(x)
# merge
x = layers.add([x, input_tensor], name='add'+str(stage))
return x
In [6]:
# Minimal example
sz_ly0_filters, nb_ly0_filters, nb_ly0_stride = (64,5,2)
sz_res_filters, nb_res_filters, nb_res_stages = (3,16,3)
# Complete example: 92% of accuracy
#sz_ly0_filters, nb_ly0_filters, nb_ly0_stride = (128,3,2)
#sz_res_filters, nb_res_filters, nb_res_stages = (3,32,25)
img_input = layers.Input(shape=(32,32,3), name='cifar')
# Initial conv layer
x = layers.Conv2D(sz_ly0_filters, (nb_ly0_filters,nb_ly0_filters),
strides=(nb_ly0_stride, nb_ly0_stride), padding='same',
kernel_initializer='glorot_normal',
kernel_regularizer=regularizers.l2(1.e-4),
use_bias=False, name='conv0')(img_input)
x = layers.BatchNormalization(axis=-1, name='bn0')(x)
x = layers.Activation('relu', name='relu0')(x)
x = layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding="same", name='maxp0')(x)
# Resnet layers
for stage in range(1, nb_res_stages+1):
x = residual_layer(x, nb_in_filters=64, nb_bottleneck_filters=nb_res_filters,
filter_sz=sz_res_filters, stage=stage,reg=0.0)
# Complete last resnet layer
x = layers.BatchNormalization(axis=-1, name='bnF')(x)
x = layers.Activation('relu', name='reluF')(x)
# Final layer
x = layers.AveragePooling2D((8, 8), name='avg_pool')(x)
x = layers.Flatten(name='flat')(x)
x = layers.Dense(10, activation='softmax', name='fc1')(x)
model1 = models.Model(inputs=img_input, outputs=x)
model1.summary()
In [5]:
# Extract images from directories
my_datagen = preprocessing.image.ImageDataGenerator()
train_generator = my_datagen.flow_from_directory(
join(data_path, 'train'),
target_size=(32, 32),
batch_size=50000)
test_generator = my_datagen.flow_from_directory(
join(data_path, 'test'),
target_size=(32, 32),
batch_size=10000)
X_train, y_train = next(train_generator)
X_test, y_test = next(test_generator)
In [6]:
# subtract mean and normalize
mean_image = np.mean(X_train, axis=0)
X_train -= mean_image
X_test -= mean_image
X_train /= 128.
X_test /= 128.
In [9]:
batch_size = 32
# Select optimizer and compile model
opt = optimizers.Adam(lr=1E-3)
model1.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
# Train
epochs = 30
tb_callback_ln = callbacks.TensorBoard(log_dir='/tmp/tensorboard/cifar10/resnet1')
history1 = model1.fit(X_train, y_train, batch_size=batch_size, epochs=epochs,
validation_data=(X_test, y_test), callbacks=[tb_callback_ln])
In [10]:
# Select optimizer and compile model
opt = optimizers.Adam(lr=1E-4)
model1.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
# Train
epochs = 10
history2 = model1.fit(X_train, y_train, batch_size=batch_size, epochs=epochs,
validation_data=(X_test, y_test), callbacks=[tb_callback_ln])
In [11]:
# Select optimizer and compile model
opt = optimizers.Adam(lr=1E-5)
model1.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
# Train
epochs = 10
history3 = model1.fit(X_train, y_train, batch_size=batch_size, epochs=epochs,
validation_data=(X_test, y_test), callbacks=[tb_callback_ln])
In [13]:
# Plot accuracy
plt.rcParams['figure.figsize'] = (10, 10) # size of images
plt.plot(history1.history['acc'] + history2.history['acc'] + history3.history['acc'], label='acc')
plt.plot(history1.history['val_acc'] + history2.history['val_acc'] + history3.history['val_acc'], label='val acc')
plt.legend(loc='lower right')
plt.show()
In [16]:
# Save model
model1.save('/tmp/cifar10_resnet1.h5')
In [17]:
# Load and test model
y_pred = model1.predict(X_test)
print(y_pred.shape)
In [22]:
# Score and select prediction with max prob
pred_test = np.argmax(y_pred, axis=1)
y_test_real = np.argmax(y_test, axis=1)
#Evaluate the confusion matrix
from sklearn.metrics import confusion_matrix
print(confusion_matrix(y_test_real, pred_test))
In [3]:
from tensorflow.contrib.keras import models, preprocessing
# Create generator of the test data with the correct transformation
test_datagen = preprocessing.image.ImageDataGenerator(rescale=1. / 255)
test_generator = test_datagen.flow_from_directory(
join(data_path, 'test'),
target_size=(32, 32),
batch_size=32)
# Load model
model_25 = models.load_model('cifar10_resnet_optimal.h5')
In [5]:
y_pred = model_25.predict_generator(test_generator, len(test_generator.filenames))
print(len(y_pred))
In [8]:
test_generator.batch_index
Out[8]:
In [7]:
#gen = image.ImageDataGenerator(shuffle=False, ...).flow_from_directory(...)
#y_pred = model_25.predict_generator(test_generator, len(test_generator.filenames))
X_test = []
y_test = []
batch_index = 0
while batch_index <= test_generator.batch_index:
x_b, y_b = test_generator.next()
X_test.append(x_b)
y_test.append(y_b)
batch_index = batch_index + 1
# now, data_array is the numeric data of whole images
X_test = np.asarray(X_test)
y_test = np.asarray(y_test)
print(X_test.shape)
print(y_test.shape)
In [17]:
#Evaluate the confusion matrix
from sklearn.metrics import confusion_matrix
pred_test = np.argmax(y_pred, axis=1)
real_test = np.argmax(y_test, axis=1)
print(confusion_matrix(real_test[:9968], pred_test[:9968]))
In [ ]:
# Example of errors
#Print probabilities to the first erros
test_errors=[]
test_errors_real=[]
test_errors_predict=[]
num_errors = 32
n = 0
for i in range(len(pred_test)):
if pred_test[i] != real_test[i] and n < num_errors: #Error!
n += 1
test_errors += [X_test[i,:,:]]
test_errors_real += [real_test[i]]
test_errors_predict += [pred_test[i]]
#Print first propabilities
index = y_pred[i].argsort()[::-1]
print('n: %2i - Pred 1: %1i(%0.3f) - Pred 2: %1i(%0.3f)' % (n,
index[0], y_pred[i][index[0]], index[1], y_pred[i][index[1]]))
print("Num errors: ", len(test_errors))
#Plot 32 images wrong classified.
fig = plt.figure()
for n, i in enumerate(range(32)):
a = fig.add_subplot(4, 8, n+1)
a.set_title('R:'+str(test_errors_real[i])+' - P:'+str(test_errors_predict[i]))
fig.tight_layout()
plt.imshow(test_errors[i])
In [ ]: