[go: nahoru, domu]

Skip to content

Commit

Permalink
Implemented complex
Browse files Browse the repository at this point in the history
  • Loading branch information
MichSchli committed Mar 6, 2017
1 parent e239ab4 commit d970f04
Show file tree
Hide file tree
Showing 12 changed files with 3,016 additions and 145 deletions.
289 changes: 155 additions & 134 deletions .idea/workspace.xml

Large diffs are not rendered by default.

1,345 changes: 1,345 additions & 0 deletions backward.rels

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions code/common/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from extras.graph_representations import Representation

from decoders.nonlinear_transform import NonlinearTransform
from decoders.complex import Complex

from encoders.bipartite_gcn import BipartiteGcn
from encoders.message_gcns.gcn_diag import DiagGcn
Expand Down Expand Up @@ -283,6 +284,8 @@ def apply_basis_gcn(encoder_settings, encoding, internal_shape, layers):
def build_decoder(encoder, decoder_settings):
if decoder_settings['Name'] == "bilinear-diag":
return BilinearDiag(encoder, decoder_settings)
elif decoder_settings['Name'] == "complex":
return Complex(int(decoder_settings['CodeDimension']), decoder_settings, next_component=encoder)
elif decoder_settings['Name'] == "nonlinear-transform":
return NonlinearTransform(encoder, decoder_settings)
else:
Expand Down
105 changes: 105 additions & 0 deletions code/decoders/complex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import tensorflow as tf
from model import Model


class Complex(Model):
X = None
Y = None

encoder_cache = {'train': None, 'test': None}

def __init__(self, dimension, settings, next_component=None):
Model.__init__(self, next_component, settings)
self.dimension = dimension

def parse_settings(self):
self.regularization_parameter = float(self.settings['RegularizationParameter'])

def compute_codes(self, mode='train'):
if self.encoder_cache[mode] is not None:
return self.encoder_cache[mode]

print("HEAVY COMPUTATIONS HERE - SHOULD BE CALLED TWICE. NOW: "+mode)
subject_codes, relation_codes, object_codes = self.next_component.get_all_codes(mode=mode)
e1s = tf.nn.embedding_lookup(subject_codes, self.X[:, 0])
rs = tf.nn.embedding_lookup(relation_codes, self.X[:, 1])
e2s = tf.nn.embedding_lookup(object_codes, self.X[:, 2])

self.encoder_cache[mode] = (e1s, rs, e2s)
return self.encoder_cache[mode]


def get_loss(self, mode='train'):
e1s, rs, e2s = self.compute_codes(mode=mode)

energies = tf.reduce_sum(e1s * rs * e2s, 1)
return tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(energies, self.Y))

def local_initialize_train(self):
self.Y = tf.placeholder(tf.float32, shape=[None])
self.X = tf.placeholder(tf.int32, shape=[None, 3])

def local_get_train_input_variables(self):
return [self.X, self.Y]

def local_get_test_input_variables(self):
return [self.X]

def predict(self):
e1s, rs, e2s = self.compute_codes(mode='test')

e1s_r, e1s_i = self.extract_real_and_imaginary(e1s)
e2s_r, e2s_i = self.extract_real_and_imaginary(e2s)
rs_r, rs_i = self.extract_real_and_imaginary(rs)

energies = tf.reduce_sum(e1s_r * rs_r * e2s_r) \
+ tf.reduce_sum(e1s_i * rs_r * e2s_i) \
+ tf.reduce_sum(e1s_r * rs_i * e2s_i) \
- tf.reduce_sum(e1s_i * rs_i * e2s_r)

return tf.nn.sigmoid(energies)

def extract_real_and_imaginary(self, composite_vector):
embedding_dim = int(self.dimension/2)
r = tf.slice(composite_vector, [0, 0], [-1, embedding_dim])
i = tf.slice(composite_vector, [0, embedding_dim], [-1, embedding_dim])
return r, i

def predict_all_subject_scores(self):
e1s, rs, e2s = self.compute_codes(mode='test')
all_subject_codes = self.next_component.get_all_subject_codes(mode='test')

e1s_r, e1s_i = self.extract_real_and_imaginary(all_subject_codes)
e2s_r, e2s_i = self.extract_real_and_imaginary(e2s)
rs_r, rs_i = self.extract_real_and_imaginary(rs)

all_energies = tf.matmul(e1s_r, tf.transpose(rs_r * e2s_r)) \
+ tf.matmul(e1s_i, tf.transpose(rs_r * e2s_i)) \
+ tf.matmul(e1s_r, tf.transpose(rs_i * e2s_i)) \
- tf.matmul(e1s_i, tf.transpose(rs_i * e2s_r))

all_energies = tf.transpose(all_energies)
return tf.nn.sigmoid(all_energies)

def predict_all_object_scores(self):
e1s, rs, e2s = self.compute_codes(mode='test')
all_object_codes = self.next_component.get_all_object_codes(mode='test')

e1s_r, e1s_i = self.extract_real_and_imaginary(e1s)
e2s_r, e2s_i = self.extract_real_and_imaginary(all_object_codes)
rs_r, rs_i = self.extract_real_and_imaginary(rs)

all_energies = tf.matmul(e1s_r * rs_r, tf.transpose(e2s_r)) \
+ tf.matmul(e1s_i * rs_r, tf.transpose(e2s_i)) \
+ tf.matmul(e1s_r * rs_i, tf.transpose(e2s_i)) \
- tf.matmul(e1s_i * rs_i, tf.transpose(e2s_r))

return tf.nn.sigmoid(all_energies)

def local_get_regularization(self):
e1s, rs, e2s = self.compute_codes(mode='train')
regularization = tf.reduce_mean(tf.square(e1s))
regularization += tf.reduce_mean(tf.square(rs))
regularization += tf.reduce_mean(tf.square(e2s))

return self.regularization_parameter * regularization
10 changes: 9 additions & 1 deletion code/encoders/message_gcns/gcn_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ def combine_messages(self, forward_messages, backward_messages, self_loop_messag
collected_messages_f = tf.sparse_tensor_dense_matmul(mtr_f, forward_messages)
collected_messages_b = tf.sparse_tensor_dense_matmul(mtr_b, backward_messages)

new_embedding = self_loop_messages + collected_messages_f + collected_messages_b + self.b
if mode=='train':
choice = tf.select(tf.random_uniform([50,1]) > 0.5, tf.ones([50,1], dtype=tf.int32), tf.zeros([50,1], dtype=tf.int32))
options = tf.constant([[2., 0.], [0., 2.]])
mixer = tf.nn.embedding_lookup(options, choice)
mixer = tf.reshape(mixer, [2,50])
else:
mixer = [1.,1.]

new_embedding = mixer[1] * self_loop_messages + mixer[0] *(collected_messages_f + collected_messages_b) #+ self.b

if self.use_nonlinearity:
new_embedding = tf.nn.relu(new_embedding)
Expand Down
6 changes: 5 additions & 1 deletion code/tools/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@

plt.get_cmap('plasma')

t = [np.log(d[name]) for name in names]
t = [d[name] for name in names]

print(names[np.argmax(t)])
print(np.max(t))
print(X[np.argmax(t)])


ax.scatter(X[:,0], X[:,1], t, marker='o', alpha=1, s=5)
Expand Down
16 changes: 14 additions & 2 deletions code/tools/ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,26 @@ def combine_prediction(self, left, right):
others[i] = self.weight * left[1][i] + (1 - self.weight) * right[1][i]
rank = np.sum(np.array(others) >= target) + 1

return 1 / rank
return rank

def combined_mrr(self):
return np.mean(list(self.combine()))
return np.mean(1 / self.ranks)

def compute_ranks(self):
self.ranks = np.array(list(self.combine()))

def hits_at(self, threshold):
hits = self.ranks[self.ranks <= threshold]
return len(hits) / len(self.ranks)

if args.method == 'cutoff':
model = CutoffEnsemble(1000, args.p1, args.p2)
elif args.method == 'weighted_sum':
model = WeightEnsemble(0.5, args.p1, args.p2)

model.compute_ranks()

print(model.combined_mrr())
print(model.hits_at(1))
print(model.hits_at(3))
print(model.hits_at(10))
4 changes: 2 additions & 2 deletions code/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,5 @@ def t_func(x): #horrible hack!!!
optimizer.set_session(model.session)

optimizer.fit(train_triplets, validation_data=valid_triplets)
scorer.dump_all_scores(valid_triplets, 'dumps/subjects.valid', 'dumps/objects.valid')
scorer.dump_all_scores(test_triplets, 'dumps/subjects.test', 'dumps/objects.test')
#scorer.dump_all_scores(valid_triplets, 'dumps/subjects.valid', 'dumps/objects.valid')
#scorer.dump_all_scores(test_triplets, 'dumps/subjects.test', 'dumps/objects.test')
Loading

0 comments on commit d970f04

Please sign in to comment.