diff --git a/Config.json b/Config.json index fc4c0d0..9fd9bb2 100644 --- a/Config.json +++ b/Config.json @@ -1,8 +1,8 @@ { "k": 1, -"T": 0.65, -"FOCUSX": 1.0305365040669583, -"FOCUSY": 0.8437127611721296, +"T": 0.6, +"FOCUSX": 1.2305365040669583, +"FOCUSY": 1.0437127611721296, "PROJECTION_DECAY_DESIRE": 0.95, "PROJECTION_DECAY_EVENT": 0.95, @@ -16,8 +16,8 @@ "POSITIVE_THRESHOLD": 0.51, "NEGATIVE_THRESHOLD": 0.5, -"MEMORY_CONCEPT_CAPACITY": 210000, -"EVENT_BUFFER_CAPACITY": 10, +"MEMORY_CONCEPT_CAPACITY": 300000, +"EVENT_BUFFER_CAPACITY": 15, "GLOBAL_BUFFER_CAPACITY": 1000, "CONCEPT_LINK_CAPACITY": 100, "NUMBER_OF_ATTEMPTS_TO_SEARCH_FOR_SEMANTICALLY_RELATED_CONCEPT": 3, diff --git a/Documentation/Diagram.png b/Documentation/Diagram.png index 1c3e643..452637b 100644 Binary files a/Documentation/Diagram.png and b/Documentation/Diagram.png differ diff --git a/NALInferenceRules/HelperFunctions.py b/NALInferenceRules/HelperFunctions.py index 2f8dbf7..d792c49 100644 --- a/NALInferenceRules/HelperFunctions.py +++ b/NALInferenceRules/HelperFunctions.py @@ -161,28 +161,28 @@ def stamp_and_print_inference_rule(sentence, inference_rule, parent_sentences): for parent in parent_sentences: sentence.stamp.parent_premises.append(parent) - if isinstance(parent.statement, NALGrammar.Terms.SpatialTerm): - parent_strings.append("CENTER: " + str(parent.statement.center) + " | DIM:" - + str(parent.statement.dimensions) + " " + str(parent.value) - + " -- pooled? " + str(parent.statement.of_spatial_terms)) - elif isinstance(parent.statement, NALGrammar.Terms.CompoundTerm) and not isinstance(parent, NALGrammar.Sentences.Goal): - parent_strings.append("CENTER1: " + str(parent.statement.subterms[0].center) + " | DIM:" - + str(parent.statement.subterms[0].dimensions) - + " -- pooled? " + str(parent.statement.subterms[0].of_spatial_terms) - + " " + str(parent.value)) - - parent_strings.append("CENTER2: " + str(parent.statement.subterms[1].center) + " | DIM:" - + str(parent.statement.subterms[1].dimensions) + " " + str(parent.value) - + " -- pooled? " + str(parent.statement.subterms[1].of_spatial_terms)) - - else: - parent_strings.append("other " + str(parent.value)) - - - # if inference_rule is F_Deduction and isinstance(sentence, NALGrammar.Sentences.Judgment) and sentence.statement.is_first_order(): - # Global.Global.debug_print(sentence.stamp.derived_by - # + " derived " + sentence.get_formatted_string() - # + " by parents " + str(parent_strings)) + # if isinstance(parent.statement, NALGrammar.Terms.SpatialTerm): + # parent_strings.append("CENTER: " + str(parent.statement.center) + " | DIM:" + # + str(parent.statement.dimensions) + " " + str(parent.value) + # + " -- pooled? " + str(parent.statement.of_spatial_terms)) + # elif isinstance(parent.statement, NALGrammar.Terms.CompoundTerm) and not isinstance(parent, NALGrammar.Sentences.Goal): + # parent_strings.append("CENTER1: " + str(parent.statement.subterms[0].center) + " | DIM:" + # + str(parent.statement.subterms[0].dimensions) + # + " -- pooled? " + str(parent.statement.subterms[0].of_spatial_terms) + # + " " + str(parent.value)) + # + # parent_strings.append("CENTER2: " + str(parent.statement.subterms[1].center) + " | DIM:" + # + str(parent.statement.subterms[1].dimensions) + " " + str(parent.value) + # + " -- pooled? " + str(parent.statement.subterms[1].of_spatial_terms)) + # + # else: + # parent_strings.append("other " + str(parent.value)) + + + if inference_rule is F_Deduction and isinstance(sentence, NALGrammar.Sentences.Judgment) and sentence.statement.is_first_order(): + Global.Global.debug_print(sentence.stamp.derived_by + + " derived " + sentence.get_formatted_string() + + " by parents " + str(parent_strings)) def premise_result_type(j1,j2): """ diff --git a/NARS.py b/NARS.py index fe3abe0..8c809bf 100644 --- a/NARS.py +++ b/NARS.py @@ -68,8 +68,8 @@ def __init__(self): Global.Global.NARS = self # global vars are part of NARS Global.Global.ARRAY_NEGATIVE_ELEMENT = NALGrammar.Terms.from_string('(--,(arrayEl-->negative))') - Global.Global.ARRAY_NEGATIVE_SENTENCE = NALGrammar.Sentences.Judgment(statement=Global.Global.ARRAY_NEGATIVE_ELEMENT.subterms[0], - value=NALGrammar.Values.TruthValue(frequency=0.0)) + Global.Global.ARRAY_NEGATIVE_SENTENCE = NALGrammar.Sentences.Judgment(statement=Global.Global.ARRAY_NEGATIVE_ELEMENT, + value=NALGrammar.Values.TruthValue(frequency=1.0)) def startup_and_run(self): @@ -120,16 +120,14 @@ def do_working_cycle(self): # OBSERVE #self.Observe() # todo begin spatial take vvv - radii = [1] - vision_sentences = [] - for radius in radii: - vision_sentences += self.vision_buffer.take(pool=False,radius=radius) - vision_sentences += self.vision_buffer.take(pool=True,radius=radius) - # single array - for vision_sentence in vision_sentences: - if vision_sentence is not None: - self.global_buffer.PUT_NEW(NARSDataStructures.Other.Task(vision_sentence)) + vision_sentence = self.vision_buffer.take(pooled=False) + if vision_sentence is not None: + self.global_buffer.PUT_NEW(NARSDataStructures.Other.Task(vision_sentence)) + + vision_sentence = self.vision_buffer.take(pooled=True) + if vision_sentence is not None: + self.global_buffer.PUT_NEW(NARSDataStructures.Other.Task(vision_sentence)) # todo end spatial take ^^ @@ -399,7 +397,7 @@ def process_judgment_task(self, task: NARSDataStructures.Other.Task): # only put non-derived atomic events in temporal module for now Global.Global.NARS.temporal_module.PUT_NEW(task) - if isinstance(task.sentence.statement, NALGrammar.Terms.SpatialTerm): return + if task.sentence.stamp.derived_by is None: return if isinstance(j.statement, NALGrammar.Terms.CompoundTerm)\ and j.statement.connector == NALSyntax.TermConnector.Negation: diff --git a/NARSDataStructures/Buffers.py b/NARSDataStructures/Buffers.py index 76f1502..4f263a8 100644 --- a/NARSDataStructures/Buffers.py +++ b/NARSDataStructures/Buffers.py @@ -87,19 +87,20 @@ def __init__(self, dimensions): self.dimensions = dimensions self.array = np.full(shape=dimensions, fill_value=NALGrammar.Sentences.TruthValue(0.0,0.9)) - self.pooled_array = None - self.components_bag = Bag(item_type=tuple, + self.components_bag = Bag(item_type=object, capacity=1000, granularity=100) - self.pooled_components_bag = Bag(item_type=tuple, + + self.pooled_array = np.full(shape=dimensions, + fill_value=NALGrammar.Sentences.TruthValue(0.0,0.9)) + self.pooled_components_bag = Bag(item_type=object, capacity=1000, granularity=100) + self.last_taken_img_array = None + self.last_sentence = None # initialize with uniform probabilility - for indices, truth_value in np.ndenumerate(self.array): - item = self.components_bag.PUT_NEW(indices) - self.components_bag.change_priority(item.key, 0.5) def blank_image(self): self.set_image(np.empty(shape=self.array.shape)) @@ -112,102 +113,105 @@ def set_image(self, img): # "ERROR: Data dimensions are incompatible with Spatial Buffer dimensions " \ # + str(event_array.shape) + " and " + str(self.dimensions) - self.array = self.create_pooled_sensation_array(original_event_array, stride=2) + self.array = self.create_pooled_sensation_array(original_event_array, stride=1) self.components_bag.clear() - self.pooled_components_bag.clear() - # maximum = 0 - # for indices, sentence in np.ndenumerate(self.array): - # e = NALInferenceRules.TruthValueFunctions.Expectation(sentence.value.frequency, sentence.value.confidence) - # maximum = max(maximum, 2 * abs(e - 0.5)) + maximum = 0 + for indices, sentence in np.ndenumerate(self.array): + if sentence.value.frequency > Config.POSITIVE_THRESHOLD \ + and not (isinstance(sentence.statement, + NALGrammar.Terms.CompoundTerm) and sentence.statement.connector == NALSyntax.TermConnector.Negation): + maximum = max(maximum, sentence.value.frequency * sentence.value.confidence) for indices, sentence in np.ndenumerate(self.array): - #e = NALInferenceRules.TruthValueFunctions.Expectation(sentence.value.frequency,sentence.value.confidence) - priority = sentence.value.frequency #2 * abs(e - 0.5) / maximum # normalized priority - self.components_bag.PUT_NEW(indices) - self.components_bag.change_priority(Item.get_key_from_object(indices), priority) + if sentence.value.frequency > Config.POSITIVE_THRESHOLD \ + and not (isinstance(sentence.statement,NALGrammar.Terms.CompoundTerm) and sentence.statement.connector == NALSyntax.TermConnector.Negation): + priority = sentence.value.frequency * sentence.value.confidence / maximum + object = indices + self.components_bag.PUT_NEW(object) + self.components_bag.change_priority(Item.get_key_from_object(object), priority) - # now the pooled array - self.pooled_array = self.create_pooled_sensation_array(original_event_array, stride=1) - self.pooled_array = self.create_pooled_sensation_array(self.pooled_array, stride=2) - # maximum = 0 - # for indices, sentence in np.ndenumerate(self.pooled_array): - # e = NALInferenceRules.TruthValueFunctions.Expectation(sentence.value.frequency, sentence.value.confidence) - # maximum = max(maximum, 2 * abs(e - 0.5)) + + # pooled + self.pooled_array = self.create_pooled_sensation_array(original_event_array, stride=2) + #self.pooled_array = self.create_pooled_sensation_array(self.pooled_array , stride=2) + self.pooled_components_bag.clear() + + maximum = 0 + for indices, sentence in np.ndenumerate(self.pooled_array): + if sentence.value.frequency > Config.POSITIVE_THRESHOLD \ + and not (isinstance(sentence.statement, + NALGrammar.Terms.CompoundTerm) and sentence.statement.connector == NALSyntax.TermConnector.Negation): + maximum = max(maximum, sentence.value.frequency * sentence.value.confidence) for indices, sentence in np.ndenumerate(self.pooled_array): - #e = NALInferenceRules.TruthValueFunctions.Expectation(sentence.value.frequency,sentence.value.confidence) - priority = sentence.value.frequency #2 * abs(e - 0.5) / maximum # normalized priority - self.pooled_components_bag.PUT_NEW(indices) - self.pooled_components_bag.change_priority(Item.get_key_from_object(indices), priority) - - # maximum = 0 - # for indices, sentence in np.ndenumerate(self.array): - # - # - # for indices, sentence in np.ndenumerate(self.array): - # - # self.components_bag.PUT_NEW(indices) - # self.components_bag.change_priority(Item.get_key_from_object(indices), priority) - - def take(self, pool, radius): + if sentence.value.frequency > Config.POSITIVE_THRESHOLD \ + and not (isinstance(sentence.statement, + NALGrammar.Terms.CompoundTerm) and sentence.statement.connector == NALSyntax.TermConnector.Negation): + priority = sentence.value.frequency * sentence.value.confidence / maximum + object = indices + self.pooled_components_bag.PUT_NEW(object) + self.pooled_components_bag.change_priority(Item.get_key_from_object(object), priority) + + def take(self, pooled): """ Probabilistically select a spatial subset of the buffer. :return: an Array Judgment of the selected subset. """ - - if pool: + if pooled: bag = self.pooled_components_bag + array = self.pooled_array else: bag = self.components_bag - + array = self.array # probabilistically peek the 2 vertices of the box + # selection 1: small fixed windows + indices = bag.peek() + if indices is None: return None + + y, x = indices.object + radius = 1#random.randint(1,2) + min_x, min_y = max(x - radius, 0), max(y - radius, 0) + max_x, max_y = min(x + radius, array.shape[1] - 1), min(y + radius, + array.shape[0] - 1) + + extracted = array[min_y:max_y+1, min_x:max_x+1] + sentence_subset= [] + for idx,sentence in np.ndenumerate(extracted): + if not (isinstance(sentence.statement, NALGrammar.Terms.CompoundTerm) + and sentence.statement.connector == NALSyntax.TermConnector.Negation): + sentence_subset.append(sentence) + + total_truth = None + statement_subset = [] + for sentence in sentence_subset: + if total_truth is None: + total_truth = sentence.value + else: + total_truth = NALInferenceRules.TruthValueFunctions.F_Intersection(sentence.value.frequency, + sentence.value.confidence, + total_truth.frequency, + total_truth.confidence) + statement_subset.append(sentence.statement) - # selection 1: small fixed windows - item = bag.peek() - radius = radius#random.randint(1,3) - element_idx_y, element_idx_x = item.object - - min_x, min_y = max(element_idx_x - radius, 0), max(element_idx_y - radius, 0) - max_x, max_y = min(element_idx_x + radius, self.array.shape[1]-1), min(element_idx_y + radius, self.array.shape[0]-1) - - - # selection 2: bounding box from random features - # item1 = bag.peek() - # item2 = item1 - # while item2 is item1: - # item2 = bag.peek() - # - # element1_idx_y, element1_idx_x = item1.object - # element2_idx_y, element2_idx_x = item2.object - # - # min_x, min_y = min(element1_idx_x, element2_idx_x), min(element1_idx_y, element2_idx_y) - # max_x, max_y = max(element1_idx_x, element2_idx_x), max(element1_idx_y, element2_idx_y) - - # extract subset of elements inside the bounding box (inclusive) - if pool: - event_subset = self.pooled_array[min_y:max_y + 1, min_x:max_x + 1] - else: - event_subset = self.array[min_y:max_y+1, min_x:max_x+1] - judgment = self.create_spatial_conjunction(event_subset) + # create conjunction of features + statement = NALGrammar.Terms.CompoundTerm(subterms=statement_subset, + term_connector=NALSyntax.TermConnector.Conjunction) - judgments = [judgment] + event_sentence = NALGrammar.Sentences.Judgment(statement=statement, + value=total_truth, + occurrence_time=Global.Global.get_current_cycle_number()) - center = ((min_y, min_x), (max_y, max_x)) - for j in judgments: - if j is not None: - j.statement.center = center - if not pool: - last_taken_img_array = np.zeros(shape=self.img.shape) - last_taken_img_array[min_y*2:(max_y+1)*2, 2*min_x:2*(max_x+1)] = self.img[min_y*2:(max_y+1)*2, 2*min_x:2*(max_x+1)] - self.last_taken_img_array = last_taken_img_array # store for visualization + # last_taken_img_array = np.zeros(shape=self.img.shape) + # last_taken_img_array[min_y+1:(max_y+1)+1, min_x+1:(max_x+1)+1] = self.img[min_y+1:(max_y+1)+1, min_x+1:(max_x+1)+1] + # self.last_taken_img_array = last_taken_img_array # store for visualization - return judgments + return event_sentence def create_spatial_conjunction(self, subset): """ @@ -486,7 +490,10 @@ def process_sentence(derived_sentence): event_task_A = temporal_chain[i].object event_A = event_task_A.sentence - if not (isinstance(event_A.statement, NALGrammar.Terms.CompoundTerm) and NALSyntax.TermConnector.is_conjunction(event_A.statement.connector)): continue + if not (isinstance(event_A.statement, NALGrammar.Terms.CompoundTerm) + and NALSyntax.TermConnector.is_conjunction(event_A.statement.connector) + and isinstance(event_A.statement.subterms[0], NALGrammar.Terms.CompoundTerm) + and NALSyntax.TermConnector.is_conjunction(event_A.statement.subterms[0].connector)): continue derived_sentences = NARSInferenceEngine.do_temporal_inference_two_premise(event_A, event_B) @@ -499,7 +506,7 @@ def temporal_chaining_2_conjunction(self): Perform temporal chaining produce all possible forward implication statements using temporal induction and intersection - A =/> B + A && B for the latest statement in the chain """ @@ -510,7 +517,9 @@ def temporal_chaining_2_conjunction(self): event_task_B = self.get_most_recent_event_task().object event_B = event_task_B.sentence - if not isinstance(event_B.statement, NALGrammar.Terms.SpatialTerm): return + if not (isinstance(event_B.statement, NALGrammar.Terms.CompoundTerm) + and NALSyntax.TermConnector.is_conjunction(event_B.statement.connector) + and (isinstance(event_B.statement.subterms[0], NALGrammar.Terms.SpatialTerm) or isinstance(event_B.statement.subterms[0], NALGrammar.Terms.StatementTerm))): return def process_sentence(derived_sentence): if derived_sentence is not None: @@ -523,7 +532,10 @@ def process_sentence(derived_sentence): event_task_A = temporal_chain[i].object event_A = event_task_A.sentence - if not isinstance(event_A.statement, NALGrammar.Terms.SpatialTerm): continue + if not (isinstance(event_A.statement, NALGrammar.Terms.CompoundTerm) + and NALSyntax.TermConnector.is_conjunction(event_A.statement.connector) + and (isinstance(event_A.statement.subterms[0], NALGrammar.Terms.SpatialTerm) or isinstance( + event_A.statement.subterms[0], NALGrammar.Terms.StatementTerm))): return derived_sentences = NARSInferenceEngine.do_temporal_inference_two_premise(event_A, event_B) diff --git a/TestCases/MNISTVisionTests.py b/TestCases/MNISTVisionTests.py index ceace2e..d814ae4 100644 --- a/TestCases/MNISTVisionTests.py +++ b/TestCases/MNISTVisionTests.py @@ -216,11 +216,11 @@ def binary_classification(): def digit_classification(): restart_NARS() - length = 400 - training_cycles = 125 + length = 500 + training_cycles = 200 x_train, y_train, x_test, y_test = load_dataset(length=length, bit=False, - percent_of_train_img=0.75) + percent_of_train_img=0.8) """ Training Phase @@ -719,7 +719,7 @@ def run_trials(q, current_best_score): q.put(avg_score) def test_main(): - time.sleep(10) + time.sleep(1) learn_best_params() #supervised_learning_binary_one_example() @@ -739,7 +739,7 @@ def test_main(): if __name__ == "__main__": global_gui = MNISTVisionTestGUI() - global_gui.gui_disabled = False + global_gui.gui_disabled = True if global_gui.gui_disabled: global_gui.start() else: