commit b2ffb7551c1382ae3ac9eb72dd569d63f79bb0bd
parent 70514cf66048db50eec73546cb9b1beffe12ee35
Author: Étienne Simon <esimon@esimon.eu>
Date:   Fri, 18 Apr 2014 17:29:04 +0200
Add multiple relations (homotheties, reflections, etc)
Diffstat:
9 files changed, 131 insertions(+), 9 deletions(-)
diff --git a/model.py b/model.py
@@ -150,8 +150,8 @@ class Model(object):
                     right_scores = numpy.array(right_batch_result, dtype=theano.config.floatX)
                 else:
                     right_scores = numpy.concatenate((right_scores, right_batch_result), axis=1)
-            left_rank = numpy.asscalar(numpy.where(numpy.argsort(left_scores)==right.indices[0])[1]) # FIXME Ugly
-            right_rank = numpy.asscalar(numpy.where(numpy.argsort(right_scores)==left.indices[0])[1]) # FIXME Ugly
+            left_rank = 1+numpy.asscalar(numpy.where(numpy.argsort(left_scores)==right.indices[0])[1]) # FIXME Ugly
+            right_rank = 1+numpy.asscalar(numpy.where(numpy.argsort(right_scores)==left.indices[0])[1]) # FIXME Ugly
             count = count + 2
             mean = mean + left_rank + right_rank
             top10 = top10 + (left_rank<=10) + (right_rank<=10)
diff --git a/relations/anisotropic homotheties.py b/relations/anisotropic homotheties.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python2
+
+from relations.base import *
+
+class Anisotropic_homotheties(Base_relation):
+    """ Anisotropic homotheties class.
+
+    This class has two parameters:
+    P -- the homothetic centers
+    S -- the scaling vectors
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'P': (dimension,), 'S': (dimension,) }
+        super(Anisotropic_homotheties, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        p = relations[0]
+        s = relations[1]
+        return p + (inputs-p)*s
diff --git a/relations/anisotropic scalings.py b/relations/anisotropic scalings.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python2
+
+from relations.base import *
+
+class Anisotropic_scalings(Base_relation):
+    """ Anisotropic scalings class.
+
+    This class has one parameter:
+    S -- the scaling vector
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'S': (dimension,) }
+        super(Anisotropic_scalings, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        return relations[0] * inputs
diff --git a/relations/base.py b/relations/base.py
@@ -22,7 +22,9 @@ class Base_relation(object):
         self.parameters = []
 
         for name, shape in parameters.iteritems():
-            bound = numpy.sqrt(6. / sum(shape))
+            dimension = sum(shape)
+            dimension = 1 if dimension==0 else dimension
+            bound = numpy.sqrt(6. / dimension)
             values = rng.uniform(low=-bound, high=bound, size=(number,)+shape)
             values = values / numpy.sqrt(numpy.sum(values **2, axis=1))[:, numpy.newaxis]
             var = theano.shared(name=tag+'.'+name, value=numpy.asarray(values, dtype=theano.config.floatX))
diff --git a/relations/homotheties.py b/relations/homotheties.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python2
+
+import theano.tensor as T
+from relations.base import *
+
+class Homotheties(Base_relation):
+    """ Homotheties class.
+
+    This class has two parameters:
+    P -- the homothetic centers
+    S -- the scaling factor
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'P': (dimension,), 'S': (1,) }
+        super(Homotheties, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        p = relations[0]
+        s = T.addbroadcast(relations[1], 1)
+        return p + (inputs-p)*s
diff --git a/relations/offsetted reflections.py b/relations/offsetted reflections.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python2
+
+import theano.tensor as T
+
+from relations.base import *
+
+class Offsetted_reflections(Base_relation):
+    """ Offsetted reflections class.
+
+    This class has two parameters:
+    H -- the hyperplanes
+    O -- the offsets
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'H': (dimension,), 'O': (1,) }
+        super(Offsetted_reflections, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        h = relations[0]
+        o = relations[1]
+        f = T.addbroadcast((T.sum(inputs*h, axis=1).dimshuffle(0, 'x') - o) / T.sum(h*h, axis=1).dimshuffle(0, 'x'), 1)
+        return inputs - 2 * h * f
diff --git a/relations/point reflections.py b/relations/point reflections.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python2
+
+from relations.base import *
+
+class Point_reflections(Base_relation):
+    """ Point reflections class.
+
+    This class has one parameter:
+    P -- the centers of reflection
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'P': (dimension,) }
+        super(Point_reflections, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        return 2*relations[0] - inputs
diff --git a/relations/reflections.py b/relations/reflections.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python2
+
+import theano.tensor as T
+
+from relations.base import *
+
+class Reflections(Base_relation):
+    """ Reflections class.
+
+    This class has one parameter:
+    H -- the hyperplanes
+    """
+    def __init__(self, rng, number, dimension, tag):
+        """ Initialise the parameter. """
+        parameters = { 'H': (dimension,) }
+        super(Reflections, self).__init__(rng, number, parameters, tag)
+
+    def apply(self, inputs, relations):
+        """ Apply the given relations to a given input. """
+        h = relations[0]
+        f = (T.sum(inputs*h, axis=1) / T.sum(h*h, axis=1)).dimshuffle(0, 'x')
+        return inputs - 2 * h * f
diff --git a/relations/translations.py b/relations/translations.py
@@ -1,11 +1,6 @@
 #!/usr/bin/env python2
 
-import numpy
-import theano
-import theano.tensor as T
-import theano.sparse as S
-
-from base import *
+from relations.base import *
 
 class Translations(Base_relation):
     """ Translations class.