Repository: accenture/ampligraph
Issue: Var ent_emb already exsists when trying to fit multiple models in a single file

### Description
Whenever we try to model.fit multiple models in single notebook it gives 

```
Variable ent_emb already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:

  File "/usr/local/lib/python3.6/dist-packages/ampligraph/latent_features/models/EmbeddingModel.py", line 502, in _initialize_parameters
    dtype=tf.float32)
  File "/usr/local/lib/python3.6/dist-packages/ampligraph/latent_features/models/EmbeddingModel.py", line 931, in fit
    self._initialize_parameters()
  File "/usr/local/lib/python3.6/dist-packages/ampligraph/latent_features/models/TransE.py", line 265, in fit
    super().fit(X, early_stopping, early_stopping_params)
  File "<ipython-input-14-31c840e2c70d>", line 5, in <module>
    model_t.fit(X_train)
  File "/usr/local/lib/python3.6/dist-packages/IPython/core/interactiveshell.py", line 2882, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
```

### Steps to Reproduce
Create multiple models.
```
model_t = TransE(batches_count=100,
                 seed=0,
                 epochs=100,
                 k=150,
                 loss='multiclass_nll',
                 embedding_model_params={'corrupt_sides':['s', 'o']},
                 verbose = True)

model_d = DistMult(batches_count=100, 
                   seed=1, 
                   epochs=100, 
                   k=150,
                   loss='multiclass_nll',
                  #  loss_params={'margin':5},
                   embedding_model_params={'corrupt_sides':['s', 'o']},
                   verbose = True)

```

Try to fit them.

```
model_t.fit()
model_d.fit()
```
###  Work Arounds 
- if a comment out one of the models then code runs fine.

Changed files:
ampligraph/latent_features/models/ComplEx.py, ampligraph/latent_features/models/ConvKB.py, ampligraph/latent_features/models/EmbeddingModel.py, ampligraph/latent_features/models/ConvE.py

diff --git a/ampligraph/latent_features/models/ComplEx.py b/ampligraph/latent_features/models/ComplEx.py
index 2857a50..7054bf7 100644
--- a/ampligraph/latent_features/models/ComplEx.py
+++ b/ampligraph/latent_features/models/ComplEx.py
@@ -2,6 +2,7 @@ from .EmbeddingModel import EmbeddingModel, register_model
 from ampligraph.latent_features import constants as constants
 from ampligraph.latent_features.initializers import DEFAULT_XAVIER_IS_UNIFORM
 import tensorflow as tf
+import time
 
 
 @register_model("ComplEx", ["negative_corruption_entities"])
@@ -185,21 +186,26 @@ class ComplEx(EmbeddingModel):
     def _initialize_parameters(self):
         """Initialize the complex embeddings.
         """
+        timestamp = int(time.time() * 1e6)
         if not self.dealing_with_large_graphs:
-            self.ent_emb = tf.get_variable('ent_emb', shape=[len(self.ent_to_idx), self.internal_k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[len(self.ent_to_idx), self.internal_k],
                                            initializer=self.initializer.get_entity_initializer(
                                            len(self.ent_to_idx), self.internal_k),
                                            dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.internal_k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.internal_k],
                                            initializer=self.initializer.get_relation_initializer(
                                            len(self.rel_to_idx), self.internal_k),
                                            dtype=tf.float32)
         else:
             # initialize entity embeddings to zero (these are reinitialized every batch by batch embeddings)
-            self.ent_emb = tf.get_variable('ent_emb', shape=[self.batch_size * 2, self.internal_k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[self.batch_size * 2, self.internal_k],
                                            initializer=tf.zeros_initializer(),
                                            dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.internal_k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.internal_k],
                                            initializer=self.initializer.get_relation_initializer(
                                            len(self.rel_to_idx), self.internal_k),
                                            dtype=tf.float32)
diff --git a/ampligraph/latent_features/models/ConvE.py b/ampligraph/latent_features/models/ConvE.py
index 87f3ffe..74ea5df 100644
--- a/ampligraph/latent_features/models/ConvE.py
+++ b/ampligraph/latent_features/models/ConvE.py
@@ -4,6 +4,7 @@ import logging
 from sklearn.utils import check_random_state
 from tqdm import tqdm
 from functools import partial
+import time
 
 from .EmbeddingModel import EmbeddingModel, register_model, ENTITY_THRESHOLD
 from ..initializers import DEFAULT_XAVIER_IS_UNIFORM
@@ -241,11 +242,11 @@ class ConvE(EmbeddingModel):
             and all relation embeddings.
             Overload this function if the parameters needs to be initialized differently.
         """
-
+        timestamp = int(time.time() * 1e6)
         if not self.dealing_with_large_graphs:
 
             with tf.variable_scope('meta'):
-                self.tf_is_training = tf.Variable(False, trainable=False, name='is_training')
+                self.tf_is_training = tf.Variable(False, trainable=False)
                 self.set_training_true = tf.assign(self.tf_is_training, True)
                 self.set_training_false = tf.assign(self.tf_is_training, False)
 
@@ -253,26 +254,32 @@ class ConvE(EmbeddingModel):
             ninput = self.embedding_model_params['embed_image_depth']
             ksize = self.embedding_model_params['conv_kernel_size']
             dense_dim = self.embedding_model_params['dense_dim']
-
-            self.ent_emb = tf.get_variable('ent_emb', shape=[len(self.ent_to_idx), self.k],
+    
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[len(self.ent_to_idx), self.k],
                                            initializer=self.initializer.get_entity_initializer(
                                            len(self.ent_to_idx), self.k),
                                            dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.k],
                                            initializer=self.initializer.get_relation_initializer(
                                            len(self.rel_to_idx), self.k),
                                            dtype=tf.float32)
 
-            self.conv2d_W = tf.get_variable('conv2d_weights', shape=[ksize, ksize, ninput, nfilters],
+            self.conv2d_W = tf.get_variable('conv2d_weights_{}'.format(timestamp),
+                                            shape=[ksize, ksize, ninput, nfilters],
                                             initializer=tf.initializers.he_normal(seed=self.seed),
                                             dtype=tf.float32)
-            self.conv2d_B = tf.get_variable('conv2d_bias', shape=[nfilters],
+            self.conv2d_B = tf.get_variable('conv2d_bias_{}'.format(timestamp),
+                                            shape=[nfilters],
                                             initializer=tf.zeros_initializer(), dtype=tf.float32)
 
-            self.dense_W = tf.get_variable('dense_weights', shape=[dense_dim, self.k],
+            self.dense_W = tf.get_variable('dense_weights_{}'.format(timestamp),
+                                           shape=[dense_dim, self.k],
                                            initializer=tf.initializers.he_normal(seed=self.seed),
                                            dtype=tf.float32)
-            self.dense_B = tf.get_variable('dense_bias', shape=[self.k],
+            self.dense_B = tf.get_variable('dense_bias_{}'.format(timestamp),
+                                           shape=[self.k],
                                            initializer=tf.zeros_initializer(), dtype=tf.float32)
 
             if self.embedding_model_params['use_batchnorm']:
@@ -293,7 +300,8 @@ class ConvE(EmbeddingModel):
                                                     'moving_variance': np.ones(shape=[1])}}
 
             if self.embedding_model_params['use_bias']:
-                self.bias = tf.get_variable('activation_bias', shape=[1, len(self.ent_to_idx)],
+                self.bias = tf.get_variable('activation_bias_{}'.format(timestamp),
+                                            shape=[1, len(self.ent_to_idx)],
                                             initializer=tf.zeros_initializer(), dtype=tf.float32)
 
         else:
@@ -388,12 +396,12 @@ class ConvE(EmbeddingModel):
         self.batch_size = int(np.ceil(len(self.ent_to_idx) / self.batches_count))
 
         with tf.variable_scope('meta'):
-            self.tf_is_training = tf.Variable(False, trainable=False, name='is_training')
+            self.tf_is_training = tf.Variable(False, trainable=False)
             self.set_training_true = tf.assign(self.tf_is_training, True)
             self.set_training_false = tf.assign(self.tf_is_training, False)
 
-        self.ent_emb = tf.Variable(self.trained_model_params['ent_emb'], dtype=tf.float32, name='ent_emb')
-        self.rel_emb = tf.Variable(self.trained_model_params['rel_emb'], dtype=tf.float32, name='rel_emb')
+        self.ent_emb = tf.Variable(self.trained_model_params['ent_emb'], dtype=tf.float32)
+        self.rel_emb = tf.Variable(self.trained_model_params['rel_emb'], dtype=tf.float32)
 
         self.conv2d_W = tf.Variable(self.trained_model_params['conv2d_W'], dtype=tf.float32)
         self.conv2d_B = tf.Variable(self.trained_model_params['conv2d_B'], dtype=tf.float32)
@@ -456,8 +464,8 @@ class ConvE(EmbeddingModel):
             return x
 
         # Inputs
-        stacked_emb = tf.stack([e_s, e_p], axis=2, name='stacked_embeddings')
-        self.inputs = tf.reshape(stacked_emb, name='embed_image',
+        stacked_emb = tf.stack([e_s, e_p], axis=2)
+        self.inputs = tf.reshape(stacked_emb,
                                  shape=[tf.shape(stacked_emb)[0], self.embedding_model_params['embed_image_height'],
                                         self.embedding_model_params['embed_image_width'], 1])
 
@@ -478,7 +486,7 @@ class ConvE(EmbeddingModel):
             # Batch normalization will cancel out bias, so only add bias term if not using batchnorm
             x = tf.nn.bias_add(x, self.conv2d_B)
 
-        x = tf.nn.relu(x, name='conv_relu')
+        x = tf.nn.relu(x)
 
         if not self.embedding_model_params['dropout_conv'] is None:
             x = _dropout(x, rate=self.embedding_model_params['dropout_conv'])
@@ -504,11 +512,11 @@ class ConvE(EmbeddingModel):
         if not self.embedding_model_params['dropout_dense'] is None:
             x = _dropout(x, rate=self.embedding_model_params['dropout_dense'])
 
-        x = tf.nn.relu(x, name='dense_relu')
-        x = tf.matmul(x, tf.transpose(self.ent_emb), name='matmul')
+        x = tf.nn.relu(x)
+        x = tf.matmul(x, tf.transpose(self.ent_emb))
 
         if self.embedding_model_params['use_bias']:
-            x = tf.add(x, self.bias, name='add_bias')
+            x = tf.add(x, self.bias)
 
         self.scores = x
 
@@ -771,10 +779,10 @@ class ConvE(EmbeddingModel):
         e_s, e_p, e_o = self._lookup_embeddings(self.X_test_tf)
 
         # Scores for all triples
-        scores = tf.sigmoid(tf.squeeze(self._fn(e_s, e_p, e_o)), name='sigmoid_scores')
+        scores = tf.sigmoid(tf.squeeze(self._fn(e_s, e_p, e_o)))
 
         # Score of positive triple
-        self.score_positive = tf.gather(scores, indices=self.X_test_tf[:, 2], name='score_positive')
+        self.score_positive = tf.gather(scores, indices=self.X_test_tf[:, 2])
 
         # Scores for positive triples
         self.scores_filtered = tf.boolean_mask(scores, tf.cast(self.X_test_filter_tf, tf.bool))
@@ -786,7 +794,7 @@ class ConvE(EmbeddingModel):
         self.filter_rank = self.perform_comparision(self.scores_filtered, self.score_positive)
 
         # Rank of triple, with other positives filtered out.
-        self.rank = tf.subtract(self.total_rank, self.filter_rank, name='rank') + 1
+        self.rank = tf.subtract(self.total_rank, self.filter_rank) + 1
 
         # NOTE: if having trouble with the above rank calculation, consider when test triple
         # has the highest score (total_rank=1, filter_rank=1)
@@ -1042,7 +1050,7 @@ class ConvE(EmbeddingModel):
         e_s, e_p, e_o = self._lookup_embeddings(self.subject_corr)
 
         # Scores for all triples
-        self.sigmoid_scores = tf.sigmoid(tf.squeeze(self._fn(e_s, e_p, e_o)), name='sigmoid_scores')
+        self.sigmoid_scores = tf.sigmoid(tf.squeeze(self._fn(e_s, e_p, e_o)))
 
     def _get_subject_ranks(self, dataset_handle, corruption_batch_size=None):
         """ Internal function for obtaining subject ranks.
diff --git a/ampligraph/latent_features/models/ConvKB.py b/ampligraph/latent_features/models/ConvKB.py
index ce479e6..7e735e4 100644
--- a/ampligraph/latent_features/models/ConvKB.py
+++ b/ampligraph/latent_features/models/ConvKB.py
@@ -12,6 +12,7 @@ import logging
 from .EmbeddingModel import EmbeddingModel, register_model, ENTITY_THRESHOLD
 from ..initializers import DEFAULT_XAVIER_IS_UNIFORM
 from ampligraph.latent_features import constants as constants
+import time
 
 logger = logging.getLogger(__name__)
 logger.setLevel(logging.DEBUG)
@@ -193,25 +194,30 @@ class ConvKB(EmbeddingModel):
         """
 
         with tf.variable_scope('meta'):
-            self.tf_is_training = tf.Variable(False, trainable=False, name='is_training')
+            self.tf_is_training = tf.Variable(False, trainable=False)
             self.set_training_true = tf.assign(self.tf_is_training, True)
             self.set_training_false = tf.assign(self.tf_is_training, False)
 
+        timestamp = int(time.time() * 1e6)
         if not self.dealing_with_large_graphs:
 
-            self.ent_emb = tf.get_variable('ent_emb', shape=[len(self.ent_to_idx), self.k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[len(self.ent_to_idx), self.k],
                                            initializer=self.initializer.get_entity_initializer(
                                            len(self.ent_to_idx), self.k), dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.k],
                                            initializer=self.initializer.get_relation_initializer(
                                            len(self.rel_to_idx), self.k), dtype=tf.float32)
 
         else:
 
-            self.ent_emb = tf.get_variable('ent_emb', shape=[self.batch_size * 2, self.internal_k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[self.batch_size * 2, self.internal_k],
                                            initializer=tf.zeros_initializer(), dtype=tf.float32)
 
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.internal_k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.internal_k],
                                            initializer=self.initializer.get_relation_initializer(
                                            len(self.rel_to_idx), self.internal_k), dtype=tf.float32)
 
@@ -225,17 +231,21 @@ class ConvKB(EmbeddingModel):
             conv_shape = [3, filter_size, 1, num_filters]
             conv_name = 'conv-maxpool-{}'.format(filter_size)
             weights_init = tf.initializers.truncated_normal(seed=self.seed)
-            self.conv_weights[conv_name] = {'weights': tf.get_variable('{}_W'.format(conv_name), shape=conv_shape,
+            self.conv_weights[conv_name] = {'weights': tf.get_variable('{}_W_{}'.format(conv_name, timestamp),
+                                                                       shape=conv_shape,
                                                                        trainable=True, dtype=tf.float32,
                                                                        initializer=weights_init),
-                                            'biases': tf.get_variable('{}_B'.format(conv_name), shape=[num_filters],
+                                            'biases': tf.get_variable('{}_B_{}'.format(conv_name, timestamp),
+                                                                      shape=[num_filters],
                                                                       trainable=True, dtype=tf.float32,
                                                                       initializer=tf.zeros_initializer())}
 
-        self.dense_W = tf.get_variable('dense_weights', shape=[dense_dim, num_outputs], trainable=True,
+        self.dense_W = tf.get_variable('dense_weights_{}'.format(timestamp),
+                                       shape=[dense_dim, num_outputs], trainable=True,
                                        initializer=tf.keras.initializers.he_normal(seed=self.seed),
                                        dtype=tf.float32)
-        self.dense_B = tf.get_variable('dense_bias', shape=[num_outputs], trainable=False,
+        self.dense_B = tf.get_variable('dense_bias_{}'.format(timestamp),
+                                       shape=[num_outputs], trainable=False,
                                        initializer=tf.zeros_initializer(), dtype=tf.float32)
 
     def get_embeddings(self, entities, embedding_type='entity'):
@@ -332,7 +342,7 @@ class ConvKB(EmbeddingModel):
         self.rel_emb = tf.Variable(self.trained_model_params['rel_emb'], dtype=tf.float32)
 
         with tf.variable_scope('meta'):
-            self.tf_is_training = tf.Variable(False, trainable=False, name='is_training')
+            self.tf_is_training = tf.Variable(False, trainable=False)
             self.set_training_true = tf.assign(self.tf_is_training, True)
             self.set_training_false = tf.assign(self.tf_is_training, False)
 
@@ -394,9 +404,9 @@ class ConvKB(EmbeddingModel):
         dropout_rate = tf.cond(self.tf_is_training,
                                true_fn=lambda: tf.constant(self.embedding_model_params['dropout']),
                                false_fn=lambda: tf.constant(0, dtype=tf.float32))
-        x = tf.nn.dropout(x, rate=dropout_rate, name='dropout_dense')
+        x = tf.nn.dropout(x, rate=dropout_rate)
 
-        self.scores = tf.nn.xw_plus_b(x, self.dense_W, self.dense_B, name="scores")
+        self.scores = tf.nn.xw_plus_b(x, self.dense_W, self.dense_B)
 
         return tf.squeeze(self.scores)
 
diff --git a/ampligraph/latent_features/models/EmbeddingModel.py b/ampligraph/latent_features/models/EmbeddingModel.py
index 6fd1947..8c68719 100644
--- a/ampligraph/latent_features/models/EmbeddingModel.py
+++ b/ampligraph/latent_features/models/EmbeddingModel.py
@@ -20,6 +20,7 @@ from ampligraph.evaluation import generate_corruptions_for_fit, to_idx, generate
 from ampligraph.datasets import AmpligraphDatasetAdapter, NumpyDatasetAdapter
 from functools import partial
 from ampligraph.latent_features import constants as constants
+import time
 
 logger = logging.getLogger(__name__)
 logger.setLevel(logging.DEBUG)
@@ -462,7 +463,7 @@ class EmbeddingModel(abc.ABC):
             A Tensor that includes the embeddings of the objects.
         """
         e_s = self._entity_lookup(x[:, 0])
-        e_p = tf.nn.embedding_lookup(self.rel_emb, x[:, 1], name='embedding_lookup_predicate')
+        e_p = tf.nn.embedding_lookup(self.rel_emb, x[:, 1])
         e_o = self._entity_lookup(x[:, 2])
         return e_s, e_p, e_o
 
@@ -495,21 +496,26 @@ class EmbeddingModel(abc.ABC):
             and all relation embeddings.
             Overload this function if the parameters needs to be initialized differently.
         """
+        timestamp = int(time.time() * 1e6)
         if not self.dealing_with_large_graphs:
-            self.ent_emb = tf.get_variable('ent_emb', shape=[len(self.ent_to_idx), self.internal_k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[len(self.ent_to_idx), self.internal_k],
                                            initializer=self.initializer.get_entity_initializer(
                                                len(self.ent_to_idx), self.internal_k),
                                            dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.internal_k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.internal_k],
                                            initializer=self.initializer.get_relation_initializer(
                                                len(self.rel_to_idx), self.internal_k),
                                            dtype=tf.float32)
         else:
             # initialize entity embeddings to zero (these are reinitialized every batch by batch embeddings)
-            self.ent_emb = tf.get_variable('ent_emb', shape=[self.batch_size * 2, self.internal_k],
+            self.ent_emb = tf.get_variable('ent_emb_{}'.format(timestamp),
+                                           shape=[self.batch_size * 2, self.internal_k],
                                            initializer=tf.zeros_initializer(),
                                            dtype=tf.float32)
-            self.rel_emb = tf.get_variable('rel_emb', shape=[len(self.rel_to_idx), self.internal_k],
+            self.rel_emb = tf.get_variable('rel_emb_{}'.format(timestamp),
+                                           shape=[len(self.rel_to_idx), self.internal_k],
                                            initializer=self.initializer.get_relation_initializer(
                                                len(self.rel_to_idx), self.internal_k),
                                            dtype=tf.float32)