Documenting

parent f9965fd8
......@@ -51,19 +51,21 @@ class TextDataShuffler(BaseDataShuffler):
batch_size=batch_size
)
# TODO: very bad solution to deal with bob.shape images an tf shape images
self.bob_shape = tuple([input_shape[2]] + list(input_shape[0:2]))
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:
if d.shape[0] != 3 and self.input_shape[2] != 3: # GRAY SCALE IMAGE
data = numpy.zeros(shape=(d.shape[0], d.shape[1], 1))
data[:, :, 0] = d
data = self.rescale(data)
else:
d = self.rescale(d)
data = self.bob2skimage(d)
return data
def bob2skimage(self, bob_image):
"""
Convert bob color image to the skcit image
......@@ -71,9 +73,9 @@ class TextDataShuffler(BaseDataShuffler):
skimage = numpy.zeros(shape=(bob_image.shape[1], bob_image.shape[2], 3))
skimage[:,:,0] = bob_image[0,:,:] #Copying red
skimage[:,:,1] = bob_image[1,:,:] #Copying green
skimage[:,:,2] = bob_image[2,:,:] #Copying blue
skimage[:, :, 0] = bob_image[0, :, :] #Copying red
skimage[:, :, 1] = bob_image[1, :, :] #Copying green
skimage[:, :, 2] = bob_image[2, :, :] #Copying blue
return skimage
......@@ -102,7 +104,9 @@ class TextDataShuffler(BaseDataShuffler):
Reescale a single sample with input_shape
"""
if self.input_shape != data.shape:
#if self.input_shape != data.shape:
if self.bob_shape != data.shape:
# TODO: Implement a better way to do this reescaling
# If it is gray scale
if self.input_shape[2] == 1:
......@@ -111,8 +115,18 @@ class TextDataShuffler(BaseDataShuffler):
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)
#dst = numpy.resize(data, self.bob_shape) # Scaling with numpy, because bob is c,w,d instead of w,h,c
dst = numpy.zeros(shape=self.bob_shape)
# TODO: LAME SOLUTION
if data.shape[0] != 3: # GRAY SCALE IMAGES IN A RGB DATABASE
step_data = numpy.zeros(shape=(3, data.shape[0], data.shape[1]))
step_data[0, ...] = data[:, :]
step_data[1, ...] = data[:, :]
step_data[2, ...] = data[:, :]
data = step_data
bob.ip.base.scale(data, dst)
return dst
else:
......@@ -176,4 +190,3 @@ class TextDataShuffler(BaseDataShuffler):
data_n *= self.scale_value
return data_a, data_p, data_n
......@@ -59,7 +59,6 @@ class Conv2D(Layer):
name="w_" + str(self.name)
)
if self.activation is not None:
self.b = self.bias_initialization(shape=[self.filters],
name="b_" + str(self.name) + "bias")
......@@ -69,9 +68,8 @@ class Conv2D(Layer):
conv2d = tf.nn.conv2d(self.input_layer, self.W, strides=[1, 1, 1, 1], padding='SAME')
if self.activation is not None:
non_linear_conv2d = self.activation(tf.nn.bias_add(conv2d, self.b))
output = non_linear_conv2d
output = self.activation(tf.nn.bias_add(conv2d, self.b))
else:
output = conv2d
output = tf.nn.bias_add(conv2d, self.b)
return output
......@@ -10,11 +10,11 @@ from .Layer import Layer
class MaxPooling(Layer):
def __init__(self, name, shape=[1, 2, 2, 1]):
def __init__(self, name, shape=[1, 2, 2, 1], activation=None):
"""
Constructor
"""
super(MaxPooling, self).__init__(name, use_gpu=False)
super(MaxPooling, self).__init__(name, use_gpu=False, activation=activation)
self.shape = shape
def create_variables(self, input_layer):
......@@ -25,4 +25,7 @@ class MaxPooling(Layer):
with tf.name_scope(str(self.name)):
output = tf.nn.max_pool(self.input_layer, ksize=self.shape, strides=[1, 1, 1, 1], padding='SAME')
if self.activation is not None:
output = self.activation(output)
return output
......@@ -4,23 +4,6 @@
# @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.
This is modifield version of the original architecture.
It is inspired on https://gitlab.idiap.ch/bob/xfacereclib.cnn/blob/master/lua/network.lua
-- C1 : Convolutional, kernel = 7x7 pixels, 15 feature maps
-- M2 : MaxPooling, 2x2
-- HT : Hard Hyperbolic Tangent
-- C3 : Convolutional, kernel = 6x6 pixels, 45 feature maps
-- M4 : MaxPooling, 4x3
-- HT : Hard Hyperbolic Tangent
-- R : Reshaping layer HT 5x5 => 25 (45 times; once for each feature map)
-- L5 : Linear 25 => 250
"""
......@@ -33,7 +16,49 @@ from bob.learn.tensorflow.initialization import Constant
class Chopra(SequenceNetwork):
"""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.
This is modifield version of the original architecture.
It is inspired on https://gitlab.idiap.ch/bob/xfacereclib.cnn/blob/master/lua/network.lua
-- C1 : Convolutional, kernel = 7x7 pixels, 15 feature maps
-- M2 : MaxPooling, 2x2
-- HT : Hard Hyperbolic Tangent
-- C3 : Convolutional, kernel = 6x6 pixels, 45 feature maps
-- M4 : MaxPooling, 4x3
-- HT : Hard Hyperbolic Tangent
-- R : Reshaping layer HT 5x5 => 25 (45 times; once for each feature map)
-- L5 : Linear 25 => 250
**Parameters**
conv1_kernel_size:
conv1_output:
pooling1_size:
conv2_kernel_size:
conv2_output:
pooling2_size
fc1_output:
seed:
"""
def __init__(self,
conv1_kernel_size=7,
conv1_output=15,
......@@ -51,42 +76,25 @@ class Chopra(SequenceNetwork):
seed=10,
use_gpu=False):
"""
Create all the necessary variables for this CNN
**Parameters**
conv1_kernel_size=5,
conv1_output=32,
pooling1_size=[1, 2, 2, 1],
conv2_kernel_size=5,
conv2_output=64,
pooling2_size=[1, 4, 3, 1],
fc1_output=50,
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,
activation=None,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling1", shape=pooling1_size))
self.add(MaxPooling(name="pooling1", shape=pooling1_size, activation=tf.nn.tanh))
self.add(Conv2D(name="conv2", kernel_size=conv2_kernel_size,
filters=conv2_output,
activation=tf.nn.tanh,
activation=None,
weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
bias_initialization=Constant(use_gpu=self.use_gpu)
))
self.add(MaxPooling(name="pooling2", shape=pooling2_size))
self.add(MaxPooling(name="pooling2", shape=pooling2_size, activation=tf.nn.tanh))
self.add(FullyConnected(name="fc1", output_dim=fc1_output,
activation=None,
......
......@@ -15,7 +15,36 @@ from bob.learn.tensorflow.initialization import Constant
class MLP(SequenceNetwork):
"""An MLP is a representation of a Multi-Layer Perceptron.
This implementation is feed-forward and fully-connected.
The implementation allows setting a global and the output activation functions.
References to fully-connected feed-forward networks: Bishop's Pattern Recognition and Machine Learning, Chapter 5. Figure 5.1 shows what is programmed.
MLPs normally are multi-layered systems, with 1 or more hidden layers.
**Parameters**
output_shape: number of neurons in the output.
hidden_layers: :py:class:`list` that contains the amount of hidden layers, where each element is the number of neurons
hidden_activation: Activation function of the hidden layers. Possible values can be seen
`here <https://www.tensorflow.org/versions/r0.11/api_docs/python/nn.html#activation-functions>`_.
If you set to ``None``, the activation will be linear.
output_activation: Activation of the output layer. If you set to `None`, the activation will be linear
weights_initialization: How you will initialize the neurons.
See :py:mod:`bob.learn.tensorflow.initialization`.
bias_initialization: How you will initialize the biases.
See :py:mod:`bob.learn.tensorflow.initialization`.
use_gpu: If ``True`` uses the GPU in the computation
seed = 10
"""
def __init__(self,
output_shape,
hidden_layers=[10],
......@@ -24,16 +53,6 @@ class MLP(SequenceNetwork):
weights_initialization=Xavier(),
bias_initialization=Constant(),
use_gpu=False):
"""
Create all the necessary variables for this CNN
**Parameters**
output_shape: Shape of the output
hidden_layers: List that contains the amount of hidden layers, where each element is the number of neurons
hidden_activation: Activation function of the hidden layer. If you set to `None`, the activation will be linear
output_activation: Activation of the output layer. If you set to `None`, the activation will be linear
seed = 10
"""
super(MLP, self).__init__(use_gpu=use_gpu)
if (not (isinstance(hidden_layers, list) or isinstance(hidden_layers, tuple))) or len(hidden_layers) == 0:
......
......@@ -3,9 +3,6 @@
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @date: Thu 11 Aug 2016 09:39:36 CEST
"""
Class that creates the lenet architecture
"""
import tensorflow as tf
import abc
......@@ -19,29 +16,28 @@ from bob.learn.tensorflow.layers import Layer, MaxPooling, Dropout, Conv2D, Full
class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
"""
Base class to create architectures using TensorFlow
Sequential model is a linear stack of :py:mod:`bob.learn.tensorflow.layers`.
**Parameters**
default_feature_layer: Default layer name (:py:obj:`str`) used as a feature layer.
use_gpu: If ``True`` uses the GPU in the computation.
"""
def __init__(self,
default_feature_layer=None,
use_gpu=False):
"""
Base constructor
**Parameters**
feature_layer:
"""
self.sequence_net = OrderedDict()
self.default_feature_layer = default_feature_layer
self.input_divide = 1.
self.input_subtract = 0.
self.use_gpu=use_gpu
#self.saver = None
self.use_gpu = use_gpu
def add(self, layer):
"""
Add a layer in the sequence network
Add a :py:class:`bob.learn.tensorflow.layers.Layer` in the sequence network
"""
if not isinstance(layer, Layer):
......@@ -49,12 +45,16 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
self.sequence_net[layer.name] = layer
def compute_graph(self, input_data, feature_layer=None, training=True):
"""
Given the current network, return the Tensorflow graph
"""Given the current network, return the Tensorflow graph
**Parameter**
input_data:
cut: Name of the layer that you want to cut.
input_data: tensorflow placeholder as input data
feature_layer: Name of the :py:class:`bob.learn.tensorflow.layer.Layer` that you want to "cut".
If `None` will run the graph until the end.
training: If `True` will generating the graph for training
"""
input_offset = input_data
......@@ -71,9 +71,26 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
return input_offset
def compute_projection_graph(self, placeholder):
"""Generate a graph for feature extraction
**Parameters**
placeholder: tensorflow placeholder as input data
"""
return self.compute_graph(placeholder)
def __call__(self, data, session=None, feature_layer=None):
"""Run a graph
**Parameters**
data: tensorflow placeholder as input data
session: tensorflow `session <https://www.tensorflow.org/versions/r0.11/api_docs/python/client.html#Session>`_
feature_layer: Name of the :py:class:`bob.learn.tensorflow.layer.Layer` that you want to "cut".
If `None` will run the graph until the end.
"""
if session is None:
session = tf.Session()
......@@ -88,6 +105,9 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
return session.run([self.compute_graph(feature_placeholder, feature_layer, training=False)], feed_dict=feed_dict)[0]
def dump_variables(self):
"""Return all the tensorflow `variables <https://www.tensorflow.org/versions/r0.11/api_docs/python/state_ops.html#Variable>`_ used in the graph
"""
variables = {}
for k in self.sequence_net:
......@@ -99,8 +119,14 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
return variables
def save(self, hdf5, step=None):
"""
Save the state of the network in HDF5 format
"""Save the state of the network in HDF5 format
**Parameters**
hdf5: An opened :py:class:`bob.io.base.HDF5File`
step: The current training step. If not `None`, will create a HDF5 group with the current step.
"""
# Directory that stores the tensorflow variables
......@@ -124,6 +150,16 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
hdf5.set('input_subtract', self.input_subtract)
def load(self, hdf5, shape, session=None):
"""Load the network
**Parameters**
hdf5: The saved network in the :py:class:`bob.io.base.HDF5File` format
shape: Input shape of the network
session: tensorflow `session <https://www.tensorflow.org/versions/r0.11/api_docs/python/client.html#Session>`_
"""
if session is None:
session = tf.Session()
......@@ -160,7 +196,6 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
tf.histogram_summary(name, var)
def generate_summaries(self):
for k in self.sequence_net.keys():
current_layer = self.sequence_net[k]
......@@ -171,15 +206,14 @@ class SequenceNetwork(six.with_metaclass(abc.ABCMeta, object)):
def compute_magic_number(self, hypothetic_image_dimensions=(28, 28, 1)):
"""
Here it is done an estimative of the capacity of CNN.
Here it is done an estimative of the capacity of DNN.
:param hypothetic_sample_number: an ar
:param hypothetic_image_dimensions:
:return:
**Parameters**
hypothetic_image_dimensions: Possible image dimentions `w, h, c` (width x height x channels)
"""
stride = 1# ALWAYS EQUALS TO ONE
current_image_dimensions = list(hypothetic_image_dimensions)
samples_per_sample = 0
......
......@@ -145,4 +145,3 @@ def main():
iterations=ITERATIONS,
snapshot=VALIDATION_TEST)
trainer.train(train_data_shuffler, validation_data_shuffler)
......@@ -25,14 +25,35 @@ extensions = [
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'matplotlib.sphinxext.plot_directive'
]
import sphinx
if sphinx.__version__ >= "1.4.1":
extensions.append('sphinx.ext.imgmath')
imgmath_image_format = 'svg'
else:
extensions.append('sphinx.ext.pngmath')
# Be picky about warnings
nitpicky = True
# Ignores stuff we can't easily resolve on other project's sphinx manuals
nitpick_ignore = []
# Allows the user to override warnings from a separate file
if os.path.exists('nitpick-exceptions.txt'):
for line in open('nitpick-exceptions.txt'):
if line.strip() == "" or line.startswith("#"):
continue
dtype, target = line.split(None, 1)
target = target.strip()
try: # python 2.x
target = unicode(target)
except NameError:
pass
nitpick_ignore.append((dtype, target))
# Always includes todos
todo_include_todos = True
......@@ -111,7 +132,7 @@ pygments_style = 'sphinx'
# Some variables which are useful for generated material
project_variable = project.replace('.', '_')
short_description = u'Tensorflow bob bindings'
short_description = u'bob.learn.tensorflow API'
owner = [u'Idiap Research Institute']
......@@ -216,8 +237,13 @@ autodoc_default_flags = [
]
# For inter-documentation mapping:
from bob.extension.utils import link_documentation
intersphinx_mapping = link_documentation()
from bob.extension.utils import link_documentation, load_requirements
sphinx_requirements = "extra-intersphinx.txt"
if os.path.exists(sphinx_requirements):
intersphinx_mapping = link_documentation(additional_packages=['python', 'numpy']+load_requirements(sphinx_requirements))
else:
intersphinx_mapping = link_documentation()
# We want to remove all private (i.e. _. or __.__) members
# that are not in the list of accepted functions
......
......@@ -36,4 +36,3 @@ Indices and tables
* :ref:`modindex`
* :ref:`search`
.. include:: links.rst
......@@ -6,8 +6,89 @@
Python API
============
Architectures
-------------
.. autosummary::
bob.learn.tensorflow.network.SequenceNetwork
bob.learn.tensorflow.network.Chopra
bob.learn.tensorflow.network.Dummy
bob.learn.tensorflow.network.Lenet
bob.learn.tensorflow.network.LenetDropout
bob.learn.tensorflow.network.MLP
bob.learn.tensorflow.network.VGG
Trainers
--------
.. autosummary::
bob.learn.tensorflow.trainers.Trainer
bob.learn.tensorflow.trainers.SiameseTrainer
bob.learn.tensorflow.trainers.TripletTrainer
Layers
------
.. autosummary::
bob.learn.tensorflow.layers.Layer
bob.learn.tensorflow.layers.Conv2D
bob.learn.tensorflow.layers.Dropout
bob.learn.tensorflow.layers.FullyConnected
bob.learn.tensorflow.layers.MaxPooling
Data Shufflers
--------------
.. autosummary::
bob.learn.tensorflow.data.BaseDataShuffler
bob.learn.tensorflow.data.MemoryDataShuffler
bob.learn.tensorflow.data.TextDataShuffler
Analizers
---------
.. autosummary::
bob.learn.tensorflow.analyzers.ExperimentAnalizer
Initialization
--------------
.. autosummary::
bob.learn.tensorflow.initialization.Initialization
bob.learn.tensorflow.initialization.Constant
bob.learn.tensorflow.initialization.Gaussian
bob.learn.tensorflow.initialization.SimpleXavier
bob.learn.tensorflow.initialization.Xavier
Loss
----
.. autosummary::
bob.learn.tensorflow.loss.BaseLoss
bob.learn.tensorflow.loss.ConstrastiveLoss
bob.learn.tensorflow.loss.TripletLoss
Detailed Information
--------------------
.. automodule:: bob.learn.tensorflow
.. automodule:: bob.learn.tensorflow.layers
.. automodule:: bob.learn.tensorflow.network
.. automodule:: bob.learn.tensorflow.trainers
.. automodule:: bob.learn.tensorflow.script
.. automodule:: bob.learn.tensorflow.layers
.. automodule:: bob.learn.tensorflow.data
.. automodule:: bob.learn.tensorflow.network
.. automodule:: bob.learn.tensorflow.analyzers
.. automodule:: bob.learn.tensorflow.initialization
.. automodule:: bob.learn.tensorflow.loss
\ No newline at end of file
......@@ -77,6 +77,8 @@ setup(
'train_mnist.py = bob.learn.tensorflow.script.train_mnist:main',
'train_mnist_siamese.py = bob.learn.tensorflow.script.train_mnist_siamese:main',
'train_mnist_triplet.py = bob.learn.tensorflow.script.train_mnist_triplet:main',
'train_siamese_casia_webface.py = bob.learn.tensorflow.script.train_siamese_casia_webface:main',
],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment