def __iter__(self): for i in range(self.length): state = random.randint(0, 1) if state == 0: yield nd.NumDict({feature("A"): 1, feature("B"): 0}) else: yield nd.NumDict({feature("A"): 0, feature("B"): 1})
def test_call_returns_empty_numdict_when_no_rules_exist(self): rules = Rules(max_conds=1) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } action_rules = ActionRules( source=chunks(1), rules=rules, temperature=1 # high temperature to ensure variety ) strengths = action_rules.call(inputs) self.assertEqual(len(strengths), 0, msg="Unexpected items in output.")
def test_rule_selection_follows_boltzmann_distribution(self): rules = Rules(max_conds=1) rules.define(rule("A"), chunk("Action 1"), chunk("Condition A")) rules.define(rule("B"), chunk("Action 1"), chunk("Condition B")) rules.define(rule("C"), chunk("Action 1"), chunk("Condition C")) rules.define(rule("D"), chunk("Action 2"), chunk("Condition D")) rules.define(rule("E"), chunk("Action 2"), chunk("Condition E")) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } get_rule = lambda c: rule(c.cid[-1]) action_rules = ActionRules( source=chunks(1), rules=rules, temperature=.1 # relatively high temperature to ensure variety ) expected = nd.transform_keys(inputs[chunks(1)], func=get_rule) expected = nd.boltzmann(expected, t=.1) expected = nd.with_default(expected, default=None) N = 100 selected = [] is_rule = lambda sym: sym.ctype in ConstructType.rule for _ in range(N): strengths = action_rules.call(inputs) s = nd.keep(strengths, func=is_rule) s = nd.threshold(s, th=0) s = s.constant(val=1) s = nd.with_default(s, default=0) selected.append(s) counts = nd.ew_sum(*selected) terms = ((counts - (N * expected))**2) / (N * expected) chi_square_stat = nd.val_sum(terms) critical_value = 9.488 # for chi square w/ 4 df @ alpha = .05 self.assertFalse(critical_value < chi_square_stat, msg="Chi square test significant at alpha = .05.")
def test_call_activates_unique_action_and_rule_pair(self): rules = Rules(max_conds=1) rules.define(rule("A"), chunk("Action 1"), chunk("Condition A")) rules.define(rule("B"), chunk("Action 1"), chunk("Condition B")) rules.define(rule("C"), chunk("Action 1"), chunk("Condition C")) rules.define(rule("D"), chunk("Action 2"), chunk("Condition D")) rules.define(rule("E"), chunk("Action 2"), chunk("Condition E")) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } action_rules = ActionRules( source=chunks(1), rules=rules, temperature=1 # high temperature to ensure variety ) strengths = action_rules.call(inputs) above_zero = nd.threshold(strengths, th=0.0) self.assertEqual( len(above_zero), 2, msg="Expected at most two items above zero activation.") if chunk("Action 1") in above_zero: self.assertTrue(rule("A") in above_zero or rule("B") in above_zero or rule("C") in above_zero, msg="Unexpected rule paired with Action 1.") if chunk("Action 2") in above_zero: self.assertTrue(rule("D") in above_zero or rule("E") in above_zero, msg="Unexpected rule paired with Action 2.")
# The basic tool for automatic differentiation is the GradientTape, which is a # context manager that tracks operations on numdicts and provides methods for # computing gradients over recorded tapes. # In the simplest case, the tape may be used in 'eager' mode. In this mode, the # tape will record all registered ops carried out in the tape scope and flush # its data when gradients are retrieved. tape = nd.GradientTape() print("Example 1") print() with tape: d1 = nd.NumDict(default=1.0) d2 = nd.NumDict(default=2.0) d3 = d1 * d2 # We can inspect the contents of the gradient tape through the data property. pprint(tape.data) print() # To get the gradients of d1 and d2 with respect to d3, it is sufficient to # call the tape.gradients() method. d3, grads = tape.gradients(d3, (d1, d2)) print("d3:", d3) print("grads:", grads)
def test_goal_buffer_push(self): # TODO: Add assertions... interface = GoalStay.Interface(name="gctl", goals=(feature("goal", "select"), feature("goal", "analyze"), feature("goal", "evaluate"), feature("gobj", "attribute"), feature("gobj", "response"), feature("gobj", "pattern"))) chunks = Chunks() blas = BLAs(density=1.0) gb = GoalStay(controller=(subsystem("acs"), terminus("gb_actions")), source=(subsystem("ms"), terminus("goal_selection")), interface=interface, chunks=chunks, blas=blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".w"): 1.0, feature(("gctl", "goal"), "analyze"): 1.0, feature(("gctl", "gobj"), "pattern"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict(default=0) } output = gb.call(inputs) chunks.step() # pprint(output) # pprint(chunks) # pprint(blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".w"): 1.0, feature(("gctl", "goal"), "evaluate"): 1.0, feature(("gctl", "gobj"), "attribute"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict(default=0) } output = gb.call(inputs) chunks.step() # pprint(output) # pprint(chunks) # pprint(blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".f"): 1.0, feature(("gctl", "goal"), "analyze"): 1.0, feature(("gctl", "gobj"), "pattern"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict({chunk(".goal_1"): 1.0}) } output = gb.call(inputs) chunks.step()
ext_actions = Construct(name=terminus("ext_actions"), process=ActionSelector( source=features("out"), interface=learner.assets.interface, temperature=0.05)) ################## ### Simulation ### ################## # We are ready to run the task. We'll run it for 800 trials with an initial # reinforcement of 0. task = ABTask(800) r = nd.NumDict({feature(("r", "respond")): 0}) losses, rs, qs = [], [], [] for stimulus in task: sensory.process.input(stimulus) reinforcement.process.input(r) learner.step() r = task.reinforcements(stimulus=stimulus, actions=ext_actions.output) q = qnet.output losses.append(qnet.process.loss) rs.append(r) qs.append(q)