Browse Source

[ENH] add dynamic budget in zoopt, revise hed

pull/1/head
troyyyyy 1 year ago
parent
commit
ec71e406b1
4 changed files with 63 additions and 30 deletions
  1. +27
    -4
      abl/reasoning/reasoner.py
  2. +22
    -20
      docs/Examples/HED.rst
  3. +9
    -4
      examples/hed/hed.ipynb
  4. +5
    -2
      examples/hed/reasoning/reasoning.py

+ 27
- 4
abl/reasoning/reasoner.py View File

@@ -200,22 +200,22 @@ class Reasoner:
"""
dimension = Dimension(size=symbol_num, regs=[[0, 1]] * symbol_num, tys=[False] * symbol_num)
objective = Objective(
lambda sol: self.zoopt_revision_score(symbol_num, data_example, sol),
lambda sol: self.zoopt_score(symbol_num, data_example, sol),
dim=dimension,
constraint=lambda sol: self._constrain_revision_num(sol, max_revision_num),
)
parameter = Parameter(budget=200, intermediate_result=False, autoset=True)
parameter = Parameter(budget=self.zoopt_budget(symbol_num), intermediate_result=False, autoset=True)
solution = Opt.min(objective, parameter)
return solution

def zoopt_revision_score(
def zoopt_score(
self,
symbol_num: int,
data_example: ListData,
sol: Solution,
) -> int:
"""
Get the revision score for a solution. A lower score suggests that ZOOpt library
Set the revision score for a solution. A lower score suggests that ZOOpt library
has a higher preference for this solution.

Parameters
@@ -240,6 +240,29 @@ class Reasoner:
return np.min(self._get_cost_list(data_example, candidates, reasoning_results))
else:
return symbol_num
def zoopt_budget(self, symbol_num: int) -> int:
"""
Sets a default budget for ZOOpt optimization. The function, in its default implementation,
returns a fixed budget value of 100. However, it can be adjusted to return other fixed
values, or a dynamic budget based on the number of symbols, if desired. For example, one might choose to
set the budget as 100 times symbol_num.

Parameters
----------
symbol_num : int
The number of symbols to be considered in the ZOOpt optimization process. Although this parameter
can be used to compute a dynamic optimization budget, by default it is not utilized in the
calculation.

Returns
-------
int
The budget for ZOOpt optimization. By default, this is a fixed value of 100,
irrespective of the symbol_num value.
"""
return 100

def _constrain_revision_num(self, solution: Solution, max_revision_num: int) -> int:
"""


+ 22
- 20
docs/Examples/HED.rst View File

@@ -208,32 +208,34 @@ Building the Reasoning Part

In the reasoning part, we first build a knowledge base. As mentioned
before, the knowledge base in this task involves the structure of the
equations and a recursive definition of bit-wise operations. The
knowledge base is already defined in ``HedKB``, which is derived from
``PrologKB``, and is built upon Prolog file ``reasoning/BK.pl`` and
``reasoning/learn_add.pl``.

Specifically, the knowledge about the structure of equations (in
``reasoning/BK.pl``) is a set of DCG (definite clause grammar) rules
recursively define that a digit is a sequence of ‘0’ and ‘1’, and
equations and a recursive definition of bit-wise operations, which are
defined in Prolog file ``examples/hed/reasoning/BK.pl``
and ``examples/hed/reasoning/learn_add.pl``, respectively.
Specifically, the knowledge about the structure of equations is a set of DCG
rules recursively define that a digit is a sequence of ‘0’ and ‘1’, and
equations share the structure of X+Y=Z, though the length of X, Y and Z
can be varied. The knowledge about bit-wise operations (in
``reasoning/learn_add.pl``) is a recursive logic program, which
reversely calculates X+Y, i.e., it operates on X and Y digit-by-digit
and from the last digit to the first.

Note: Please notice that, the specific rules for calculating the
operations are undefined in the knowledge base, i.e., results of ‘0+0’,
‘0+1’ and ‘1+1’ could be ‘0’, ‘1’, ‘00’, ‘01’ or even ‘10’. The missing
calculation rules are required to be learned from the data. Therefore,
``HedKB`` incorporates methods for abducing rules from data. Users
interested can refer to the specific implementation of ``HedKB`` in
``reasoning/reasoning.py``
can be varied. The knowledge about bit-wise operations is a recursive
logic program, which reversely calculates X+Y, i.e., it operates on
X and Y digit-by-digit and from the last digit to the first.

The knowledge base is already built in ``HedKB``.
``HedKB`` is derived from class ``PrologKB``, and is built upon the aformentioned Prolog
files.

.. code:: ipython3

kb = HedKB()

.. note::

Please notice that, the specific rules for calculating the
operations are undefined in the knowledge base, i.e., results of ‘0+0’,
‘0+1’ and ‘1+1’ could be ‘0’, ‘1’, ‘00’, ‘01’ or even ‘10’. The missing
calculation rules are required to be learned from the data. Therefore,
``HedKB`` incorporates methods for abducing rules from data. Users
interested can refer to the specific implementation of ``HedKB`` in
``examples/hed/reasoning/reasoning.py``

Then, we create a reasoner. Due to the indeterminism of abductive
reasoning, there could be multiple candidates compatible to the
knowledge base. When this happens, reasoner can minimize inconsistencies


+ 9
- 4
examples/hed/hed.ipynb View File

@@ -290,11 +290,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"In the reasoning part, we first build a knowledge base. As mentioned before, the knowledge base in this task involves the structure of the equations and a recursive definition of bit-wise operations. The knowledge base is already defined in `HedKB`, which is derived from `PrologKB`, and is built upon Prolog file `reasoning/BK.pl` and `reasoning/learn_add.pl`.\n",
"In the reasoning part, we first build a knowledge base. As mentioned before, the knowledge base in this task involves the structure of the equations and a recursive definition of bit-wise operations, which are defined in Prolog file ``reasoning/BK.pl`` and ``reasoning/learn_add.pl``, respectively. Specifically, the knowledge about the structure of equations is a set of DCG rules recursively define that a digit is a sequence of ‘0’ and ‘1’, and equations share the structure of X+Y=Z, though the length of X, Y and Z can be varied. The knowledge about bit-wise operations is a recursive logic program, which reversely calculates X+Y, i.e., it operates on X and Y digit-by-digit and from the last digit to the first.\n",
"\n",
"Specifically, the knowledge about the structure of equations (in `reasoning/BK.pl`) is a set of DCG (definite clause grammar) rules recursively define that a digit is a sequence of '0' and '1', and equations share the structure of X+Y=Z, though the length of X, Y and Z can be varied. The knowledge about bit-wise operations (in `reasoning/learn_add.pl`) is a recursive logic program, which reversely calculates X+Y, i.e., it operates on X and Y digit-by-digit and from the last digit to the first.\n",
"\n",
"Note: Please notice that, the specific rules for calculating the operations are undefined in the knowledge base, i.e., results of '0+0', '0+1' and '1+1' could be '0', '1', '00', '01' or even '10'. The missing calculation rules are required to be learned from the data. Therefore, `HedKB` incorporates methods for abducing rules from data. Users interested can refer to the specific implementation of `HedKB` in `reasoning/reasoning.py`"
"The knowledge base is already built in ``HedKB``. ``HedKB`` is derived from class ``PrologKB``, and is built upon the aformentioned Prolog files. "
]
},
{
@@ -306,6 +304,13 @@
"kb = HedKB()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note: Please notice that, the specific rules for calculating the operations are undefined in the knowledge base, i.e., results of '0+0', '0+1' and '1+1' could be '0', '1', '00', '01' or even '10'. The missing calculation rules are required to be learned from the data. Therefore, `HedKB` incorporates methods for abducing rules from data. Users interested can refer to the specific implementation of `HedKB`."
]
},
{
"cell_type": "markdown",
"metadata": {},


+ 5
- 2
examples/hed/reasoning/reasoning.py View File

@@ -31,8 +31,11 @@ class HedReasoner(Reasoner):
data_example.pred_pseudo_label, data_example.Y, data_example.X, revision_idx
)
return candidate
def zoopt_budget(self, symbol_num):
return 200

def zoopt_revision_score(self, symbol_num, data_example, sol, get_score=True):
def zoopt_score(self, symbol_num, data_example, sol, get_score=True):
revision_flag = reform_list(
list(sol.get_x().astype(np.int32)), data_example.pred_pseudo_label
)
@@ -78,7 +81,7 @@ class HedReasoner(Reasoner):
max_revision_num = self._get_max_revision_num(self.max_revision, symbol_num)

solution = self._zoopt_get_solution(symbol_num, data_example, max_revision_num)
max_candidate_idxs = self.zoopt_revision_score(symbol_num, data_example, solution, get_score=False)
max_candidate_idxs = self.zoopt_score(symbol_num, data_example, solution, get_score=False)

abduced_pseudo_label = [[] for _ in range(len(data_example))]



Loading…
Cancel
Save