thunlp / OpenKE

An Open-Source Package for Knowledge Embedding (KE)
3.83k stars 985 forks source link

Tensorflow HolE implementation is not working #233

Closed unmeshvrije closed 4 years ago

unmeshvrije commented 4 years ago

I am executing the program using python train_model.py --gpu --db fb15k237 --mode train --model hole

Note that I added the missing lines in openke/module/model/__init__.py to export HolE class.

Following is my code i.e. cat train_model.py which is in the home directory OpenKE


import openke
from openke.config import Trainer, Tester
from openke.module.model import TransE, HolE
from openke.module.loss import MarginLoss
from openke.module.strategy import NegativeSampling
from openke.data import TrainDataLoader, TestDataLoader
import sys
import json
import argparse

def parse_args():
    parser = argparse.ArgumentParser(description = 'Train embeddings of the KG with a given model')
    parser.add_argument('--gpu', dest ='gpu', help = 'Whether to use gpu or not', action = 'store_true')
    parser.add_argument('--filtered', dest ='filtered', help = 'Whether to use filtered setting or not', action = 'store_true')
    parser.add_argument('--mode', dest = 'mode', type = str, choices = ['train', 'test', 'trainAsTest'], \
    help = 'Choice of the mode: train and test are intuitive. trainAsTest uses training data as test', default = None)
    parser.add_argument('--db', required = True, dest = 'db', type = str, default = None)
    parser.add_argument('--model', dest = 'model', type = str, default = 'transe')
    parser.add_argument('--topk', dest = 'topk', type = int, default = 10)
    return parser.parse_args()

args = parse_args()

# Global constants
N_DIM = 200 # Number of dimensions for embeddings

# Paths
db_path = "./benchmarks/" + args.db + "/"
checkpoint_path = "./checkpoint/" + args.db + "-" + args.model + ".ckpt"
result_path     = "./result/"     + args.db + "-" + args.model + ".json"

# define the model

def choose_model():
    model = None
    if args.model == "transe":
        model = TransE(
                ent_tot = train_dataloader.get_ent_tot(),
                rel_tot = train_dataloader.get_rel_tot(),
                dim = N_DIM,
                p_norm = 1,
                norm_flag = True
                )
    elif args.model == "hole":
        model = HolE(
                ent_tot = train_dataloader.get_ent_tot(),
                rel_tot = train_dataloader.get_rel_tot(),
                dim = N_DIM
                );

    return model

if args.mode == "train":
    train_dataloader = TrainDataLoader(
        in_path = db_path,
        nbatches = 100,
        threads = 8,
        sampling_mode = "normal",
        bern_flag = 1,
        filter_flag = 1,
        neg_ent = 25,
        neg_rel = 0
        )

    model = choose_model()
    # define the loss function
    model_with_loss = NegativeSampling(
        model = model,
        loss = MarginLoss(margin = 5.0),
        batch_size = train_dataloader.get_batch_size()
        )
    trainer = Trainer(model = model_with_loss, data_loader = train_dataloader, train_times = 1000, alpha = 1.0, use_gpu = args.gpu)
    trainer.run()

    model.save_checkpoint(checkpoint_path)
    model.save_parameters(result_path)

elif args.mode == "test":
    test_dataloader = TestDataLoader(db_path, "link")
    model = choose_model()
    model.load_checkpoint(checkpoint_path)
    model.load_parameters(result_path)
    tester = Tester(args.db, model = model, data_loader = test_dataloader, use_gpu = args.gpu)
    with open (result_path, 'r') as fin:
        params = json.loads(fin.read())
    tester.run_ans_prediction(params['ent_embeddings.weight'], topk, filtered = args.filtered)

Following is my Error log. Is using NegativeSampling bad ?

File "train_model.py", line 72, in <module>
    trainer.run()
  File "/home/uji300/OpenKE/openke/config/Trainer.py", line 92, in run
    loss = self.train_one_step(data)
  File "/home/uji300/OpenKE/openke/config/Trainer.py", line 50, in train_one_step
    'mode': data['mode']
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/torch/nn/modules/module.py", line 547, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/uji300/OpenKE/openke/module/strategy/NegativeSampling.py", line 24, in forward
    score = self.model(data)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/torch/nn/modules/module.py", line 547, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/uji300/OpenKE/openke/module/model/HolE.py", line 38, in forward
    score = self._calc(h ,t, r)
  File "/home/uji300/OpenKE/openke/module/model/HolE.py", line 67, in _calc
    relation_mention = tf.nn.l2_normalize(rel, 1)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/ops/nn_impl.py", line 650, in l2_normalize_v2
    x = ops.convert_to_tensor(x, name="x")
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/ops.py", line 1184, in convert_to_tensor
    return convert_to_tensor_v2(value, dtype, preferred_dtype, name)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/ops.py", line 1242, in convert_to_tensor_v2
    as_ref=False)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/ops.py", line 1296, in internal_convert_to_tensor
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/constant_op.py", line 286, in _constant_tensor_conversion_function
    return constant(v, dtype=dtype, name=name)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/constant_op.py", line 227, in constant
    allow_broadcast=True)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/constant_op.py", line 235, in _constant_impl
t = convert_to_eager_tensor(value, ctx, dtype)
  File "/home/uji300/.pyenv/versions/py3.5/lib/python3.5/site-packages/tensorflow_core/python/framework/constant_op.py", line 96, in convert_to_eager_tensor
    return ops.EagerTensor(value, ctx.device_name, dtype)
ValueError: Attempt to convert a value (tensor([[ 0.0961, -0.0783, -0.0658,  ...,  0.0066, -0.0900,  0.0736],
        [-0.0466, -0.0214, -0.1038,  ..., -0.0565, -0.0763, -0.0223],
        [ 0.0871,  0.0958, -0.0819,  ...,  0.0153, -0.0963, -0.0352],
        ...,
        [ 0.0420,  0.0983,  0.0951,  ...,  0.0569, -0.0205, -0.0489],
        [ 0.0871,  0.0958, -0.0819,  ...,  0.0153, -0.0963, -0.0352],
        [-0.0468, -0.0542, -0.1154,  ..., -0.0133,  0.0794, -0.0056]],
       device='cuda:0', grad_fn=<EmbeddingBackward>)) with an unsupported type (<class 'torch.Tensor'>) to a Tensor.
  0%|                                                                                                               | 0/1000 [00:00<?, ?it/s]
unmeshvrije commented 4 years ago

@chenweize1998 , Sorry to tag you, but would you be kind enough to take a look at this one ?

chenweize1998 commented 4 years ago

Which branch of code are you using? Seems like you mixed the code of tensorflow branch and pytorch branch.

unmeshvrije commented 4 years ago

I forked from the master branch (or Pytorch branch) on 9 Nov 2019.
Can you kindly give me pointers on how to resolve this and use OpenKE to get HolE embeddings ?

unmeshvrije commented 4 years ago

I think HolE.py in PyTorch branch still has the tensorflow code

THUCSTHanxu13 commented 4 years ago

I have implemented the code for HolE with Pytorch.