------------- User's settings -------------


In [ ]:
# Location of digested data
input_directory = '/digested/'

# Desired location to save temporary PNG outputs:
png_directory = '/digested_png/'

# Location of saved trained model
model_directory = '/model_directory/'

# Desired location for outputs
output_directory = '/output_directory_transferred/'

In [ ]:
# Define native shape of the transferred model (refer to model documentation)
shape=(197,197,3)

------------- (semi)-Automatic -------------


In [ ]:
%matplotlib inline
import keras
import keras.preprocessing.image
import pickle
from keras.layers import *
from keras.models import Sequential
import numpy
import os
import os.path

import matplotlib.pyplot
import pandas
import seaborn
import sklearn.metrics
import tensorflow

from tensorflow.contrib.tensorboard.plugins import projector

Configure GPU/CPU devices:


In [ ]:
# -------- If using Tensorflow-GPU: -------- #

configuration = tensorflow.ConfigProto()

configuration.gpu_options.allow_growth = True

configuration.gpu_options.visible_device_list = "0"

session = tensorflow.Session(config=configuration)

keras.backend.set_session(session)


# -------- If using Tensorflow (CPU) : -------- #

# configuration = tensorflow.ConfigProto()

# session = tensorflow.Session(config=configuration)

# keras.backend.set_session(session)

In [ ]:
if not os.path.exists(output_directory):
    os.makedirs(output_directory)

Load data:


In [ ]:
testing_x = numpy.load(os.path.join(input_directory, "testing_x.npy"))

testing_y = numpy.load(os.path.join(input_directory, "testing_y.npy"))

Stack single-channel images (maximum 3 channels) and store to PNG files


In [ ]:
%%capture
digest.save_png(testing_x, os.path.join(png_directory,"Testing") )

In [ ]:
testing_generator = keras.preprocessing.image.ImageDataGenerator()

testing_generator = testing_generator.flow_from_directory(
    batch_size=32,
    color_mode="rgb",
    directory= os.path.join(png_directory,"Testing"),
    target_size=(shape[0], shape[1])
)

Load trained model:

(can also load checkpoints)


In [ ]:
model = keras.models.load_model( os.path.join(model_directory, 'model.h5') )

In [ ]:
model.load_weights(os.path.join(model_directory, 'model.h5'))

Evaluate testing set


In [ ]:
model.evaluate_generator(
    generator=testing_generator, 
    steps=256
)

Extract the most crucial layer


In [ ]:
layers = model.layers

In [ ]:
model.summary()

Look for the densely/fully connected layer nearest to the classier, which is the one that has the shape of (None, number-of-classes)

==================================================================

Example 1: in case of classification of 7 classes, the last few layers are:


dense_1 (Dense) (None, 1024) 943820


dropout_1 (Dropout) (None, 1024) 0


dense_2 (Dense) (None, 7) 7175


activation_1 (Activation) (None, 7) 0

then look for the layer dense_1 , which has a shape of (None, 1024)

==================================================================

Example 2: in case of classification of 5 classes, the last few layers are:

activation_49 (Activation) (None, 8, 8, 2048) 0


avg_pool (AveragePooling2D) (None, 1, 1, 2048) 0


global_average_pooling2d_1 (Glob (None, 2048) 0


dense_2 (Dense) (None, 5) 10245

then look for the layer global_average_pooling2d_1 , which has a shape of (None, 2048)


In [ ]:
print(layers[-3])

In [ ]:
abstract_model = None # Clear cached abstract_model
abstract_model = Sequential([layers[-3]])

In [ ]:
abstract_model.summary()

In [ ]:
extracted_features = abstract_model.predict_generator(
    generator=testing_generator,
    steps=256)

Metadata for embeddings


In [ ]:
print('Converting numeric labels into class names...')

class_names = pickle.load(open(os.path.join(input_directory, "class_names.sav"), 'rb'))

def save_metadata(file):
    with open(file, 'w') as f:
        for i in range(test_y.shape[0]):
            f.write('{}\n'.format( class_names[test_y[i]] ))     

save_metadata( os.path.join(output_directory, 'metadata.tsv') )  

print('Done.')

Predicted values in .TXT

To be uploaded and viewed on http://projector.tensorflow.org


In [ ]:
numpy.savetxt( os.path.join(output_directory, 'table_of_features.txt' ), extracted_features, delimiter='\t')

Note:

Once finished, open http://projector.tensorflow.org on web-browser.

Click "Load data" on the left panel.

  • Step 1: Load a TSV file of vectors >> Choose file: 'table_of_features.txt'

  • Step 2: Load a TSV file of metadata >> Choose file: 'metadata.tsv'

Hit ESC or click outside the load data window to dismiss.

Predicted values in .NPY

Used for generating Tensorboard embeddings to be viewed locally on http://localhost:6006


In [ ]:
numpy.save( os.path.join(output_directory, 'table_of_features.npy' ), extracted_features )

In [ ]:
extracted_features = numpy.load( 'table_of_features.npy' )
embedding_var = tensorflow.Variable(extracted_features)

embedSess = tensorflow.Session()

# save variable in session
embedSess.run(embedding_var.initializer)

# save session (only used variable) to file
saver = tensorflow.train.Saver([embedding_var])
saver.save(embedSess, 'tf.ckpt')

summary_writer = tensorflow.summary.FileWriter('./')

config = tensorflow.contrib.tensorboard.plugins.projector.ProjectorConfig()
embedding = config.embeddings.add()
embedding.tensor_name = embedding_var.name
embedding.metadata_path = 'metadata.tsv' # this metadata_path need to be modified later. See note.
tensorflow.contrib.tensorboard.plugins.projector.visualize_embeddings(summary_writer, config)

embedSess.close()

Note:

Tensorboard embeddings files will be saved in the same location with this script.

Collect the following files into one folder:

  • metadata.tsv
  • checkpoint
  • projector_config.pbtxt
  • tf.ckpt.index
  • tf.ckpt.meta
  • tf.ckpt.data-00000-of-00001

Open with any text editor : "projector_config.pbtxt"

"/path/to/logdir/metadata.tsv" has to be specified, CANNOT be relative path "./metadata.tsv", nor "~/metadata.tsv"

Then type command in terminal: tensorboard --logdir="/path/to/logdir"

Next, open web-browser, connect to http://localhost:6006

Plot categorical accuracy and loss


In [ ]:
metrics = pandas.read_csv(os.path.join(model_directory, 'training.csv') )

In [ ]:
print(metrics)

In [ ]:
matplotlib.pyplot.plot(metrics["acc"])
matplotlib.pyplot.plot(metrics["val_acc"])

In [ ]:
matplotlib.pyplot.plot(metrics["loss"])
matplotlib.pyplot.plot(metrics["val_loss"])

Confusion matrix


In [ ]:
predicted = model.predict(
    batch_size=50,
    x=testing_x
)

predicted = numpy.argmax(predicted, -1)
expected = numpy.argmax(testing_y[:, :], -1)

In [ ]:
confusion = sklearn.metrics.confusion_matrix(expected, predicted)

confusion = pandas.DataFrame(confusion)

matplotlib.pyplot.figure(figsize=(12, 8))

seaborn.heatmap(confusion, annot=True)

matplotlib.pyplot.savefig( os.path.join(output_directory, 'confusion_matrix.eps') , format='eps', dpi=600)