From 7b209e73a501cf8c761c5a65091988b515651f99 Mon Sep 17 00:00:00 2001 From: Tony-HYX <605698554@qq.com> Date: Tue, 14 Mar 2023 14:53:30 +0800 Subject: [PATCH 1/6] update TODO in abducer_base --- abl/abducer/abducer_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/abl/abducer/abducer_base.py b/abl/abducer/abducer_base.py index 54dbec1..e2a16bf 100644 --- a/abl/abducer/abducer_base.py +++ b/abl/abducer/abducer_base.py @@ -62,6 +62,7 @@ class AbducerBase(abc.ABC): else: all_address_flag = reform_idx(sol.get_x(), pred_res) score = 0 + # TODO:这个循环里,和上面if not self.multiple_predictions部分逻辑完全一样吧,应该把上面封装一下,然后下面循环里调用封装方法即可 for idx in range(len(pred_res)): address_idx = np.where(all_address_flag[idx] != 0)[0] candidates = self.address_by_idx([pred_res[idx]], key[idx], address_idx) From 88a8f33f169fbd6306367609efbf98522252d0b9 Mon Sep 17 00:00:00 2001 From: troyyyyy <49091847+troyyyyy@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:08:13 +0800 Subject: [PATCH 2/6] Add `_get_zoopt_score` --- abl/abducer/abducer_base.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/abl/abducer/abducer_base.py b/abl/abducer/abducer_base.py index e2a16bf..d52f74b 100644 --- a/abl/abducer/abducer_base.py +++ b/abl/abducer/abducer_base.py @@ -50,26 +50,23 @@ class AbducerBase(abc.ABC): cost_list = self._get_cost_list(pred_res, pred_res_prob, candidates) candidate = candidates[np.argmin(cost_list)] return candidate - + + def _get_zoopt_score(self, sol_x, pred_res, pred_res_prob, key): + address_idx = np.where(sol_x != 0)[0] + candidates = self.address_by_idx(pred_res, key, address_idx) + if len(candidates) > 0: + return np.min(self._get_cost_list(pred_res, pred_res_prob, candidates)) + else: + return len(pred_res) + def _zoopt_address_score(self, pred_res, pred_res_prob, key, sol): if not self.multiple_predictions: - address_idx = np.where(sol.get_x() != 0)[0] - candidates = self.address_by_idx(pred_res, key, address_idx) - if len(candidates) > 0: - return np.min(self._get_cost_list(pred_res, pred_res_prob, candidates)) - else: - return len(pred_res) + return self._get_address_score(sol.get_x(), pred_res, pred_res_prob, key) else: all_address_flag = reform_idx(sol.get_x(), pred_res) score = 0 - # TODO:这个循环里,和上面if not self.multiple_predictions部分逻辑完全一样吧,应该把上面封装一下,然后下面循环里调用封装方法即可 for idx in range(len(pred_res)): - address_idx = np.where(all_address_flag[idx] != 0)[0] - candidates = self.address_by_idx([pred_res[idx]], key[idx], address_idx) - if len(candidates) > 0: - score += np.min(self._get_cost_list(pred_res[idx], pred_res_prob[idx], candidates)) - else: - score += len(pred_res[idx]) + score += self._get_address_score(all_address_flag[idx], pred_res[idx], pred_res_prob[idx], key) return score def _constrain_address_num(self, solution, max_address_num): @@ -112,10 +109,10 @@ class AbducerBase(abc.ABC): return self.kb.abduce_rules(pred_res) def batch_abduce(self, Z, Y, max_address_num=-1, require_more_address=0): - # if self.multiple_predictions: - return self.abduce((Z['cls'], Z['prob'], Y), max_address_num, require_more_address) - # else: - # return [self.abduce((z, prob, y), max_address_num, require_more_address) for z, prob, y in zip(Z['cls'], Z['prob'], Y)] + if self.multiple_predictions: + return self.abduce((Z['cls'], Z['prob'], Y), max_address_num, require_more_address) + else: + return [self.abduce((z, prob, y), max_address_num, require_more_address) for z, prob, y in zip(Z['cls'], Z['prob'], Y)] def __call__(self, Z, Y, max_address_num=-1, require_more_address=0): return self.batch_abduce(Z, Y, max_address_num, require_more_address) @@ -241,4 +238,4 @@ if __name__ == '__main__': print() abduced_rules = abd.abduce_rules(consist_exs) - print(abduced_rules) \ No newline at end of file + print(abduced_rules) From a71af2e5ab4bb953931d15d86f0ab23107f8c0a8 Mon Sep 17 00:00:00 2001 From: troyyyyy <49091847+troyyyyy@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:08:37 +0800 Subject: [PATCH 3/6] Rearrange rules to `HED_prolog_KB` --- abl/abducer/kb.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/abl/abducer/kb.py b/abl/abducer/kb.py index 333901e..fb606f3 100644 --- a/abl/abducer/kb.py +++ b/abl/abducer/kb.py @@ -271,12 +271,16 @@ class prolog_KB(KBBase): candidates.append(candidate) return candidates + +class HED_prolog_KB(prolog_KB): + def __init__(self, pseudo_label_list, pl_file): + super().__init__(pseudo_label_list, pl_file) + def consist_rule(self, exs, rules): rules = str(rules).replace("\'","") return len(list(self.prolog.query("eval_inst_feature(%s, %s)." % (exs, rules)))) != 0 def abduce_rules(self, pred_res): - # print(pred_res) prolog_result = list(self.prolog.query("consistent_inst_feature(%s, X)." % pred_res)) if len(prolog_result) == 0: return None @@ -341,4 +345,4 @@ class HWF_KB(RegKB): if __name__ == "__main__": - pass \ No newline at end of file + pass From 176f4bdd20e4dc08479cbf160874d11aeca7cac3 Mon Sep 17 00:00:00 2001 From: Tony-HYX <605698554@qq.com> Date: Tue, 14 Mar 2023 15:26:35 +0800 Subject: [PATCH 4/6] fix method name bug in abducer_base --- abl/abducer/abducer_base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/abl/abducer/abducer_base.py b/abl/abducer/abducer_base.py index d52f74b..06845a3 100644 --- a/abl/abducer/abducer_base.py +++ b/abl/abducer/abducer_base.py @@ -51,7 +51,7 @@ class AbducerBase(abc.ABC): candidate = candidates[np.argmin(cost_list)] return candidate - def _get_zoopt_score(self, sol_x, pred_res, pred_res_prob, key): + def _zoopt_address_score_single(self, sol_x, pred_res, pred_res_prob, key): address_idx = np.where(sol_x != 0)[0] candidates = self.address_by_idx(pred_res, key, address_idx) if len(candidates) > 0: @@ -61,12 +61,12 @@ class AbducerBase(abc.ABC): def _zoopt_address_score(self, pred_res, pred_res_prob, key, sol): if not self.multiple_predictions: - return self._get_address_score(sol.get_x(), pred_res, pred_res_prob, key) + return self._zoopt_address_score_single(sol.get_x(), pred_res, pred_res_prob, key) else: all_address_flag = reform_idx(sol.get_x(), pred_res) score = 0 for idx in range(len(pred_res)): - score += self._get_address_score(all_address_flag[idx], pred_res[idx], pred_res_prob[idx], key) + score += self._zoopt_address_score_single(all_address_flag[idx], pred_res[idx], pred_res_prob[idx], key) return score def _constrain_address_num(self, solution, max_address_num): From d80e9228d3ac70f08fb3633e16efad71d9a1ccf7 Mon Sep 17 00:00:00 2001 From: Tony-HYX <605698554@qq.com> Date: Tue, 14 Mar 2023 17:35:40 +0800 Subject: [PATCH 5/6] update TODO in kb --- abl/abducer/kb.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/abl/abducer/kb.py b/abl/abducer/kb.py index fb606f3..8bb7854 100644 --- a/abl/abducer/kb.py +++ b/abl/abducer/kb.py @@ -26,6 +26,10 @@ import pyswip class KBBase(ABC): def __init__(self, pseudo_label_list, len_list=None, GKB_flag=False, max_err=0): + # TODO:添加一下类型检查,比如 + # if not isinstance(X, (np.ndarray, spmatrix)): + # raise TypeError("X should be numpy array or sparse matrix") + self.pseudo_label_list = pseudo_label_list self.len_list = len_list self.GKB_flag = GKB_flag @@ -161,6 +165,7 @@ class KBBase(ABC): new_candidates += candidates return new_candidates + # TODO:在类初始化时应该有一个cache(默认True)的参数,用户可以指定是否用cache(若KB会变,那不能用cache) @lru_cache(maxsize=100) def _abduce_by_search(self, pred_res, key, max_address_num, require_more_address, multiple_predictions): pred_res = hashable_to_list(pred_res) From 2aa88634abacf1a1e419fb50320f45ab40791315 Mon Sep 17 00:00:00 2001 From: Tony-HYX <605698554@qq.com> Date: Tue, 14 Mar 2023 18:06:42 +0800 Subject: [PATCH 6/6] update TODO in kb --- abl/abducer/kb.py | 1 + 1 file changed, 1 insertion(+) diff --git a/abl/abducer/kb.py b/abl/abducer/kb.py index 8bb7854..fafc1a8 100644 --- a/abl/abducer/kb.py +++ b/abl/abducer/kb.py @@ -166,6 +166,7 @@ class KBBase(ABC): return new_candidates # TODO:在类初始化时应该有一个cache(默认True)的参数,用户可以指定是否用cache(若KB会变,那不能用cache) + # TODO:如果是multiple_predictions=True,那这个cache几乎不会命中吧? @lru_cache(maxsize=100) def _abduce_by_search(self, pred_res, key, max_address_num, require_more_address, multiple_predictions): pred_res = hashable_to_list(pred_res)