def test_multilayer(self):
        Input_Layer = TransferMechanism(
            name='Input Layer',
            function=Logistic,
            default_variable=np.zeros((2, )),
        )

        Hidden_Layer_1 = TransferMechanism(
            name='Hidden Layer_1',
            function=Logistic(),
            default_variable=np.zeros((5, )),
        )

        Hidden_Layer_2 = TransferMechanism(
            name='Hidden Layer_2',
            function=Logistic(),
            default_variable=[0, 0, 0, 0],
        )

        Output_Layer = TransferMechanism(
            name='Output Layer',
            function=Logistic,
            default_variable=[0, 0, 0],
        )

        Input_Weights_matrix = (np.arange(2 * 5).reshape((2, 5)) + 1) / (2 * 5)

        # TEST PROCESS.LEARNING WITH:
        # CREATION OF FREE STANDING PROJECTIONS THAT HAVE NO LEARNING (Input_Weights, Middle_Weights and Output_Weights)
        # INLINE CREATION OF PROJECTIONS (Input_Weights, Middle_Weights and Output_Weights)
        # NO EXPLICIT CREATION OF PROJECTIONS (Input_Weights, Middle_Weights and Output_Weights)

        # This projection will be used by the process below by referencing it in the process' pathway;
        #    note: sender and receiver args don't need to be specified
        Input_Weights = MappingProjection(
            name='Input Weights',
            matrix=Input_Weights_matrix,
        )

        p = Process(
            default_variable=[0, 0],
            pathway=[
                Input_Layer,
                # The following reference to Input_Weights is needed to use it in the pathway
                #    since it's sender and receiver args are not specified in its declaration above
                Input_Weights,
                Hidden_Layer_1,
                # No projection specification is needed here since the sender arg for Middle_Weights
                #    is Hidden_Layer_1 and its receiver arg is Hidden_Layer_2
                # Middle_Weights,
                Hidden_Layer_2,
                # Output_Weights does not need to be listed for the same reason as Middle_Weights
                # If Middle_Weights and/or Output_Weights is not declared above, then the process
                #    will assign a default for missing projection
                # Output_Weights,
                Output_Layer
            ],
            clamp_input=SOFT_CLAMP,
            target=[0, 0, 1],
            prefs={
                VERBOSE_PREF: False,
                REPORT_OUTPUT_PREF: True
            })

        s = System(processes=[p])

        s.reportOutputPref = True

        stim_list = {Input_Layer: [[-1, 30]]}

        s.run(
            num_trials=10,
            inputs=stim_list,
        )

        expected_Output_Layer_output = [
            np.array([0.97988347, 0.97988347, 0.97988347])
        ]

        np.testing.assert_allclose(expected_Output_Layer_output,
                                   Output_Layer.get_output_values(s))
def test_reinforcement():
    input_layer = TransferMechanism(
        default_variable=[0, 0, 0],
        name='Input Layer',
    )

    action_selection = TransferMechanism(
        default_variable=[0, 0, 0],
        function=SoftMax(
            output=PROB,
            gain=1.0,
        ),
        name='Action Selection',
    )

    p = Process(
        default_variable=[0, 0, 0],
        size=3,
        pathway=[input_layer, action_selection],
        learning=LearningProjection(learning_function=Reinforcement(
            learning_rate=0.05)),
        target=0,
    )

    # print ('reward prediction weights: \n', action_selection.input_states[0].path_afferents[0].matrix)
    # print ('targetMechanism weights: \n', action_selection.output_states.sendsToProjections[0].matrix)

    reward_values = [10, 10, 10]

    # Must initialize reward (won't be used, but needed for declaration of lambda function)
    action_selection.output_state.value = [0, 0, 1]
    # Get reward value for selected action)
    reward = lambda: [
        reward_values[int(np.nonzero(action_selection.output_state.value)[0])]
    ]

    def print_header(system):
        print("\n\n**** TRIAL: ",
              system.scheduler_processing.clock.simple_time)

    def show_weights():
        print(
            'Reward prediction weights: \n',
            action_selection.input_states[0].path_afferents[0].get_mod_matrix(
                s))
        print('\nAction selected:  {}; predicted reward: {}'.format(
            np.nonzero(action_selection.output_state.value)[0][0],
            action_selection.output_state.value[np.nonzero(
                action_selection.output_state.value)[0][0]],
        ))

    input_list = {input_layer: [[1, 1, 1]]}

    s = System(
        processes=[p],
        # learning_rate=0.05,
        targets=[0],
    )

    results = s.run(
        num_trials=10,
        inputs=input_list,
        targets=reward,
        call_before_trial=functools.partial(print_header, s),
        call_after_trial=show_weights,
    )

    results_list = []
    for elem in s.results:
        for nested_elem in elem:
            nested_elem = nested_elem.tolist()
            try:
                iter(nested_elem)
            except TypeError:
                nested_elem = [nested_elem]
            results_list.extend(nested_elem)

    mech_objective_action = s.mechanisms[2]
    mech_learning_input_to_action = s.mechanisms[3]

    reward_prediction_weights = action_selection.input_states[
        0].path_afferents[0]

    expected_output = [
        (input_layer.get_output_values(s), [np.array([1., 1., 1.])]),
        (action_selection.get_output_values(s),
         [np.array([0., 3.71496434, 0.])]),
        (pytest.helpers.expand_np_ndarray(
            mech_objective_action.get_output_values(s)),
         pytest.helpers.expand_np_ndarray(
             [np.array([6.28503566484375]),
              np.array(39.50167330835792)])),
        (pytest.helpers.expand_np_ndarray(
            mech_learning_input_to_action.get_output_values(s)),
         pytest.helpers.expand_np_ndarray([[
             np.array([0., 0.31425178324218755, 0.]),
             np.array([0., 0.31425178324218755, 0.])
         ]])),
        (reward_prediction_weights.get_mod_matrix(s),
         np.array([
             [1., 0., 0.],
             [0., 4.02921612, 0.],
             [0., 0., 1.8775],
         ])),
        (results, [
            [np.array([0., 1., 0.])],
            [np.array([0., 1.45, 0.])],
            [np.array([0., 0., 1.])],
            [np.array([0., 1.8775, 0.])],
            [np.array([0., 2.283625, 0.])],
            [np.array([0., 2.66944375, 0.])],
            [np.array([0., 0., 1.45])],
            [np.array([0., 3.03597156, 0.])],
            [np.array([0., 3.38417298, 0.])],
            [np.array([0., 3.71496434, 0.])],
        ]),
    ]

    for i, exp in enumerate(expected_output):
        val, expected = exp
        np.testing.assert_allclose(
            val, expected, err_msg='Failed on expected_output[{0}]'.format(i))
Example #3
0
def test_multilayer():
    Input_Layer = TransferMechanism(
        name='Input Layer',
        function=Logistic,
        default_variable=np.zeros((2, )),
    )

    Hidden_Layer_1 = TransferMechanism(
        name='Hidden Layer_1',
        function=Logistic(),
        # default_variable=np.zeros((5,)),
        size=5)

    Hidden_Layer_2 = TransferMechanism(
        name='Hidden Layer_2',
        function=Logistic(),
        default_variable=[0, 0, 0, 0],
    )

    Output_Layer = TransferMechanism(
        name='Output Layer',
        function=Logistic,
        default_variable=[0, 0, 0],
    )

    Input_Weights_matrix = (np.arange(2 * 5).reshape((2, 5)) + 1) / (2 * 5)
    Middle_Weights_matrix = (np.arange(5 * 4).reshape((5, 4)) + 1) / (5 * 4)
    Output_Weights_matrix = (np.arange(4 * 3).reshape((4, 3)) + 1) / (4 * 3)

    # TEST PROCESS.LEARNING WITH:
    # CREATION OF FREE STANDING PROJECTIONS THAT HAVE NO LEARNING (Input_Weights, Middle_Weights and Output_Weights)
    # INLINE CREATION OF PROJECTIONS (Input_Weights, Middle_Weights and Output_Weights)
    # NO EXPLICIT CREATION OF PROJECTIONS (Input_Weights, Middle_Weights and Output_Weights)

    # This projection will be used by the process below by referencing it in the process' pathway;
    #    note: sender and receiver args don't need to be specified
    Input_Weights = MappingProjection(
        name='Input Weights',
        matrix=Input_Weights_matrix,
    )

    # This projection will be used by the process below by assigning its sender and receiver args
    #    to mechanismss in the pathway
    Middle_Weights = MappingProjection(
        name='Middle Weights',
        sender=Hidden_Layer_1,
        receiver=Hidden_Layer_2,
        matrix=Middle_Weights_matrix,
    )

    # Commented lines in this projection illustrate variety of ways in which matrix and learning signals can be specified
    Output_Weights = MappingProjection(
        name='Output Weights',
        sender=Hidden_Layer_2,
        receiver=Output_Layer,
        matrix=Output_Weights_matrix,
    )

    p = Process(
        # default_variable=[0, 0],
        size=2,
        pathway=[
            Input_Layer,
            # The following reference to Input_Weights is needed to use it in the pathway
            #    since it's sender and receiver args are not specified in its declaration above
            Input_Weights,
            Hidden_Layer_1,
            # No projection specification is needed here since the sender arg for Middle_Weights
            #    is Hidden_Layer_1 and its receiver arg is Hidden_Layer_2
            # Middle_Weights,
            Hidden_Layer_2,
            # Output_Weights does not need to be listed for the same reason as Middle_Weights
            # If Middle_Weights and/or Output_Weights is not declared above, then the process
            #    will assign a default for missing projection
            # Output_Weights,
            Output_Layer
        ],
        clamp_input=SOFT_CLAMP,
        learning=LEARNING,
        learning_rate=1.0,
        target=[0, 0, 1],
        prefs={
            VERBOSE_PREF: False,
            REPORT_OUTPUT_PREF: False
        },
    )

    stim_list = {Input_Layer: [[-1, 30]]}
    target_list = {Output_Layer: [[0, 0, 1]]}

    def show_target():
        i = s.input
        t = s.target_input_states[0].parameters.value.get(s)
        print('\nOLD WEIGHTS: \n')
        print('- Input Weights: \n', Input_Weights.get_mod_matrix(s))
        print('- Middle Weights: \n', Middle_Weights.get_mod_matrix(s))
        print('- Output Weights: \n', Output_Weights.get_mod_matrix(s))
        print('\nSTIMULI:\n\n- Input: {}\n- Target: {}\n'.format(i, t))
        print('ACTIVITY FROM OLD WEIGHTS: \n')
        print('- Middle 1: \n', Hidden_Layer_1.parameters.value.get(s))
        print('- Middle 2: \n', Hidden_Layer_2.parameters.value.get(s))
        print('- Output:\n', Output_Layer.parameters.value.get(s))

    s = System(
        processes=[p],
        targets=[0, 0, 1],
        learning_rate=1.0,
    )

    # s.reportOutputPref = True

    results = s.run(
        num_trials=10,
        inputs=stim_list,
        targets=target_list,
        call_after_trial=show_target,
    )

    objective_output_layer = s.mechanisms[4]

    results_list = []
    for elem in s.results:
        for nested_elem in elem:
            nested_elem = nested_elem.tolist()
            try:
                iter(nested_elem)
            except TypeError:
                nested_elem = [nested_elem]
            results_list.extend(nested_elem)

    expected_output = [
        (Output_Layer.get_output_values(s),
         [np.array([0.22686074, 0.25270212, 0.91542149])]),
        (objective_output_layer.output_states[MSE].parameters.value.get(s),
         np.array(0.04082589331852094)),
        (Input_Weights.get_mod_matrix(s),
         np.array([
             [0.09900247, 0.19839653, 0.29785764, 0.39739191, 0.49700232],
             [0.59629092, 0.69403786, 0.79203411, 0.89030237, 0.98885379],
         ])),
        (Middle_Weights.get_mod_matrix(s),
         np.array([
             [0.09490249, 0.10488719, 0.12074013, 0.1428774],
             [0.29677354, 0.30507726, 0.31949676, 0.3404652],
             [0.49857336, 0.50526254, 0.51830509, 0.53815062],
             [0.70029406, 0.70544225, 0.71717037, 0.73594383],
             [0.90192903, 0.90561554, 0.91609668, 0.93385292],
         ])),
        (Output_Weights.get_mod_matrix(s),
         np.array([
             [-0.74447522, -0.71016859, 0.31575293],
             [-0.50885177, -0.47444784, 0.56676582],
             [-0.27333719, -0.23912033, 0.8178167],
             [-0.03767547, -0.00389039, 1.06888608],
         ])),
        (results, [[np.array([0.8344837, 0.87072018, 0.89997433])],
                   [np.array([0.77970193, 0.83263138, 0.90159627])],
                   [np.array([0.70218502, 0.7773823, 0.90307765])],
                   [np.array([0.60279149, 0.69958079, 0.90453143])],
                   [np.array([0.4967927, 0.60030321, 0.90610082])],
                   [np.array([0.4056202, 0.49472391, 0.90786617])],
                   [np.array([0.33763025, 0.40397637, 0.90977675])],
                   [np.array([0.28892812, 0.33633532, 0.9117193])],
                   [np.array([0.25348771, 0.28791896, 0.9136125])],
                   [np.array([0.22686074, 0.25270212, 0.91542149])]]),
    ]

    # Test nparray output of log for Middle_Weights

    for i in range(len(expected_output)):
        val, expected = expected_output[i]
        # setting absolute tolerance to be in accordance with reference_output precision
        # if you do not specify, assert_allcose will use a relative tolerance of 1e-07,
        # which WILL FAIL unless you gather higher precision values to use as reference
        np.testing.assert_allclose(
            val,
            expected,
            atol=1e-08,
            err_msg='Failed on expected_output[{0}]'.format(i))
Example #4
0
    def test_compositions_as_origin_nodes(self, mode):

        inner_composition_1 = Composition(name="inner_composition_1")

        A = TransferMechanism(name="A", function=Linear(slope=0.5))

        B = TransferMechanism(name="B", function=Linear(slope=2.0))

        C = TransferMechanism(name="C", function=Linear(slope=3.0))

        inner_composition_1.add_node(A)
        inner_composition_1.add_node(B)
        inner_composition_1.add_node(C)

        inner_composition_1.add_projection(MappingProjection(), A, C)
        inner_composition_1.add_projection(MappingProjection(), B, C)

        inner_composition_1._analyze_graph()

        inner_composition_2 = Composition(name="inner_composition_2")

        A2 = TransferMechanism(name="A2", function=Linear(slope=0.25))

        B2 = TransferMechanism(name="B2", function=Linear(slope=1.0))

        inner_composition_2.add_node(A2)
        inner_composition_2.add_node(B2)

        inner_composition_2.add_projection(MappingProjection(), A2, B2)

        inner_composition_2._analyze_graph()

        mechanism_d = TransferMechanism(name="D", function=Linear(slope=3.0))

        outer_composition = Composition(name="outer_composition")

        outer_composition.add_node(inner_composition_1)
        outer_composition.add_node(inner_composition_2)
        outer_composition.add_node(mechanism_d)

        outer_composition.add_projection(projection=MappingProjection(),
                                         sender=inner_composition_1,
                                         receiver=mechanism_d)
        outer_composition.add_projection(projection=MappingProjection(),
                                         sender=inner_composition_2,
                                         receiver=mechanism_d)

        sched = Scheduler(composition=outer_composition)
        outer_composition._analyze_graph()

        # FIX: order of InputStates on inner composition 1 is not stable
        output = outer_composition.run(
            inputs={
                # inner_composition_1: [[2.0], [1.0]],
                inner_composition_1: {
                    A: [2.0],
                    B: [1.0]
                },
                inner_composition_2: [[12.0]]
            },
            scheduler_processing=sched,
            bin_execute=mode)
        assert np.allclose(output, [[[36.]]])

        if mode == 'Python':
            assert np.allclose(A.get_output_values(outer_composition), [[1.0]])
            assert np.allclose(B.get_output_values(outer_composition), [[2.0]])
            assert np.allclose(C.get_output_values(outer_composition), [[9.0]])
            assert np.allclose(A2.get_output_values(outer_composition),
                               [[3.0]])
            assert np.allclose(B2.get_output_values(outer_composition),
                               [[3.0]])
            assert np.allclose(
                inner_composition_1.get_output_values(outer_composition),
                [[9.0]])
            assert np.allclose(
                inner_composition_2.get_output_values(outer_composition),
                [[3.0]])
            assert np.allclose(
                mechanism_d.get_output_values(outer_composition), [[36.0]])
            assert np.allclose(
                outer_composition.get_output_values(outer_composition),
                [[36.0]])