kb.pyYou can use the methods implemented in kb.py to construct a KB (knowledge base).
When constructing a KB, users only need to specify two items:
pseudo_label_list, the output of the machine learning part or the input of the logical reasoning part.
For example, the
pseudo_label_listpassed in MNIST_add is [0,1,2,...,9].
logic_forward, how to get the output through the input of the logical reasoning part.
For example, the
logic_forwardin MNIST_add is: "Add two pseudo labels to get the result."
After that, other functions of KB (such as abduction, etc.) will be automatically constructed.
In a Python program, you can build a KB by creating a subclass of KBBase.
For example, the construction of the KB (
kb1) of MNIST_add is:class add_KB(KBBase): def __init__(self, pseudo_label_list=list(range(10))): super().__init__(pseudo_label_list) def logic_forward(self, pseudo_labels): return sum(pseudo_labels) kb1 = add_KB()
When building a KB, users can specify GKB_flag in __init__ to indicate whether to build GKB (Ground Knowledge Base, domain knowledge base). GKB is a Python dictionary. The key is a list composed of pseudo_label input into logic_forward, and the value corresponding to each key is a list composed of the aforementioned pseudo_label. After the GKB is built, it can speed up the time required for abduction.
When GKB_flag is True, in order to build GKB, users also need to specify len_list, which is used to indicate the length of each list composed of pseudo_label in GKB. At the same time as __init__ constructs KB, GKB will be automatically constructed according to pseudo_label_list, len_list, and logic_forward.
For example, the
len_listpassed in MNIST_add is [2], and the GKB constructed is {0:0,0, 1:1,0],[0,1, 2:0,2],[1,1],[2,0, ..., 18:9,9}
The abduction function of KB is automatically implemented in abduce_candidates. The following parameters need to be passed in when calling abduce_candidates:
pred_res: the pseudo label output by machine learningkey: the correct result of logical reasoningmax_address_num: the maximum number of modified pseudo labelsrequire_more_address: indicate whether to continue to increase the number of modified pseudo labels to obtain more abduction results after the result has been obtained.The output is all possible abduction results.
For example: The result obtained by calling
kb1.abduce_candidatesof thekb1(KB of MNIST_add) is as follows:
pred_reskeymax_address_numrequire_more_addressOutput [1,1] 8 2 0 1,7],[7,1 [1,1] 8 2 1 1,7],[7,1],[2,6],[6,2],[3,5],[5,3],[4,4 [1,1] 8 1 1 1,7],[7,1 [1,1] 17 1 0 [] [1,1] 17 1 1 8,9],[9,8 [1,1] 17 2 0 8,9],[9,8 [1,1] 20 2 0 []
When building KB, GKB_flag can be used to automatically implement abduction. If GKB_flag is True, _abduce_by_GKB will be called to implement abduction. Otherwise, _abduce_by_search will be called to implement abduction.
_abduce_by_GKBSearch whether there is a result of abduction in GKB that meets the restriction conditions composed of pred_res, max_address_num, and require_more_address and has a key of key.
For example, in MNIST_add, when the
keyis 4, [1,3], [3,1], and [2,2] can be found in GKB. If thepred_respassed in at this time is [2,8],max_address_numis 2, andrequire_more_addressis 0, the output result is [2,2].
_abduce_by_searchStarting from 0, continuously increase the number of modified pseudo labels, and enumerate all possible modified pseudo labels until the max_address_num is reached or the logic defined by logic_forward is found. Then, if require_more_address is not 0, continue to increase the number of modified pseudo labels and output the matching results together.
For example, in MNIST_add, when the
keyis 4, thepred_resis [2,8], and themax_address_numis 2: when 0 pseudo labels are modified, the correct result cannot be obtained. When 1 pseudo label is modified, the possible modified logical inputs are [2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[2,9],[0,8],[1,8],[3,8],[4,8],[5,8],[6,8],[7,8],[8,8],[9,8], among which [2,2] is the result that meets the logic. Ifrequire_more_addressis 0, the final output result is [2,2], otherwise, continue to increase the number of modified pseudo labels and verify.
Note: When the index of the pseudo label to be modified has been obtained using zoopt or other methods, it is not necessary to call the entire process of _abduce_by_search, only address_by_idx needs to be called. This part will be described in detail in abducer_base.py.
prolog_KBWhen the logic is passed in the form of a prolog program, prolog_KB can be directly passed to the class by specifying pseudo_label_list and pl_file.
Note: The prolog program passed in needs to have the implementation of logic_forward, and the variable name of the result of logic_forward is Res.
For example, MNIST_add can first write the
add.plfile:pseudo_label(N) :- between(0, 9, N). logic_forward([Z1, Z2], Res) :- pseudo_label(Z1), pseudo_label(Z2), Res is Z1+Z2.Then, the corresponding KB can be constructed
kb2 = prolog_KB(pseudo_label_list=list(range(10)), \ pl_file='add.pl')
Similarly, other functions of KB (such as abduction, etc.) will be automatically constructed.
The following parameters can also be passed in when building KB:
max_erruse_cachemax_errWhen the output of the logical reasoning part is a numerical value, max_err can be passed in so that when calling abduce_candidates, all results whose error with key is between max_err will be output.
For example: The
pred_respassed in MNIST_add is [2,2], thekeyis 7, themax_address_numis 2, and therequire_more_addressis 0. Ifmax_erris 0, the output result is 2,5],[5,2; ifmax_erris 1, the output result is 2,4],[2,5],[2,6],[4,2],[5,2],[6,2.
use_cacheWhen use_cache is True, the result of each call to abduce_candidates will be cached so that it can be returned directly the next time it is called.
abducer_base.pyYou can use the methods implemented in abducer_base.py to help with abduction. The method is to instantiate the AbducerBase class and pass in kb.
For example, in MNIST_add, after defining
kb1, continue to constructabd1 = AbducerBase(kb1)
The main function implemented by AbducerBase is abduce. Its function is to obtain one most likely result after the data is available. When calling abduce, the following parameters need to be passed in:
data: a tuple composed of three elements, pred_res, pred_res_prob, and key. Among them, the definitions of pred_res and key are the same as those in abduce_candidates in kb.py, and pred_res_prob is the confidence list of each pseudo label output by machine learning.max_address: the maximum number of modified pseudo labels, which can be input as a float or an int. If a float is passed in, the maximum number of modified pseudo labels accounts for the proportion of all pseudo labels. If an int is passed in, it is the maximum number of modified pseudo labels (the same as the definition of max_address_num in abduce_candidates in `kb.py).require_more_address: the same definition as in abduce_candidates in kb.py.The output is a result of abduction.
abduceWhen instantiating AbducerBase, zoopt can be passed in to decide whether to use zero-order optimization to find the index of the modified pseudo label during abduction.
zoopt is False, zero-order optimization is not used, and abduce_candidates in kb.py is directly used to find all possible abduction results, and then _get_one_candidate is used to find the most likely result.zoopt is True, zero-order optimization is used to find the index of the modified pseudo label, and then address_by_idx in kb.py is used to find the result of abduction. Finally, _get_one_candidate is used to find the most likely result.
For example, in MNIST_add, when
pred_resis [2,9],keyis 18, first use zero-order optimization to get the index of the pseudo label to be modified as 0, then substitutepred_res,key, and the modified index ([0]) intoaddress_by_idxinkb.py. In it, all possible logical inputs after modifying the index are [0,9],[1,9],[3,9],[4,9],[5,9],[6,9],[7,9],[8,9],[9,9], among which [9,9] is the one that meets the logic, so the output is [9,9].Another example is HED, where
pred_resis [1,0,1,'=',1] (keyis set toNoneby default). First, use zero-order optimization to get the index of the pseudo label to be modified as 1, and then substitute it intoaddress_by_idxinkb.py. In it, all possible logical inputs after modifying the index are [1,1,1,'=',1],[1,'+',1,'=',1],[1,'=',1,'=',1], among which [1,'+',1,'=',1] is the one that meets the logic, so the output is [1,'+',1,'=',1].
When instantiating AbducerBase, dist_func can be passed in to indicate how to choose the most likely output when returning multiple results of abduction. The types that dist_func can choose are:
hamming: Use the Hamming distance between the results after abduction and pred_res as the metric, and output the result with the minimum distance.
confidence: Use the distance between the results after abduction and pred_res_prob as the metric, and output the result with the minimum distance.
For example, in MNIST_add, when
pred_resis [1,1],keyis 8, andmax_addressis 1, ifpred_res_probis 0, 0.99, 0.01, 0, 0, 0, 0, 0, 0, 0], [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, the output result is [1,7]; ifpred_res_probis 0, 0, 0.01, 0, 0, 0, 0, 0.99, 0, 0], [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, the output result is [7,1].
batch_abduce can be used to perform abduction on a batch of data at the same time. For example, the abd1.batch_abduce({'cls':[[1,1], [1,2]], 'prob':multiple_prob}, [4,8], max_address=2, require_more_address=0) is called, and the output result is 1,3], [6,2.