transform

old TransE-like models
git clone https://esimon.eu/repos/transform.git
Log | Files | Refs | README

commit 434233eacd7b074f6232a38caff0537941073db3
parent 1ce979232de97cb635a26d4ec2a574464a567c61
Author: Étienne Simon <esimon@esimon.eu>
Date:   Wed, 23 Apr 2014 12:44:54 +0200

Add/Update relation (affine hadamard)

Diffstat:
Mmodel.py | 10+++++-----
Arelations/affine hadamard.py | 19+++++++++++++++++++
Mrelations/anisotropic homotheties.py | 6++----
Mrelations/anisotropic scalings.py | 6+++---
Mrelations/base.py | 9++++++---
Mrelations/homotheties.py | 7+++----
Mrelations/offsetted reflections.py | 6++----
Mrelations/point reflections.py | 6+++---
Mrelations/reflections.py | 5++---
Mrelations/translations.py | 8++++----
10 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/model.py b/model.py @@ -88,9 +88,9 @@ class Model(object): left_negative, right_negative = self.embeddings.embed(inputs[3]), self.embeddings.embed(inputs[4]) relation = self.relations.lookup(inputs[0]) - score_positive = self.config['similarity'](self.relations.apply(left_positive, relation), right_positive) - score_left_negative = self.config['similarity'](self.relations.apply(left_negative, relation), right_positive) - score_right_negative = self.config['similarity'](self.relations.apply(left_positive, relation), right_negative) + score_positive = self.config['similarity'](self.relations.transform(left_positive, relation), right_positive) + score_left_negative = self.config['similarity'](self.relations.transform(left_negative, relation), right_positive) + score_right_negative = self.config['similarity'](self.relations.transform(left_positive, relation), right_negative) score_left = self.config['margin'] + score_positive - score_left_negative score_right = self.config['margin'] + score_positive - score_right_negative @@ -106,8 +106,8 @@ class Model(object): relation = map(lambda r: T.addbroadcast(r, 0), relation) left_broadcasted = T.addbroadcast(left_positive, 0) right_broadcasted = T.addbroadcast(right_positive, 0) - left_score = self.config['similarity'](self.relations.apply(left_broadcasted, relation), right_positive) - right_score = self.config['similarity'](self.relations.apply(left_positive, relation), right_broadcasted) + left_score = self.config['similarity'](self.relations.transform(left_broadcasted, relation), right_positive) + right_score = self.config['similarity'](self.relations.transform(left_positive, relation), right_broadcasted) self.left_scoring_function = theano.function(inputs=list(inputs[0:3]), outputs=[left_score]) self.right_scoring_function = theano.function(inputs=list(inputs[0:3]), outputs=[right_score]) diff --git a/relations/affine hadamard.py b/relations/affine hadamard.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python2 + +from relations.base import * + +class Affine_hadamard(Base_relation): + """ Affine hadamard class. + + This class has two parameters: + A -- the multiplicative vectors + B -- the additive vectors + """ + def __init__(self, rng, number, dimension, tag): + """ Initialise the parameter. """ + parameters = [ ('A', (dimension,)), ('B', (dimension,)) ] + super(Affine_hadamard, self).__init__(rng, number, parameters, tag) + + def apply(self, inputs, a, b): + """ Apply the given relations to a given input. """ + return a*inputs+b diff --git a/relations/anisotropic homotheties.py b/relations/anisotropic homotheties.py @@ -11,11 +11,9 @@ class Anisotropic_homotheties(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'P': (dimension,), 'S': (dimension,) } + parameters = [ ('P', (dimension,)), ('S', (dimension,)) ] super(Anisotropic_homotheties, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, p, s): """ 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 @@ -10,9 +10,9 @@ class Anisotropic_scalings(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'S': (dimension,) } + parameters = [ ('S', (dimension,)) ] super(Anisotropic_scalings, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, s): """ Apply the given relations to a given input. """ - return relations[0] * inputs + return s * inputs diff --git a/relations/base.py b/relations/base.py @@ -21,9 +21,8 @@ class Base_relation(object): self.number = number self.parameters = [] - for name, shape in parameters.iteritems(): + for name, shape in parameters: 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] @@ -33,7 +32,11 @@ class Base_relation(object): def lookup(self, relations): """ Embed given relations. """ - return [ S.dot(relations, parameter) for parameter in self.parameters ] + return map(lambda parameter: S.dot(relations, parameter), self.parameters) + + def transform(self, inputs, relations): + """ Transform the given input w.r.t. the given relations. """ + return self.apply(inputs, *relations) def updates(self, cost, learning_rate): """ Compute the updates to perform a SGD step w.r.t. a given cost. diff --git a/relations/homotheties.py b/relations/homotheties.py @@ -12,11 +12,10 @@ class Homotheties(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'P': (dimension,), 'S': (1,) } + parameters = [ ('P', (dimension,)), ('S', (1,)) ] super(Homotheties, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, p, s): """ Apply the given relations to a given input. """ - p = relations[0] - s = T.addbroadcast(relations[1], 1) + s = T.addbroadcast(s, 1) return p + (inputs-p)*s diff --git a/relations/offsetted reflections.py b/relations/offsetted reflections.py @@ -13,12 +13,10 @@ class Offsetted_reflections(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'H': (dimension,), 'O': (1,) } + parameters = [ ('H', (dimension,)), ('O', (1,)) ] super(Offsetted_reflections, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, h, o): """ 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 @@ -10,9 +10,9 @@ class Point_reflections(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'P': (dimension,) } + parameters = [ ('P', (dimension,)) ] super(Point_reflections, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, p): """ Apply the given relations to a given input. """ - return 2*relations[0] - inputs + return 2*p - inputs diff --git a/relations/reflections.py b/relations/reflections.py @@ -12,11 +12,10 @@ class Reflections(Base_relation): """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'H': (dimension,) } + parameters = [ ('H', (dimension,)) ] super(Reflections, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, h): """ 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 @@ -6,13 +6,13 @@ class Translations(Base_relation): """ Translations class. This class has one parameter: - R -- the translations + T -- the translations """ def __init__(self, rng, number, dimension, tag): """ Initialise the parameter. """ - parameters = { 'R': (dimension,) } + parameters = [ ('T', (dimension,)) ] super(Translations, self).__init__(rng, number, parameters, tag) - def apply(self, inputs, relations): + def apply(self, inputs, t): """ Apply the given relations to a given input. """ - return relations[0] + inputs + return t + inputs