Commit 8bc92f21 authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira
Browse files

Finished some milestones

parent 271e12b9
......@@ -8,9 +8,11 @@ Neural net work error rates analizer
"""
import numpy
import bob.measure
from tensorflow.core.framework import summary_pb2
from scipy.spatial.distance import cosine
class Analizer:
class ExperimentAnalizer:
"""
Analizer.
......@@ -21,7 +23,7 @@ class Analizer:
"""
def __init__(self, data_shuffler, machine, session):
def __init__(self, data_shuffler, machine, session, convergence_threshold=0.01, convergence_reference='eer'):
"""
Use the CNN as feature extractor for a n-class classification
......@@ -29,6 +31,10 @@ class Analizer:
data_shuffler:
graph:
session:
convergence_threshold:
convergence_reference: References to analize the convergence. Possible values are `eer`, `far10`, `far10`
"""
......@@ -49,8 +55,6 @@ class Analizer:
enroll_features = self.machine(enroll_data, session=self.session)
del enroll_data
#import ipdb; ipdb.set_trace();
# Extracting features for probing
probe_data, probe_labels = self.data_shuffler.get_batch()
probe_features = self.machine(probe_data, session=self.session)
......@@ -79,9 +83,9 @@ class Analizer:
n = [cosine(models[i], negative_data[j]) for j in range(negative_data.shape[0])]
negative_scores = numpy.hstack((negative_scores, n))
self.compute_stats((-1)*negative_scores, (-1) * positive_scores)
return self.__compute_tensorflow_summary((-1)*negative_scores, (-1) * positive_scores)
def compute_stats(self, negative_scores, positive_scores):
def __compute_tensorflow_summary(self, negative_scores, positive_scores):
"""
Compute some stats with the scores, such as:
- EER
......@@ -96,25 +100,31 @@ class Analizer:
positive_scores:
"""
summaries = []
# Compute EER
threshold = bob.measure.eer_threshold(negative_scores, positive_scores)
far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
eer = (far + frr) / 2.
summaries.append(summary_pb2.Summary.Value(tag="EER", simple_value=eer))
self.eer.append(eer)
# Computing FAR 10
threshold = bob.measure.far_threshold(negative_scores, positive_scores, far_value=0.1)
far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
summaries.append(summary_pb2.Summary.Value(tag="FAR 10", simple_value=frr))
self.far10.append(frr)
# Computing FAR 100
threshold = bob.measure.far_threshold(negative_scores, positive_scores, far_value=0.01)
far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
summaries.append(summary_pb2.Summary.Value(tag="FAR 100", simple_value=frr))
self.far100.append(frr)
# Computing FAR 1000
threshold = bob.measure.far_threshold(negative_scores, positive_scores, far_value=0.001)
far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
summaries.append(summary_pb2.Summary.Value(tag="FAR 1000", simple_value=frr))
self.far1000.append(frr)
return
return summary_pb2.Summary(value=summaries)
\ No newline at end of file
......@@ -34,6 +34,8 @@ class BaseDataShuffler(object):
self.data = data
self.shape = tuple([batch_size] + input_shape)
self.input_shape = tuple(input_shape)
self.labels = labels
self.possible_labels = list(set(self.labels))
......
......@@ -6,6 +6,7 @@
import numpy
import bob.io.base
import bob.io.image
import bob.ip.base
import tensorflow as tf
from .BaseDataShuffler import BaseDataShuffler
......@@ -27,12 +28,12 @@ class TextDataShuffler(BaseDataShuffler):
Shuffler that deal with file list
**Parameters**
data:
labels:
perc_train:
scale:
train_batch_size:
validation_batch_size:
data:
labels:
input_shape: Shape of the input. `input_shape != data.shape`, the data will be reshaped
input_dtype="float64":
scale=True:
batch_size=1:
"""
if isinstance(data, list):
......@@ -52,12 +53,15 @@ class TextDataShuffler(BaseDataShuffler):
def load_from_file(self, file_name, shape):
d = bob.io.base.load(file_name)
#import ipdb; ipdb.set_trace();
if len(d.shape) == 2:
data = numpy.zeros(shape=tuple(shape[1:]))
data = numpy.zeros(shape=(d.shape[0], d.shape[1], 1))
data[:, :, 0] = d
else:
data = d
data = self.rescale(data)
return data
def get_batch(self):
......@@ -80,6 +84,27 @@ class TextDataShuffler(BaseDataShuffler):
return selected_data.astype("float32"), selected_labels
def rescale(self, data):
"""
Reescale a single sample with input_shape
"""
if self.input_shape != data.shape:
# TODO: Implement a better way to do this reescaling
# If it is gray scale
if self.input_shape[2] == 1:
copy = data[:, :, 0].copy()
dst = numpy.zeros(shape=self.input_shape[0:2])
bob.ip.base.scale(copy, dst)
dst = numpy.reshape(dst, self.input_shape)
else:
dst = numpy.resize(data, self.input_shape) # Scaling with numpy, because bob is c,w,d instead of w,h,c
#bob.ip.base.scale(data, dst)
return dst
else:
return data
def get_pair(self, zero_one_labels=True):
"""
Get a random pair of samples
......
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @date: Wed 11 May 2016 09:39:36 CEST
"""
Class that creates the architecture presented in the paper:
Chopra, Sumit, Raia Hadsell, and Yann LeCun. "Learning a similarity metric discriminatively, with application to
face verification." 2005 IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR'05). Vol. 1. IEEE, 2005.
"""
import tensorflow as tf
from .SequenceNetwork import SequenceNetwork
from ..layers import Conv2D, FullyConnected, MaxPooling
import bob.learn.tensorflow
from bob.learn.tensorflow.initialization import Xavier
from bob.learn.tensorflow.initialization import Constant
class Chopra(SequenceNetwork):
def __init__(self,
conv1_kernel_size=7,
conv1_output=15,
conv2_kernel_size=6,
conv2_output=45,
conv3_kernel_size=5,
conv3_output=250,
fc6_output=50,
n_classes=40,
default_feature_layer="fc7",
seed=10,
use_gpu=False):
"""
Create all the necessary variables for this CNN
**Parameters**
conv1_kernel_size=5,
conv1_output=32,
conv2_kernel_size=5,
conv2_output=64,
conv3_kernel_size=5,
conv3_output=250,
fc6_output=50,
n_classes=10
seed = 10
"""
super(Chopra, self).__init__(default_feature_layer=default_feature_layer,
use_gpu=use_gpu)
self.add(Conv2D(name="conv1", kernel_size=conv1_kernel_size,
filters=conv1_output,
activation=tf.nn.tanh,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling1"))
self.add(Conv2D(name="conv2", kernel_size=conv2_kernel_size,
filters=conv2_output,
activation=tf.nn.tanh,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling2"))
self.add(Conv2D(name="conv3", kernel_size=conv3_kernel_size,
filters=conv3_output,
activation=tf.nn.tanh,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(FullyConnected(name="fc6", output_dim=fc6_output,
activation=tf.nn.tanh,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(FullyConnected(name="fc7", output_dim=n_classes,
activation=None,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)))
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @date: Wed 11 May 2016 09:39:36 CEST
"""
Summy architecture
"""
import tensorflow as tf
from .SequenceNetwork import SequenceNetwork
from ..layers import Conv2D, FullyConnected, MaxPooling
import bob.learn.tensorflow
from bob.learn.tensorflow.initialization import Xavier
from bob.learn.tensorflow.initialization import Constant
class Dummy(SequenceNetwork):
def __init__(self,
conv1_kernel_size=3,
conv1_output=1,
n_classes=2,
default_feature_layer="fc1",
seed=10,
use_gpu=False):
"""
Create all the necessary variables for this CNN
**Parameters**
conv1_kernel_size=3,
conv1_output=2,
n_classes=10
seed = 10
"""
super(Dummy, self).__init__(default_feature_layer=default_feature_layer,
use_gpu=use_gpu)
self.add(Conv2D(name="conv1", kernel_size=conv1_kernel_size,
filters=conv1_output,
activation=tf.nn.tanh,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(FullyConnected(name="fc1", output_dim=n_classes,
activation=None,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)))
......@@ -10,10 +10,11 @@ Class that creates the lenet architecture
import tensorflow as tf
import abc
import six
import numpy
import os
from collections import OrderedDict
from bob.learn.tensorflow.layers import Layer, MaxPooling, Dropout
from bob.learn.tensorflow.layers import Layer, MaxPooling, Dropout, Conv2D, FullyConnected
class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
......@@ -146,6 +147,65 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
self.sequence_net[k].b.assign(hdf5.read(self.sequence_net[k].b.name)).eval(session=session)
session.run(self.sequence_net[k].b)
def variable_summaries(self, var, name):
"""Attach a lot of summaries to a Tensor."""
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.scalar_summary('mean/' + name, mean)
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_sum(tf.square(var - mean)))
tf.scalar_summary('sttdev/' + name, stddev)
tf.scalar_summary('max/' + name, tf.reduce_max(var))
tf.scalar_summary('min/' + name, tf.reduce_min(var))
tf.histogram_summary(name, var)
def generate_summaries(self):
for k in self.sequence_net.keys():
current_layer = self.sequence_net[k]
if not isinstance(self.sequence_net[k], MaxPooling) and not isinstance(self.sequence_net[k], Dropout):
self.variable_summaries(current_layer.W, current_layer.name + '/weights')
self.variable_summaries(current_layer.b, current_layer.name + '/bias')
def compute_magic_number(self, hypothetic_image_dimensions=(28, 28, 1)):
"""
Here it is done an estimative of the capacity of CNN.
:param hypothetic_sample_number: an ar
:param hypothetic_image_dimensions:
:return:
"""
stride = 1# ALWAYS EQUALS TO ONE
current_image_dimensions = list(hypothetic_image_dimensions)
samples_per_sample = 0
flatten_dimension = numpy.prod(current_image_dimensions)
for k in self.sequence_net.keys():
current_layer = self.sequence_net[k]
if isinstance(current_layer, Conv2D):
#samples_per_sample += current_layer.filters * current_layer.kernel_size * current_image_dimensions[0] + current_layer.filters
#samples_per_sample += current_layer.filters * current_layer.kernel_size * current_image_dimensions[1] + current_layer.filters
samples_per_sample += current_layer.filters * current_image_dimensions[0] * current_image_dimensions[1] + current_layer.filters
current_image_dimensions[2] = current_layer.filters
flatten_dimension = numpy.prod(current_image_dimensions)
if isinstance(current_layer, MaxPooling):
current_image_dimensions[0] /= 2
current_image_dimensions[1] /= 2
flatten_dimension = current_image_dimensions[0] * current_image_dimensions[1] * current_image_dimensions[2]
if isinstance(current_layer, FullyConnected):
samples_per_sample += flatten_dimension * current_layer.output_dim + current_layer.output_dim
flatten_dimension = current_layer.output_dim
return samples_per_sample
#if self.saver is None:
# variables = self.dump_variables()
......
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @date: Wed 11 May 2016 09:39:36 CEST
"""
Class that creates the lenet architecture
"""
import tensorflow as tf
from .SequenceNetwork import SequenceNetwork
from ..layers import Conv2D, FullyConnected, MaxPooling
from bob.learn.tensorflow.initialization import Xavier
from bob.learn.tensorflow.initialization import Constant
class VGG(SequenceNetwork):
def __init__(self,
# First convolutional block
conv1_1_kernel_size=3,
conv1_1_output=64,
conv1_2_kernel_size=3,
conv1_2_output=64,
# Second convolutional block
conv2_1_kernel_size=3,
conv2_1_output=128,
conv2_2_kernel_size=3,
conv2_2_output=128,
# Third convolutional block
conv3_1_kernel_size=3,
conv3_1_output=256,
conv3_2_kernel_size=3,
conv3_2_output=256,
conv3_3_kernel_size=3,
conv3_3_output=256,
# Forth convolutional block
conv4_1_kernel_size=3,
conv4_1_output=512,
conv4_2_kernel_size=3,
conv4_2_output=512,
conv4_3_kernel_size=3,
conv4_3_output=512,
# Forth convolutional block
conv5_1_kernel_size=3,
conv5_1_output=512,
conv5_2_kernel_size=3,
conv5_2_output=512,
conv5_3_kernel_size=3,
conv5_3_output=512,
fc6_output=4096,
fc7_output=4096,
n_classes=10,
default_feature_layer="fc7",
seed=10,
use_gpu=False):
"""
Create all the necessary variables for this CNN
**Parameters**
conv1_kernel_size=5,
conv1_output=32,
conv2_kernel_size=5,
conv2_output=64,
fc1_output=400,
n_classes=10
seed = 10
"""
super(VGG, self).__init__(default_feature_layer=default_feature_layer,
use_gpu=use_gpu)
# First convolutional block
self.conv1_1_kernel_size = conv1_1_kernel_size
self.conv1_1_output = conv1_1_output
self.conv1_2_kernel_size = conv1_2_kernel_size
self.conv1_2_output = conv1_2_output
# Second convolutional block
self.conv2_1_kernel_size = conv2_1_kernel_size
self.conv2_1_output = conv2_1_output
self.conv2_2_kernel_size = conv2_2_kernel_size
self.conv2_2_output = conv2_2_output
# Third convolutional block
self.conv3_1_kernel_size = conv3_1_kernel_size
self.conv3_1_output = conv3_1_output
self.conv3_2_kernel_size = conv3_2_kernel_size
self.conv3_2_output = conv3_2_output
self.conv3_3_kernel_size = conv3_3_kernel_size
self.conv3_3_output = conv3_3_output
# Forth convolutional block
self.conv4_1_kernel_size = conv4_1_kernel_size
self.conv4_1_output = conv4_1_output
self.conv4_2_kernel_size = conv4_2_kernel_size
self.conv4_2_output = conv4_2_output
self.conv4_3_kernel_size = conv4_3_kernel_size
self.conv4_3_output = conv4_3_output
# Forth convolutional block
self.conv5_1_kernel_size = conv5_1_kernel_size
self.conv5_1_output = conv5_1_output
self.conv5_2_kernel_size = conv5_2_kernel_size
self.conv5_2_output = conv5_2_output
self.conv5_3_kernel_size = conv5_3_kernel_size
self.conv5_3_output = conv5_3_output
self.fc6_output = fc6_output
self.fc7_output = fc7_output
self.n_classes = n_classes
# First convolutional
self.add(Conv2D(name="conv1_1", kernel_size=conv1_1_kernel_size,
filters=conv1_1_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv1_2", kernel_size=conv1_2_kernel_size,
filters=conv2_1_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling1"))
# Second convolutional
self.add(Conv2D(name="conv2_1", kernel_size=conv2_1_kernel_size,
filters=conv2_1_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv2_2", kernel_size=conv2_2_kernel_size,
filters=conv2_2_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling2"))
# Third convolutional
self.add(Conv2D(name="conv3_1", kernel_size=conv3_1_kernel_size,
filters=conv3_1_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv3_2", kernel_size=conv3_2_kernel_size,
filters=conv3_2_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv3_3", kernel_size=conv3_3_kernel_size,
filters=conv3_3_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling3"))
# Forth convolutional
self.add(Conv2D(name="conv4_1", kernel_size=conv4_1_kernel_size,
filters=conv4_1_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv4_2", kernel_size=conv4_2_kernel_size,
filters=conv4_2_output,
activation=tf.nn.relu,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(Conv2D(name="conv4_3", kernel_size=conv4_3_kernel_size,
filters=conv4_3_output,