From 1a517ecd4564f1436c79e1945bb991b2e8423973 Mon Sep 17 00:00:00 2001 From: Tiago Freitas Pereira <tiagofrepereira@gmail.com> Date: Fri, 11 Nov 2016 17:08:33 +0100 Subject: [PATCH] DOcumenting --- bob/learn/tensorflow/datashuffler/Memory.py | 2 +- .../tensorflow/datashuffler/SiameseDisk.py | 7 +- .../tensorflow/datashuffler/TripletDisk.py | 10 +- .../tensorflow/network/SequenceNetwork.py | 4 +- bob/learn/tensorflow/network/VGG16_mod.py | 8 +- bob/learn/tensorflow/test/test_cnn.py | 69 ++++-------- bob/learn/tensorflow/test/test_cnn_load.py | 44 ++++++++ .../test/test_cnn_pretrained_model.py | 47 ++++++-- bob/learn/tensorflow/test/test_cnn_scratch.py | 7 +- .../tensorflow/test/test_datashuffler.py | 2 +- .../test/test_datashuffler_augmentation.py | 2 +- bob/learn/tensorflow/test/test_dnn.py | 50 ++++----- .../tensorflow/trainers/SiameseTrainer.py | 28 ++--- bob/learn/tensorflow/trainers/Trainer.py | 13 +-- .../tensorflow/trainers/TripletTrainer.py | 40 +++---- bob/learn/tensorflow/utils/session.py | 3 - doc/py_api.rst | 2 + doc/user_guide.rst | 105 +++++++++++++++--- 18 files changed, 274 insertions(+), 169 deletions(-) create mode 100644 bob/learn/tensorflow/test/test_cnn_load.py diff --git a/bob/learn/tensorflow/datashuffler/Memory.py b/bob/learn/tensorflow/datashuffler/Memory.py index 45e64404..1b9509e0 100644 --- a/bob/learn/tensorflow/datashuffler/Memory.py +++ b/bob/learn/tensorflow/datashuffler/Memory.py @@ -60,7 +60,7 @@ class Memory(Base): indexes = numpy.array(range(self.data.shape[0])) numpy.random.shuffle(indexes) - selected_data = self.data[indexes[0:self.batch_size], :, :, :] + selected_data = self.data[indexes[0:self.batch_size], ...] selected_labels = self.labels[indexes[0:self.batch_size]] # Applying the data augmentation diff --git a/bob/learn/tensorflow/datashuffler/SiameseDisk.py b/bob/learn/tensorflow/datashuffler/SiameseDisk.py index 03b4423d..52f64ee4 100644 --- a/bob/learn/tensorflow/datashuffler/SiameseDisk.py +++ b/bob/learn/tensorflow/datashuffler/SiameseDisk.py @@ -75,13 +75,10 @@ class SiameseDisk(Siamese, Disk): genuine = True for i in range(self.shape[0]): file_name, file_name_p = self.get_genuine_or_not(self.data, self.labels, genuine=genuine) - sample_l[i, ...] = self.load_from_file(str(file_name)) - sample_r[i, ...] = self.load_from_file(str(file_name_p)) + sample_l[i, ...] = self.normalize_sample(self.load_from_file(str(file_name))) + sample_r[i, ...] = self.normalize_sample(self.load_from_file(str(file_name_p))) labels_siamese[i] = not genuine genuine = not genuine - sample_l = self.normalize_sample(sample_l) - sample_r = self.normalize_sample(sample_r) - return sample_l, sample_r, labels_siamese diff --git a/bob/learn/tensorflow/datashuffler/TripletDisk.py b/bob/learn/tensorflow/datashuffler/TripletDisk.py index 2df05c08..fd117190 100644 --- a/bob/learn/tensorflow/datashuffler/TripletDisk.py +++ b/bob/learn/tensorflow/datashuffler/TripletDisk.py @@ -78,12 +78,8 @@ class TripletDisk(Triplet, Disk): for i in range(self.shape[0]): file_name_a, file_name_p, file_name_n = self.get_one_triplet(self.data, self.labels) - sample_a[i, ...] = self.load_from_file(str(file_name_a)) - sample_p[i, ...] = self.load_from_file(str(file_name_p)) - sample_n[i, ...] = self.load_from_file(str(file_name_n)) - - sample_a = self.normalize_sample(sample_a) - sample_p = self.normalize_sample(sample_p) - sample_n = self.normalize_sample(sample_n) + sample_a[i, ...] = self.normalize_sample(self.load_from_file(str(file_name_a))) + sample_p[i, ...] = self.normalize_sample(self.load_from_file(str(file_name_p))) + sample_n[i, ...] = self.normalize_sample(self.load_from_file(str(file_name_n))) return [sample_a, sample_p, sample_n] diff --git a/bob/learn/tensorflow/network/SequenceNetwork.py b/bob/learn/tensorflow/network/SequenceNetwork.py index fd727c1d..49af83b5 100644 --- a/bob/learn/tensorflow/network/SequenceNetwork.py +++ b/bob/learn/tensorflow/network/SequenceNetwork.py @@ -322,8 +322,8 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)): session = Session.instance().session self.sequence_net = pickle.loads(open(path+"_sequence_net.pickle").read()) - #saver = tf.train.import_meta_graph(path + ".meta", clear_devices=clear_devices) - saver = tf.train.import_meta_graph(path + ".meta") + saver = tf.train.import_meta_graph(path + ".meta", clear_devices=clear_devices) + #saver = tf.train.import_meta_graph(path + ".meta") saver.restore(session, path) self.inference_graph = tf.get_collection("inference_graph")[0] self.inference_placeholder = tf.get_collection("inference_placeholder")[0] diff --git a/bob/learn/tensorflow/network/VGG16_mod.py b/bob/learn/tensorflow/network/VGG16_mod.py index a3b7f187..bdfa4f89 100644 --- a/bob/learn/tensorflow/network/VGG16_mod.py +++ b/bob/learn/tensorflow/network/VGG16_mod.py @@ -71,10 +71,13 @@ class VGG16_mod(SequenceNetwork): default_feature_layer="fc8", seed=10, + + do_dropout=True, + use_gpu=False): super(VGG16_mod, self).__init__(default_feature_layer=default_feature_layer, - use_gpu=use_gpu) + use_gpu=use_gpu) # First convolutional block self.conv1_1_kernel_size = conv1_1_kernel_size @@ -223,6 +226,9 @@ class VGG16_mod(SequenceNetwork): )) self.add(AveragePooling(name="pooling5", strides=[1, 2, 2, 1])) + if do_dropout: + self.add(Dropout(name="dropout", keep_prob=0.4)) + self.add(FullyConnected(name="fc8", output_dim=n_classes, activation=None, weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), diff --git a/bob/learn/tensorflow/test/test_cnn.py b/bob/learn/tensorflow/test/test_cnn.py index 43f0ff5e..257258e1 100644 --- a/bob/learn/tensorflow/test/test_cnn.py +++ b/bob/learn/tensorflow/test/test_cnn.py @@ -8,12 +8,11 @@ from bob.learn.tensorflow.datashuffler import Memory, SiameseMemory, TripletMemo from bob.learn.tensorflow.network import Chopra from bob.learn.tensorflow.loss import BaseLoss, ContrastiveLoss, TripletLoss from bob.learn.tensorflow.trainers import Trainer, SiameseTrainer, TripletTrainer, constant +from .test_cnn_scratch import validate_network -# from ..analyzers import ExperimentAnalizer, SoftmaxAnalizer -from bob.learn.tensorflow.util import load_mnist +from bob.learn.tensorflow.utils import load_mnist import tensorflow as tf import bob.io.base -import os import shutil from scipy.spatial.distance import cosine import bob.measure @@ -28,7 +27,7 @@ iterations = 50 seed = 10 -def dummy_experiment(data_s, architecture, session): +def dummy_experiment(data_s, architecture): """ Create a dummy experiment and return the EER """ @@ -38,12 +37,12 @@ def dummy_experiment(data_s, architecture, session): # Extracting features for enrollment enroll_data, enroll_labels = data_shuffler.get_batch() - enroll_features = architecture(enroll_data, session=session) + enroll_features = architecture(enroll_data) del enroll_data # Extracting features for probing probe_data, probe_labels = data_shuffler.get_batch() - probe_features = architecture(probe_data, session=session) + probe_features = architecture(probe_data) del probe_data # Creating models @@ -102,26 +101,14 @@ def test_cnn_trainer(): prefetch=False, temp_dir=directory) trainer.train(train_data_shuffler) - del trainer #Just to clean tf.variables - with tf.Session() as session: + accuracy = validate_network(validation_data, validation_labels, architecture) - # Testing - chopra = Chopra(seed=seed, fc1_output=10) - chopra.load(session, os.path.join(directory, "model.ckp")) - - validation_data_shuffler = Memory(validation_data, validation_labels, - input_shape=[28, 28, 1], - batch_size=validation_batch_size) - - [data, labels] = validation_data_shuffler.get_batch() - predictions = chopra(data, session=session) - accuracy = 100. * numpy.sum(numpy.argmax(predictions, 1) == labels) / predictions.shape[0] - - # At least 80% of accuracy - assert accuracy > 80. - shutil.rmtree(directory) - del chopra + # At least 80% of accuracy + assert accuracy > 80. + shutil.rmtree(directory) + del trainer + del architecture def test_siamesecnn_trainer(): @@ -155,19 +142,15 @@ def test_siamesecnn_trainer(): temp_dir=directory) trainer.train(train_data_shuffler) - del trainer # Just to clean tf.variables - with tf.Session() as session: - # Testing - chopra = Chopra(seed=seed, fc1_output=10) - chopra.load(session, os.path.join(directory, "model.ckp")) + eer = dummy_experiment(validation_data_shuffler, architecture) - eer = dummy_experiment(validation_data_shuffler, chopra, session) + # At least 80% of accuracy + assert eer < 0.25 + shutil.rmtree(directory) - # At least 80% of accuracy - assert eer < 0.25 - shutil.rmtree(directory) - del chopra + del architecture + del trainer # Just to clean tf.variables def test_tripletcnn_trainer(): @@ -201,17 +184,13 @@ def test_tripletcnn_trainer(): temp_dir=directory) trainer.train(train_data_shuffler) - del trainer # Just to clean tf.variables - with tf.Session() as session: + # Testing + eer = dummy_experiment(validation_data_shuffler, architecture) - # Testing - chopra = Chopra(seed=seed, fc1_output=10) - chopra.load(session, os.path.join(directory, "model.ckp")) + # At least 80% of accuracy + assert eer < 0.25 + shutil.rmtree(directory) - eer = dummy_experiment(validation_data_shuffler, chopra, session) - - # At least 80% of accuracy - assert eer < 0.25 - shutil.rmtree(directory) - del chopra + del architecture + del trainer # Just to clean tf.variables diff --git a/bob/learn/tensorflow/test/test_cnn_load.py b/bob/learn/tensorflow/test/test_cnn_load.py new file mode 100644 index 00000000..02553e40 --- /dev/null +++ b/bob/learn/tensorflow/test/test_cnn_load.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : +# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch> +# @date: Thu 13 Oct 2016 13:35 CEST + + +""" +Some unit tests that create networks on the fly +""" + + +import numpy +import pkg_resources +from bob.learn.tensorflow.utils import load_mnist +from bob.learn.tensorflow.network import SequenceNetwork +from bob.learn.tensorflow.datashuffler import Memory + + +def validate_network(validation_data, validation_labels, network): + # Testing + validation_data_shuffler = Memory(validation_data, validation_labels, + input_shape=[28, 28, 1], + batch_size=400) + + [data, labels] = validation_data_shuffler.get_batch() + predictions = network.predict(data) + accuracy = 100. * numpy.sum(predictions == labels) / predictions.shape[0] + + return accuracy + +""" +def test_load_test_cnn(): + + _, _, validation_data, validation_labels = load_mnist() + + # Creating datashufflers + validation_data = numpy.reshape(validation_data, (validation_data.shape[0], 28, 28, 1)) + network = SequenceNetwork() + network.load(pkg_resources.resource_filename(__name__, 'data/cnn_mnist/model.ckp')) + + accuracy = validate_network(validation_data, validation_labels, network) + assert accuracy > 80 + del network +""" diff --git a/bob/learn/tensorflow/test/test_cnn_pretrained_model.py b/bob/learn/tensorflow/test/test_cnn_pretrained_model.py index b27a1e23..e8d4e90c 100644 --- a/bob/learn/tensorflow/test/test_cnn_pretrained_model.py +++ b/bob/learn/tensorflow/test/test_cnn_pretrained_model.py @@ -9,7 +9,10 @@ import os from bob.learn.tensorflow.datashuffler import Memory, ImageAugmentation from bob.learn.tensorflow.loss import BaseLoss from bob.learn.tensorflow.trainers import Trainer, constant -from bob.learn.tensorflow.util import load_mnist +from bob.learn.tensorflow.utils import load_mnist +from bob.learn.tensorflow.network import SequenceNetwork +from bob.learn.tensorflow.layers import Conv2D, FullyConnected + import tensorflow as tf import shutil @@ -22,10 +25,36 @@ validation_batch_size = 400 iterations = 50 seed = 10 -from test_cnn_scratch import scratch_network, validate_network + +def scratch_network(): + # Creating a random network + scratch = SequenceNetwork(default_feature_layer="fc1") + scratch.add(Conv2D(name="conv1", kernel_size=3, + filters=10, + activation=tf.nn.tanh, + batch_norm=False)) + scratch.add(FullyConnected(name="fc1", output_dim=10, + activation=None, + batch_norm=False + )) + + return scratch + + +def validate_network(validation_data, validation_labels, network): + # Testing + validation_data_shuffler = Memory(validation_data, validation_labels, + input_shape=[28, 28, 1], + batch_size=validation_batch_size) + + [data, labels] = validation_data_shuffler.get_batch() + predictions = network.predict(data) + accuracy = 100. * numpy.sum(predictions == labels) / predictions.shape[0] + + return accuracy -def test_cnn_trainer_scratch(): +def test_cnn_pretrained(): train_data, train_labels, validation_data, validation_labels = load_mnist() train_data = numpy.reshape(train_data, (train_data.shape[0], 28, 28, 1)) @@ -55,8 +84,7 @@ def test_cnn_trainer_scratch(): learning_rate=constant(0.05, name="lr"), temp_dir=directory) trainer.train(train_data_shuffler) - - accuracy = validate_network(validation_data, validation_labels, directory) + accuracy = validate_network(validation_data, validation_labels, scratch) assert accuracy > 85 del scratch @@ -77,7 +105,12 @@ def test_cnn_trainer_scratch(): trainer.train(train_data_shuffler) - accuracy = validate_network(validation_data, validation_labels, directory2) - assert accuracy > 85 + accuracy = validate_network(validation_data, validation_labels, scratch) + assert accuracy > 90 shutil.rmtree(directory) shutil.rmtree(directory2) + + del scratch + del loss + del trainer + diff --git a/bob/learn/tensorflow/test/test_cnn_scratch.py b/bob/learn/tensorflow/test/test_cnn_scratch.py index 242eac52..580985e7 100644 --- a/bob/learn/tensorflow/test/test_cnn_scratch.py +++ b/bob/learn/tensorflow/test/test_cnn_scratch.py @@ -7,12 +7,11 @@ import numpy import bob.io.base import os from bob.learn.tensorflow.datashuffler import Memory, ImageAugmentation -from bob.learn.tensorflow.initialization import Xavier, Constant from bob.learn.tensorflow.network import SequenceNetwork from bob.learn.tensorflow.loss import BaseLoss from bob.learn.tensorflow.trainers import Trainer from bob.learn.tensorflow.utils import load_mnist -from bob.learn.tensorflow.layers import Conv2D, FullyConnected, MaxPooling +from bob.learn.tensorflow.layers import Conv2D, FullyConnected import tensorflow as tf import shutil @@ -33,13 +32,9 @@ def scratch_network(): scratch.add(Conv2D(name="conv1", kernel_size=3, filters=10, activation=tf.nn.tanh, - weights_initialization=Xavier(seed=seed, use_gpu=False), - bias_initialization=Constant(use_gpu=False), batch_norm=False)) scratch.add(FullyConnected(name="fc1", output_dim=10, activation=None, - weights_initialization=Xavier(seed=seed, use_gpu=False), - bias_initialization=Constant(use_gpu=False), batch_norm=False )) diff --git a/bob/learn/tensorflow/test/test_datashuffler.py b/bob/learn/tensorflow/test/test_datashuffler.py index fb13e422..648fdbed 100644 --- a/bob/learn/tensorflow/test/test_datashuffler.py +++ b/bob/learn/tensorflow/test/test_datashuffler.py @@ -6,7 +6,7 @@ import numpy from bob.learn.tensorflow.datashuffler import Memory, SiameseMemory, TripletMemory, Disk, SiameseDisk, TripletDisk import pkg_resources -from ..util import load_mnist +from bob.learn.tensorflow.utils import load_mnist import os """ diff --git a/bob/learn/tensorflow/test/test_datashuffler_augmentation.py b/bob/learn/tensorflow/test/test_datashuffler_augmentation.py index 67de430d..ed1281dd 100644 --- a/bob/learn/tensorflow/test/test_datashuffler_augmentation.py +++ b/bob/learn/tensorflow/test/test_datashuffler_augmentation.py @@ -6,7 +6,7 @@ import numpy from bob.learn.tensorflow.datashuffler import Memory, SiameseMemory, TripletMemory, Disk, SiameseDisk, TripletDisk, ImageAugmentation import pkg_resources -from ..util import load_mnist +from bob.learn.tensorflow.utils import load_mnist import os """ diff --git a/bob/learn/tensorflow/test/test_dnn.py b/bob/learn/tensorflow/test/test_dnn.py index 613b744c..ddb5b0ff 100644 --- a/bob/learn/tensorflow/test/test_dnn.py +++ b/bob/learn/tensorflow/test/test_dnn.py @@ -8,13 +8,9 @@ from bob.learn.tensorflow.datashuffler import Memory from bob.learn.tensorflow.network import MLP from bob.learn.tensorflow.loss import BaseLoss from bob.learn.tensorflow.trainers import Trainer, constant -# from ..analyzers import ExperimentAnalizer, SoftmaxAnalizer -from bob.learn.tensorflow.util import load_mnist +from bob.learn.tensorflow.utils import load_mnist import tensorflow as tf -import bob.io.base -import os import shutil -import bob.measure """ Some unit tests for the datashuffler @@ -26,14 +22,25 @@ iterations = 200 seed = 10 +def validate_network(validation_data, validation_labels, network): + # Testing + validation_data_shuffler = Memory(validation_data, validation_labels, + input_shape=[784], + batch_size=validation_batch_size) + + [data, labels] = validation_data_shuffler.get_batch() + predictions = network.predict(data) + accuracy = 100. * numpy.sum(predictions == labels) / predictions.shape[0] + + return accuracy + + def test_dnn_trainer(): train_data, train_labels, validation_data, validation_labels = load_mnist() - train_data = numpy.reshape(train_data, (train_data.shape[0], 28, 28, 1)) - validation_data = numpy.reshape(validation_data, (validation_data.shape[0], 28, 28, 1)) # Creating datashufflers train_data_shuffler = Memory(train_data, train_labels, - input_shape=[28, 28, 1], + input_shape=[784], batch_size=batch_size) directory = "./temp/dnn" @@ -53,21 +60,12 @@ def test_dnn_trainer(): learning_rate=constant(0.05, name="dnn_lr"), temp_dir=directory) trainer.train(train_data_shuffler) - del trainer# Just to clean the variables - - with tf.Session() as session: - # Testing - mlp = MLP(10, hidden_layers=[15, 20]) - mlp.load(session, os.path.join(directory, "model.ckp")) - validation_data_shuffler = Memory(validation_data, validation_labels, - input_shape=[28, 28, 1], - batch_size=validation_batch_size) - - [data, labels] = validation_data_shuffler.get_batch() - predictions = mlp(data, session=session) - accuracy = 100. * numpy.sum(numpy.argmax(predictions, 1) == labels) / predictions.shape[0] - - # At least 50% of accuracy for the DNN - assert accuracy > 50. - shutil.rmtree(directory) - session.close() + + accuracy = validate_network(validation_data, validation_labels, architecture) + + # At least 50% of accuracy for the DNN + assert accuracy > 50. + shutil.rmtree(directory) + + del architecture + del trainer # Just to clean the variables diff --git a/bob/learn/tensorflow/trainers/SiameseTrainer.py b/bob/learn/tensorflow/trainers/SiameseTrainer.py index ad7b558a..7b3b3764 100644 --- a/bob/learn/tensorflow/trainers/SiameseTrainer.py +++ b/bob/learn/tensorflow/trainers/SiameseTrainer.py @@ -49,9 +49,6 @@ class SiameseTrainer(Trainer): temp_dir="cnn", # Learning rate - #base_learning_rate=0.001, - #weight_decay=0.9, - #decay_steps=1000, learning_rate=constant(), ###### training options ########## @@ -76,9 +73,6 @@ class SiameseTrainer(Trainer): temp_dir=temp_dir, # Learning rate - #base_learning_rate=base_learning_rate, - #weight_decay=weight_decay, - #decay_steps=decay_steps, learning_rate=learning_rate, ###### training options ########## @@ -207,7 +201,7 @@ class SiameseTrainer(Trainer): return feed_dict - def fit(self, session, step): + def fit(self, step): """ Run one iteration (`forward` and `backward`) @@ -217,19 +211,19 @@ class SiameseTrainer(Trainer): """ if self.prefetch: - _, l, bt_class, wt_class, lr, summary = session.run([self.optimizer, - self.training_graph, self.between_class_graph_train, self.within_class_graph_train, - self.learning_rate, self.summaries_train]) + _, l, bt_class, wt_class, lr, summary = self.session.run([self.optimizer, + self.training_graph, self.between_class_graph_train, self.within_class_graph_train, + self.learning_rate, self.summaries_train]) else: feed_dict = self.get_feed_dict(self.train_data_shuffler) - _, l, bt_class, wt_class, lr, summary = session.run([self.optimizer, + _, l, bt_class, wt_class, lr, summary = self.session.run([self.optimizer, self.training_graph, self.between_class_graph_train, self.within_class_graph_train, self.learning_rate, self.summaries_train], feed_dict=feed_dict) logger.info("Loss training set step={0} = {1}".format(step, l)) self.train_summary_writter.add_summary(summary, step) - def compute_validation(self, session, data_shuffler, step): + def compute_validation(self, data_shuffler, step): """ Computes the loss in the validation set @@ -245,9 +239,9 @@ class SiameseTrainer(Trainer): self.validation_graph = self.compute_graph(data_shuffler, name="validation", training=False) feed_dict = self.get_feed_dict(data_shuffler) - l, bt_class, wt_class = session.run([self.validation_graph, - self.between_class_graph_validation, self.within_class_graph_validation], - feed_dict=feed_dict) + l, bt_class, wt_class = self.session.run([self.validation_graph, + self.between_class_graph_validation, self.within_class_graph_validation], + feed_dict=feed_dict) summaries = [] summaries.append(summary_pb2.Summary.Value(tag="loss", simple_value=float(l))) @@ -268,7 +262,7 @@ class SiameseTrainer(Trainer): tf.scalar_summary('lr', self.learning_rate, name="train") return tf.merge_all_summaries() - def load_and_enqueue(self, session): + def load_and_enqueue(self): """ Injecting data in the place holder queue @@ -285,4 +279,4 @@ class SiameseTrainer(Trainer): placeholder_right_data: batch_right, placeholder_label: labels} - session.run(self.enqueue_op, feed_dict=feed_dict) + self.session.run(self.enqueue_op, feed_dict=feed_dict) diff --git a/bob/learn/tensorflow/trainers/Trainer.py b/bob/learn/tensorflow/trainers/Trainer.py index 47e4f54f..c648c7e4 100644 --- a/bob/learn/tensorflow/trainers/Trainer.py +++ b/bob/learn/tensorflow/trainers/Trainer.py @@ -306,7 +306,7 @@ class Trainer(object): """ - saver = self.architecture.load(self.session, self.model_from_file) + saver = self.architecture.load(self.model_from_file) # Loading training graph self.training_graph = tf.get_collection("training_graph")[0] @@ -357,21 +357,16 @@ class Trainer(object): logger.info("Initializing !!") - config = tf.ConfigProto(log_device_placement=True, - gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.333)) - config.gpu_options.allow_growth = True - # Pickle the architecture to save self.architecture.pickle_net(train_data_shuffler.deployment_shape) - #with tf.Session(config=config) as session: - + Session.create() self.session = Session.instance().session # Loading a pretrained model if self.model_from_file != "": logger.info("Loading pretrained model from {0}".format(self.model_from_file)) - saver = self.bootstrap_graphs_fromfile(self.session, train_data_shuffler, validation_data_shuffler) + saver = self.bootstrap_graphs_fromfile(train_data_shuffler, validation_data_shuffler) else: # Bootstraping all the graphs self.bootstrap_graphs(train_data_shuffler, validation_data_shuffler) @@ -408,7 +403,7 @@ class Trainer(object): for step in range(self.iterations): start = time.time() - self.fit(self.session, step) + self.fit(step) end = time.time() summary = summary_pb2.Summary.Value(tag="elapsed_time", simple_value=float(end-start)) self.train_summary_writter.add_summary(summary_pb2.Summary(value=[summary]), step) diff --git a/bob/learn/tensorflow/trainers/TripletTrainer.py b/bob/learn/tensorflow/trainers/TripletTrainer.py index 093bd45c..4c287a72 100644 --- a/bob/learn/tensorflow/trainers/TripletTrainer.py +++ b/bob/learn/tensorflow/trainers/TripletTrainer.py @@ -49,9 +49,6 @@ class TripletTrainer(Trainer): temp_dir="cnn", # Learning rate - #base_learning_rate=0.001, - #weight_decay=0.9, - #decay_steps=1000, learning_rate=constant(), ###### training options ########## @@ -76,9 +73,6 @@ class TripletTrainer(Trainer): temp_dir=temp_dir, # Learning rate - #base_learning_rate=base_learning_rate, - #weight_decay=weight_decay, - #decay_steps=decay_steps, learning_rate=learning_rate, ###### training options ########## @@ -213,7 +207,7 @@ class TripletTrainer(Trainer): return feed_dict - def fit(self, session, step): + def fit(self, step): """ Run one iteration (`forward` and `backward`) @@ -223,21 +217,21 @@ class TripletTrainer(Trainer): """ if self.prefetch: - _, l, bt_class, wt_class, lr, summary = session.run([self.optimizer, - self.training_graph, self.between_class_graph_train, - self.within_class_graph_train, self.learning_rate, - self.summaries_train]) + _, l, bt_class, wt_class, lr, summary = self.session.run([self.optimizer, + self.training_graph, self.between_class_graph_train, + self.within_class_graph_train, self.learning_rate, + self.summaries_train]) else: feed_dict = self.get_feed_dict(self.train_data_shuffler) - _, l, bt_class, wt_class, lr, summary = session.run([self.optimizer, - self.training_graph, self.between_class_graph_train, - self.within_class_graph_train, - self.learning_rate, self.summaries_train], - feed_dict=feed_dict) + _, l, bt_class, wt_class, lr, summary = self.session.run([self.optimizer, + self.training_graph, self.between_class_graph_train, + self.within_class_graph_train, + self.learning_rate, self.summaries_train], + feed_dict=feed_dict) logger.info("Loss training set step={0} = {1}".format(step, l)) self.train_summary_writter.add_summary(summary, step) - def compute_validation(self, session, data_shuffler, step): + def compute_validation(self, data_shuffler, step): """ Computes the loss in the validation set @@ -250,13 +244,13 @@ class TripletTrainer(Trainer): if self.validation_summary_writter is None: self.validation_summary_writter = tf.train.SummaryWriter(os.path.join(self.temp_dir, 'validation'), - session.graph) + self.session.graph) self.validation_graph = self.compute_graph(data_shuffler, name="validation", training=False) feed_dict = self.get_feed_dict(data_shuffler) - l, bt_class, wt_class = session.run([self.validation_graph, - self.between_class_graph_validation, self.within_class_graph_validation], - feed_dict=feed_dict) + l, bt_class, wt_class = self.session.run([self.validation_graph, + self.between_class_graph_validation, self.within_class_graph_validation], + feed_dict=feed_dict) summaries = [] summaries.append(summary_pb2.Summary.Value(tag="loss", simple_value=float(l))) @@ -277,7 +271,7 @@ class TripletTrainer(Trainer): tf.scalar_summary('lr', self.learning_rate, name="train") return tf.merge_all_summaries() - def load_and_enqueue(self, session): + def load_and_enqueue(self): """ Injecting data in the place holder queue @@ -294,4 +288,4 @@ class TripletTrainer(Trainer): placeholder_positive_data: batch_positive, placeholder_negative_data: batch_negative} - session.run(self.enqueue_op, feed_dict=feed_dict) + self.session.run(self.enqueue_op, feed_dict=feed_dict) diff --git a/bob/learn/tensorflow/utils/session.py b/bob/learn/tensorflow/utils/session.py index cd123bd5..a539eb32 100644 --- a/bob/learn/tensorflow/utils/session.py +++ b/bob/learn/tensorflow/utils/session.py @@ -15,6 +15,3 @@ class Session(object): gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.333)) config.gpu_options.allow_growth = True self.session = tf.Session() - - #def __del__(self): - # self.session.close() \ No newline at end of file diff --git a/doc/py_api.rst b/doc/py_api.rst index 576cedf4..99b9b0c7 100644 --- a/doc/py_api.rst +++ b/doc/py_api.rst @@ -2,6 +2,8 @@ .. Tiago de Freitas Pereira <laurent.el-shafey@idiap.ch> .. Tue 28 Aug 2012 18:09:40 CEST +.. _py_api: + ============ Python API ============ diff --git a/doc/user_guide.rst b/doc/user_guide.rst index e5732845..6f4fb7de 100644 --- a/doc/user_guide.rst +++ b/doc/user_guide.rst @@ -8,8 +8,8 @@ =========== -Getting started ---------------- +Quick start +----------- Before explain the base elements of this library, lets first do a simple example. The example consists in training a very simple **CNN** with `MNIST` dataset in 4 steps. @@ -48,18 +48,19 @@ The example consists in training a very simple **CNN** with `MNIST` dataset in 4 .. doctest:: - >>> with tf.Session() as session: - >>> # Loading the model - >>> architecture = bob.learn.tensorflow.network.SequenceNetwork() - >>> architecture.load(session, "./cnn/model.ckp") - >>> # Predicting - >>> predictions = scratch.predict(validation_data, session=session) - >>> # Computing an awesome accuracy for a simple network and 100 iterations - >>> accuracy = 100. * numpy.sum(predictions == validation_labels) / predictions.shape[0] - >>> print accuracy + >>> # Loading the model + >>> architecture = bob.learn.tensorflow.network.SequenceNetwork() + >>> architecture.load("./cnn/model.ckp") + >>> # Predicting + >>> predictions = scratch.predict(validation_data, session=session) + >>> # Computing an awesome accuracy for a simple network and 100 iterations + >>> accuracy = 100. * numpy.sum(predictions == validation_labels) / predictions.shape[0] + >>> print accuracy 90.4714285714 -Now lets describe each step in detail. + +Understanding what you have done +-------------------------------- Preparing your input data @@ -81,9 +82,9 @@ number of channels. Creating the architecture ......................... -Architectures are assembled as a :py:class:`bob.learn.tensorflow.network.SequenceNetwork` object. -Once the objects are created it is necessary to fill it up with `Layers`_. -The library has already some crafted networks implemented in `Architectures`_ +Architectures are assembled in the :py:class:`bob.learn.tensorflow.network.SequenceNetwork` object. +Once the objects are created it is necessary to fill it up with `Layers <py_api.html#layers>`_ +The library has already some crafted networks implemented in `Architectures <py_api.html#architectures>`_ Defining a loss and training @@ -99,6 +100,80 @@ As for the loss, we have specific trainers for Siamese (:py:class:`bob.learn.ten nd Triplet networks (:py:class:`bob.learn.tensorflow.trainers.TripletTrainer`). +Components in detail +-------------------- + +If you have reached this point it means that you want to understand a little bit more on how this library works. +The next sections give some details of each element. + +Data Shufflers +.............. + +As mentioned before, datasets are wrapped in **data shufflers**. +Data shufflers were designed to shuffle the input data for stochastic training. +It has one basic functionality which is :py:meth:`bob.learn.tensorflow.datashuffler.Base.get_batch` functionality. + +The shufflers are categorized with respect to: + 1. How the data is fetched + 2. The type of the trainer + 3. How the data is sampled + +How do you want to fetch your data? +``````````````````````````````````` + +The data can be fetched either from the memory (:py:class:`bob.learn.tensorflow.datashuffler.Memory`), as in out example, or from +disk (:py:class:`bob.learn.tensorflow.datashuffler.Disk`). +To train networks fetched from the disk, your training data must be a list of paths like in the example below: + +.. doctest:: + + >>> train_data = ['./file/id1_0.jpg', './file/id1_1.jpg', './file/id2_1.jpg'] + >>> train_labels = [0, 0, 1] + +With disk data shufflers, the data is loaded on the fly. + + +How is the shape of your trainer? +````````````````````````````````` + +Here we have one data shuffler for each type of the trainer. + +You will see in the section `Trainers`_ that we have three types of trainer. +The first one is the regular trainer, which deals with one graph only. +The data shuflers for this type of trainer must be a direct instance of either :py:class:`bob.learn.tensorflow.datashuffler.Memory` +or :py:class:`bob.learn.tensorflow.datashuffler.Disk`. + +The second one is the :py:class:`bob.learn.tensorflow.trainers.Siamese` trainer, which is designed to train Siamese networks. +The data shuflers for this type of trainer must be a direct instance of either + +The third one is the :py:class:`bob.learn.tensorflow.trainers.Triplet` trainer, which is designed to train Triplet networks. + + + +Architecture +............ + +Trainers +........ + + +Layers +...... + + +Initialization +.............. + + +Loss +.... + +Analyzers +......... + + + + Sandbox ------- -- GitLab