Composition

Overview

Composition is the base class for objects that combine PsyNeuLink Components into an executable model. It defines a common set of attributes possessed, and methods used by all Composition objects.

Composition “Nodes” are Mechanisms and/or nested Compositions. Projections connect two Nodes. The Composition’s graph stores the structural relationships among the Nodes of a Composition and the Projections that connect them. The Composition’s scheduler generates an execution queue based on these structural dependencies, allowing for other user-specified scheduling and termination conditions to be specified.

Creating a Composition

A generic Composition can be created by calling the constructor, and then adding Components using the following Composition methods:

  • add_node

    adds a node to the Composition

  • add_nodes

    adds mutiple nodes to the Composition

  • add_projection

    adds a connection between a pair of nodes in the Composition

  • add_projections

    adds connection between multiple pairs of nodes in the Composition

  • add_linear_processing_pathway

    adds and connects a list of nodes and/or Projections to the Composition; Inserts a default Projection between any adjacent Nodes.

In addition, a Composition has the following set of learning methods that can also be used to create a Composition from (or add) pathways that implement learning:

Note

Only Mechanisms and Projections added to a Composition via the methods above constitute a Composition, even if other Mechanism and/or Projections are constructed in the same script.

In the following script comp_0, comp_1 and comp_2 are identical, but constructed using different methods.

Create Mechanisms:

>>> import psyneulink as pnl
>>> A = pnl.ProcessingMechanism(name='A')
>>> B = pnl.ProcessingMechanism(name='B')
>>> C = pnl.ProcessingMechanism(name='C')

Create Projections:

>>> A_to_B = pnl.MappingProjection(name="A-to-B")
>>> B_to_C = pnl.MappingProjection(name="B-to-C")

Create Composition; Add Nodes (Mechanisms) and Projections via the add_linear_processing_pathway method:

>>> comp_0 = pnl.Composition(name='comp-0')
>>> comp_0.add_linear_processing_pathway(pathway=[A, A_to_B, B, B_to_C, C])

Create Composition; Add Nodes (Mechanisms) and Projections via the add_nodes and add_projection methods:

>>> comp_1 = pnl.Composition(name='comp-1')
>>> comp_1.add_nodes(nodes=[A, B, C])
>>> comp_1.add_projection(projection=A_to_B)
>>> comp_1.add_projection(projection=B_to_C)

Create Composition; Add Nodes (Mechanisms) and Projections via the add_node and add_projection methods:

>>> comp_2 = pnl.Composition(name='comp-2')
>>> comp_2.add_node(node=A)
>>> comp_2.add_node(node=B)
>>> comp_2.add_node(node=C)
>>> comp_2.add_projection(projection=A_to_B)
>>> comp_2.add_projection(projection=B_to_C)

Run each Composition:

>>> input_dict = {A: [[[1.0]]]}
>>> comp_0_output = comp_0.run(inputs=input_dict)
>>> comp_1_output = comp_1.run(inputs=input_dict)
>>> comp_2_output = comp_2.run(inputs=input_dict)

Nested Compositions

A Composition can be used as a node of another Composition, by calling add_node from the parent composition using the child Composition as an argument. Projections can then be specifed to and from the nested composition just as for any other node.

Create outer Composition:

>>> outer_A = pnl.ProcessingMechanism(name='outer_A')
>>> outer_B = pnl.ProcessingMechanism(name='outer_B')
>>> outer_comp = pnl.Composition(name='outer_comp')
>>> outer_comp.add_nodes([outer_A, outer_B])

Create and configure inner Composition:

>>> inner_A = pnl.ProcessingMechanism(name='inner_A')
>>> inner_B = pnl.ProcessingMechanism(name='inner_B')
>>> inner_comp = pnl.Composition(name='inner_comp')
>>> inner_comp.add_linear_processing_pathway([inner_A, inner_B])

Nest inner Composition within outer Composition using `add_node <Composition.add_node>`:

>>> outer_comp.add_node(inner_comp)

Create Projections:

>>> outer_comp.add_projection(pnl.MappingProjection(), sender=outer_A, receiver=inner_comp)
>>> outer_comp.add_projection(pnl.MappingProjection(), sender=inner_comp, receiver=outer_B)
>>> input_dict = {outer_A: [[[1.0]]]}

Run Composition:

>>> outer_comp.run(inputs=input_dict)

Using `add_linear_processing_pathway <Composition.add_linear_processing_pathway>` with nested compositions for brevity:

>>> outer_A = pnl.ProcessingMechanism(name='outer_A')
>>> outer_B = pnl.ProcessingMechanism(name='outer_B')
>>> outer_comp = pnl.Composition(name='outer_comp')
>>> inner_A = pnl.ProcessingMechanism(name='inner_A')
>>> inner_B = pnl.ProcessingMechanism(name='inner_B')
>>> inner_comp = pnl.Composition(name='inner_comp')
>>> inner_comp.add_linear_processing_pathway([inner_A, inner_B])
>>> outer_comp.add_linear_processing_pathway([outer_A, inner_comp, outer_B])
>>> input_dict = {outer_A: [[[1.0]]]}
>>> outer_comp.run(inputs=input_dict)

Running a Composition

Inputs

The run method presents the inputs for each TRIAL to the input_states of the INPUT Nodes in the scope of execution. These input values are specified in the inputs argument of a Composition’s execute or run methods.

The standard way to specificy inputs is a Python dictionary in which each key is an INPUT Node and each value is a list. The lists represent the inputs to the key INPUT Nodes, in which the i-th element of the list represents the input value to the key Node on trial i.

Example input specifications with input states

Each input value must be compatible with the shape of the key INPUT Node’s external_input_values. As a result, each item in the list of inputs is typically a 2d list/array, though some shorthand notations are allowed.

>>> import psyneulink as pnl
>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[0.0, 0.0]])
>>> b = pnl.TransferMechanism(name='b',
...                           default_variable=[[0.0], [0.0]])
>>> c = pnl.TransferMechanism(name='c')
>>> pathway1 = [a, c]
>>> pathway2 = [b, c]
>>> comp = Composition(name='comp')
>>> comp.add_linear_processing_pathway(pathway1)
>>> comp.add_linear_processing_pathway(pathway2)
>>> input_dictionary = {a: [[[1.0, 1.0]], [[1.0, 1.0]]],
...                     b: [[[2.0], [3.0]], [[2.0], [3.0]]]}
>>> comp.run(inputs=input_dictionary)

Note

A Node’s external_input_values attribute is always a 2d list in which the index i element is the value of the Node’s index i external_input_state. In many cases, external_input_values is the same as variable. Keep in mind that any InputStates marked as “internal” are excluded from external_input_values, and do not receive user-specified input values.

If num_trials is not in use, the number of inputs provided determines the number of trials in the run. For example, if five inputs are provided for each INPUT Node, and num_trials is not specified, the Composition executes five times.

Trial # 0 1 2 3 4
Input to Mechanism a 1.0 2.0 3.0 4.0 5.0
>>> import psyneulink as pnl
>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> comp.add_linear_processing_pathway(pathway1)
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary)

The number of inputs specified must be the same for all Nodes in the input dictionary (except for any Nodes for which only one input is specified). In other words, all of the values in the input dictionary must have the same length as each other (or length 1).

If num_trials is in use, run iterates over the inputs until num_trials is reached. For example, if five inputs are provided for each INPUT Node, and num_trials = 7, the system executes seven times. The input values from trials 0 and 1 are used again on trials 5 and 6, respectively.

Trial # 0 1 2 3 4 5 6
Input to Mechanism a 1.0 2.0 3.0 4.0 5.0 1.0 2.0
>>> import psyneulink as pnl
>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> comp.add_linear_processing_pathway(pathway1)
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary,
...          num_trials=7)

For convenience, condensed versions of the input specification described above are also accepted in the following situations:

  • Case 1: INPUT Node has only one input state
Trial # 0 1 2 3 4
Input to Mechanism a 1.0 2.0 3.0 4.0 5.0

Complete input specification:

>>> import psyneulink as pnl
>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> comp.add_linear_processing_pathway(pathway1)
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on each input because Mechanism a only has one input state:

>>> input_dictionary = {a: [[1.0], [2.0], [3.0], [4.0], [5.0]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the remaining list on each input because Mechanism a’s one input state’s value is length 1:

>>> input_dictionary = {a: [1.0, 2.0, 3.0, 4.0, 5.0]}
>>> comp.run(inputs=input_dictionary)
  • Case 2: Only one input is provided for the INPUT Node
Trial # 0
Input to Mechanism a [[1.0], [2.0]]

Complete input specification:

>>> import psyneulink as pnl
>>> a = pnl.TransferMechanism(name='a',
                              default_variable=[[0.0], [0.0]])
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> comp.add_linear_processing_pathway(pathway1)
>>> input_dictionary = {a: [[[1.0], [2.0]]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on Mechanism a’s input specification because there is only one trial:

>>> input_dictionary = {a: [[1.0], [2.0]]}
>>> comp.run(inputs=input_dictionary)
  • Case 3: The same input is used on all trials
Trial # 0 1 2 3 4
Input to Mechanism a [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]]

Complete input specification:

>>> import psyneulink as pnl

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[0.0], [0.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = Composition(name='comp')

>>> comp.add_linear_processing_pathway(pathway1)

>>> input_dictionary = {a: [[[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]]]}

>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on Mechanism a’s input specification and use num_trials to repeat the input value

>>> input_dictionary = {a: [[1.0], [2.0]]}

>>> comp.run(inputs=input_dictionary,
...          num_trials=5)
  • Case 4: There is only one INPUT Node
Trial # 0 1
Input to Mechanism a [1.0, 2.0, 3.0] [1.0, 2.0, 3.0]

Complete input specification:

>>> import psyneulink as pnl

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[1.0, 2.0, 3.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = Composition(name='comp')

>>> comp.add_linear_processing_pathway(pathway1)

>>> input_dictionary = input_dictionary = {a: [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]}

>>> comp.run(inputs=input_dictionary)

Shorthand - specify Mechanism a’s inputs in a list because it is the only INPUT Node

>>> input_list = [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]

>>> comp.run(inputs=input_list)

Interactive Inputs

An alternative way to specify inputs is with a function. The function must return a dictionary that satisfies the rules above for standard input specification. The only difference is that on each execution, the function returns the input values for each INPUT Node for a single trial.

Controlling a Composition

A Composition can be assigned a controller. This is a Control Mechanisms, or a subclass of one, that modulates the parameters of Components within the Composition (including Components of nested Compositions). It typically does this based on the output of an ObjectiveMechanism that evaluates the value of other Mechanisms in the Composition, and provides the result to the controller.

Assigning a Controller

A controller can be assigned either by specifying it in the controller argument of the Composition’s constructor, or using its add_controller method.

Controller Execution

The controller is executed only if the Composition’s enable_controller attribute is True. This generally done automatically when the controller is assigned. If enabled, the controller is generally executed either before or after all of the other Components in the Composition have been executed, as determined by the Composition’s controller_mode attribute. However, the Composition’s controller_condition attribute can be used to customize when it is executed. All three of these attributes can be specified in corresponding arguments of the Composition’s constructor, or programmatically after it is constructed by assigning the desired value to the attribute.

Learning in a Composition

Learning is used to modify the Projections between Mechanisms in a Composition. More specifically, it modifies the matrix parameter of those MappingProjections, which implements the strengths (“weights”) of the associations between representations in the Mechanisms they connect. There are three ways of implementing learning in a Composition: i) using standard PsyNeuLink Components; ii) using the AutodiffComposition – a specialized subclass of Composition that executes learning using PyTorch; and iii) by using UserDefinedFunctions. The advantage of using standard PsyNeuLink compoments is that it assigns each operation involved in learning to a dedicated Component. This helps make clear exactly what those operations are, the sequence in which they are carried out, and how they interact with one another. However, this can also make execution inefficient, due to the “overhead” incurred by distributing the calculations over different Components. If more efficient computation is critical, then the AutodiffComposition can be used to execute a compatible PsyNeuLink Composition in PyTorch, or one or more UserDefinedFunctions can be assigned to either PyTorch functions or those in any other Python environment that implements learning and accepts and returns tensors. Each of these approaches is described in more detail below.

Learning Using AutodiffCompositon

The AutodiffComposition can be used to implement a Composition in PsyNeuLink, which is then executed using PyTorch (see example in Basics and Sampler). The AutodiffComposition constructor provides arguments for configuring the PyTorch implementation in various ways; the Composition is then built using the same methods (e.g., add_node, add_projection, add_linear_processing_pathway, etc.) as any other Composition, and it is executed using its run method. Note that there is no need to use any learning methods — the Composition is translated into PyTorch objects and functions, which are called when it is run. It can be run in training mode (during which learning occurs) or test mode (which runs the Composition without learning).

The advantage of this approach is that it allows the Composition to be implemented in PsyNeuLink, while exploiting the efficiency of execution in PyTorch (which can yield as much as three orders of magnitude improvement). However, a disadvantage is that there are restrictions on the kinds of Compositions that be implemented in this way. First, because it relies on PyTorch, it is best suited for use with supervised learning, although it can be used for some forms of unsupervised learning that are supported in PyTorch (e.g., self-organized maps). Second, all of the Components in the Composition are be subject to and must be with compatible with learning. This means that it cannot be used with a Composition that contains any modulatory components or that are subject to modulation, whether by ControlMechanisms within or outside the Composition; this includes a controller or any LearningMechanisms. An AutodiffComposition can be nested in a Composition that has such other Components. During learning, none of the internal Components of the AutodiffComposition (e.g., intermediate layers of a neural network model) are accessible to the other Components of the outer Composition, (e.g., as sources of information, or for modulation). However, when learning turned off, then the AutodiffComposition functions like any other, and all of its internal Components accessible to other Components of the outer Composition. Thus, as long as access to its internal Components is not needed during learning, an AutodiffComposition can be trained, and then used to execute the trained Composition like any other.

Learning Using UserDefinedFunctions

If execution efficiency is critical and the AutodiffComposition is too restrictive, a function from any Python environment that supports learning can be assigned as the function of a Mechanisms, in which case it is automatically wrapped as UserDefinedFunction. For example, the forward and backward methods of a PyTorch object can be assigned in this way. The advanatage of this approach is that it can be applied to any Python function that adheres to the requirements of a UserDefinedFunction. The disadvantage is that it can’t be compiled, so efficiency may be compromised. It must also be carefully coordinated with the execution of other learning-related Components in the Composition, to insure that each function is called at the appropriate times during execution. Furthermore, as with an AutodiffComposition, the internal constituents of the object (e.g., intermediates layers of a neural network model) are not accessible to other Components in the Composition (e.g., as a source of information or for modulation).

Visualizing a Composition

The show_graph method generates a display of the graph structure of Nodes (Mechanisms and Nested Compositions) and Projections in the Composition (based on the Composition’s processing graph).

By default, Nodes are shown as ovals labeled by their names, with the Composition’s INPUT Mechanisms shown in green, its OUTPUT Mechanisms shown in red, and Projections shown as unlabeled arrows, as illustrated for the Composition in the example below:

>>> from psyneulink import *
>>> a = ProcessingMechanism(
              name='A',
...           size=3,
...           output_states=[RESULTS, OUTPUT_MEAN]
...           )
>>> b = ProcessingMechanism(
...           name='B',
...           size=5
...           )
>>> c = ProcessingMechanism(
...           name='C',
...           size=2,
...           function=Logistic(gain=pnl.CONTROL)
...           )
>>> comp = Composition(
...           name='Comp',
...           enable_controller=True
...           )
>>> comp.add_linear_processing_pathway([a,c])
>>> comp.add_linear_processing_pathway([b,c])
>>> ctlr = OptimizationControlMechanism(
...            name='Controller',
...            monitor_for_control=[(pnl.OUTPUT_MEAN, a)],
...            function=GridSearch,
...            control_signals=(GAIN, c),
...            agent_rep=comp
...            )
>>> comp.add_controller(ctlr)
_images/show_graph_basic.svg

Note that the Composition’s controller is not shown by default. However this can be shown, along with other information, using options in the Composition’s show_graph method. The figure below shows several examples.

Output of show_graph using different options

Composition graph examples

Displays of the Composition used in the example above, generated using various options of its show_graph method. Panel A shows the graph with its Projections labeled and Component dimensions displayed. Panel B shows the controller for the Composition and its associated ObjectiveMechanism using the show_controller option (controller-related Components are displayed in blue by default). Panel C adds the Composition’s CompositionInterfaceMechanisms using the show_cim option. Panel D shows a detailed view of the Mechanisms using the show_node_structure option, that includes their States and their roles in the Composition. Panel E show an even more detailed view using show_node_structure as well as show_cim.

If a Composition has one ore more Compositions nested as Nodes within it, then these can be shown using the show_nested option. For example, if two Compositions identical to comp in the example above are added as the nodes of the linear processing pathway of a third* comp *, these can be shown as follows:

>>> comp.show_graph()
_images/nested.svg
>>> comp.show_graph(show_nested=True)
_images/show_nested.svg

Class Reference

class psyneulink.core.compositions.composition.Composition(name=None, controller: psyneulink.core.components.mechanisms.modulatory.control.controlmechanism.ControlMechanism = None, enable_controller=None, controller_mode: <typecheck.tc_predicates.enum object at 0x11fcc1c18> = 'after', controller_condition: psyneulink.core.scheduling.condition.Condition = <psyneulink.core.scheduling.condition.Always object>, enable_learning=False, retain_old_simulation_data=None, prefs=None, **param_defaults)
Parameters:
  • controller (OptimizationControlmechanism : default None) – specifies the OptimizationControlMechanism to use as the Composition’s controller (see Controlling a Composition for details).
  • enable_controller (bool : default None) – specifies whether the Composition’s controller is executed when the Composition is executed. Set to True by default if controller specified; if set to False, the controller is ignored when the Composition is executed.
  • controller_mode (Enum[BEOFRE|AFTER] : default AFTER) – specifies whether the controller is executed before or after the rest of the Composition in each trial. Must be either the keyword BEFORE or AFTER.
  • controller_condition (Condition : default Always) – specifies when the Composition’s controller is executed in a trial.
  • enable_learning (bool : default True) – specifies whether LearningMechanisms in the Composition are executed when it is executed.
  • name (str : default see name) – specifies the name of the Composition.
  • prefs (PreferenceSet or specification dict : default Composition.classPreferences) – specifies the PreferenceSet for the Composition; see prefs for details.
graph

Graph – the full Graph associated with this Composition. Contains both Nodes (Mechanisms or Compositions) and Projections

nodes

list[Mechanisms and Compositions] – a list of all Nodes (Mechanisms and/or Compositions) contained in this Composition

input_CIM

CompositionInterfaceMechanism – mediates input values for the INPUT nodes of the Composition. If the Composition is nested, then the input_CIM and its InputStates serve as proxies for the Composition itself in terms of afferent projections.

input_CIM_states

dict – a dictionary in which keys are InputStates of INPUT Nodes in a composition, and values are lists containing two items: the corresponding InputState and OutputState on the input_CIM.

afferents

ContentAddressableList – a list of all of the Projections to the Composition’s input_CIM.

output_CIM

CompositionInterfaceMechanism – aggregates output values from the OUTPUT nodes of the Composition. If the Composition is nested, then the output_CIM and its OutputStates serve as proxies for Composition itself in terms of efferent projections.

output_CIM_states

dict – a dictionary in which keys are OutputStates of OUTPUT Nodes in a composition, and values are lists containing two items: the corresponding InputState and OutputState on the input_CIM.

efferents

ContentAddressableList – a list of all of the Projections from the Composition’s output_CIM.

env

Gym Forager Environment : default: None – stores a Gym Forager Environment so that the Composition may interact with this environment within a single call to run.

shadows

dict – a dictionary in which the keys are all in the Composition and the values are lists of any Nodes that shadow the original Node’s input.

controller

OptimizationControlMechanism – identifies the OptimizationControlMechanism used as the Composition’s controller (see Controlling a Composition for details).

enable_controller

bool – determines whether the Composition’s controller is executed in each trial (see controller_mode <Composition.controller_mode>` for timing of execution). Set to True by default if controller is specified. Setting it to False suppresses exectuion of the controller.

controller_mode

BEFORE or AFTER – determines whether the controller is executed before or after the rest of the Composition is executed on each trial.

controller_condition

Condition – specifies whether the controller is executed in a given trial. The default is Always, which executes the controller on every trial.

default_execution_id

if no context is specified in a call to run, this context is used; by default, it is the Composition’s name.

execution_ids

set – stores all execution_ids used by this Composition.

enable_learning

bool : default True – determines whether LearningMechanisms in the Composition are executed when it is executed.

learning_components

list – contains the learning-related components in the Composition, all or many of which may have been created automatically in a call to one of its add_<*learning_type*>_pathway' methods (see `Composition_Learning for details). This does not contain the ProcessingMechanisms or MappingProjections in the pathway(s) being learned; those are contained in learning_pathways attribute.

learned_components

list[list] – contains a list of the components subject to learning in the Composition (ProcessingMechanisms and MappingProjections); this does not contain the components used for learning; those are contained in learning_components attribute.

results

3d array – stores the output_values of the OUTPUT Mechanisms in the Composition for every TRIAL executed in a call to run. Each item in the outermost dimension (axis 0) of the array corresponds to a trial; each item within a trial corresponds to the output_values of an OUTPUT Mechanism.

simulation_results

3d array – stores the results for executions of the Composition when it is executed using its evaluate method.

retain_old_simulation_data

bool – if True, all Parameter values generated during simulations will be saved for later inspection; if False, simulation values will be deleted unless otherwise specified by individual Parameters

name

str – the name of the Composition; if it is not specified in the name argument of the constructor, a default is assigned by CompositionRegistry (see Naming for conventions used for default and duplicate names).

prefs

PreferenceSet or specification dict – the PreferenceSet for the Composition; if it is not specified in the prefs argument of the constructor, a default is assigned using classPreferences defined in __init__.py (see PreferenceSet for details).

add_backpropagation_learning_pathway(pathway, learning_rate=0.05, error_function=None, learning_update: <typecheck.framework.optional object at 0x12040ada0> = 'after')

Convenience method that calls add_linear_learning_pathway with **learning_function**=`Backpropagation`

Parameters:
Returns:

  • A dictionary of components that were automatically generated and added to the Composition in order to
  • implement Backpropagation along the pathway.
  • {LEARNING_MECHANISM (learning_mechanism,) – COMPARATOR_MECHANISM: comparator, TARGET_MECHANISM: target, LEARNED_PROJECTION: learned_projection}

add_controller(controller: psyneulink.core.components.mechanisms.modulatory.control.controlmechanism.ControlMechanism)

Add an OptimizationControlMechanism as the controller of the Composition, which gives the OCM access to the Composition’s evaluate method. This allows the OCM to use simulations to determine an optimal Control policy.

add_linear_learning_pathway(pathway, learning_function, learning_rate=0.05, error_function=(LinearCombination LinearCombination Function-7), learning_update: <typecheck.tc_predicates.any object at 0x12040a940> = 'online')

Implement learning pathway (including necessary learning components.

Generic method for implementing a learning pathway. Calls add_linear_processing_pathway to implement the processing components including, if necessary, the MappingProjections between Mechanisms. All of the MappingProjections (whether specified or created) are subject to learning (and are assigned as the learned_projection attribute of the LearningMechanisms created for the pathway.

If learning_function is a sublcass of LearningFunction, a class-specific learning method is called. Some may allow the error_function to be specified, in which case it must be compatible with the class of LearningFunction specified.

If learning_function an instantiated function, it is assigned to all of the LearningMechanisms created for the MappingProjections in the pathway. A ComparatorMechanism is created to compute the error for the pathway, and assigned the function specified in error_function, which must be compatible with learning_function.

See Learning in a Composition for for a more detailed description of how learning is implemented in a Composition, including the learning components <Composition_Learning_Components>` that are created, as well as other learning methods that can be used to implement specific algorithms.

Parameters:
  • pathway (List) – list containing either [Node1, Node2] or [Node1, MappingProjection, Node2]. If a projection is specified, that projection is the learned projection. Otherwise, a default MappingProjection is automatically generated for the learned projection.
  • learning_rate (float : default 0.05) – specifies the learning_rate used for the learning_function of the Learning Mechanism in the pathway.
  • error_function (function : default LinearCombination) –

    specifies the function assigned to Mechanism used to compute the error from the target and the output (value) of the TARGET Mechanism in the pathway.

    Note

    For most learning algorithms (and by default), a ComparatorMechanism is used to compute the error. However, some learning algorithms may use a different Mechanism (e.g., for TDlearning a PredictionErrorMechanism is used, which uses as its fuction PredictionErrorDeltaFunction.

  • learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameter of the learned_projection is updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanism in the pathway, and its LearningProjection (see learning_enabled for meaning of values).
Returns:

  • A dictionary of components that were automatically generated and added to the Composition in order to
  • implement ReinforcementLearning in the pathway.
  • {LEARNING_MECHANISM (learning_mechanism,) – COMPARATOR_MECHANISM: comparator, TARGET_MECHANISM: target, LEARNED_PROJECTION: learned_projection}

add_linear_processing_pathway(pathway, *args)

Add sequence of Mechanisms or Compositions possibly with intercolated Projections

A MappingProjection is created for each contiguous pair of Mechanisms and/or Compositions in the pathway argument, from the primary OutputState of the first one to the primary InputState of the second.

Tuples (Mechanism, NodeRoles) can be used to assign required_roles to Mechanisms.

Note that any specifications of a ControlMechanism’s monitor_for_control argument or the monitor argument specified in the constructor for an ObjectiveMechanism in the objective_mechanism argument supercede any MappingProjections that would otherwise be created for them when specified in the pathway argument.

add_node(node, required_roles=None, context=None)

Add a Composition Node (Mechanisms or Composition) to the Composition, if it is not already added

Parameters:
  • node (Mechanisms or Composition) – the node to be added to the Composition
  • required_roles (NodeRole or list of NodeRoles) – any NodeRoles roles that this node should have in addition to those determined by analyze graph.
add_nodes(nodes, required_roles=None)

Add a list of Composition Nodes (Mechanisms or Composition) to the Composition,

Parameters:
  • nodes (list) – the nodes to be added to the Composition. Each item of the list must be a Mechanisms, a Composition or a role-specification tuple with a Mechanism or Composition as the first item, and a NodeRole or list of those as the second item; any NodeRoles in a role-specification tuple are applied in addition to those specified in the required_roles argument.
  • required_roles (NodeRole or list of NodeRoles) – NodeRoles to assign to the nodes in addition to those determined by analyze graph; these apply to any items in the list of nodes that are not in a tuple; these apply to any specified in any role-specification tuples in the nodes argument.
add_pathway(path)

Adds an existing Pathway to the current Composition

Parameters:path (the Pathway (Composition) to be added) –
add_projection(projection=None, sender=None, receiver=None, feedback=False, learning_projection=False, name=None, allow_duplicates=False)

Add projection to the Composition, if one with the same sender and receiver doesn’t already exist.

If projection is not specified, create a default MappingProjection using sender and receiver.

If projection is specified:

  • if projection has already been instantiated, and sender and receiver are also specified, they must match the sender and receiver of projection.

  • if sender and receiver are specified and one or more Projections already exists between them: - if it is in the Composition:

    • if there is only one, the request is ignored and the existing Projection is returned
    • if there is more than one, an exception is raised as this should never be the case
    • it is NOT in the Composition: - if there is only one, that Projection is used; - if there is more than one, the last in the list (presumably the most recent) is used; in either case, processing continues, to activate it for the Compostion, construct any “shadow” projections that may be specified, and assign feedback if specified,
  • if the status of projection is deferred_init:

    • if its sender and/or receiver attributes are not specified, then sender and/or receiver are used.
    • if sender and/or receiver attributes are specified, they must match sender and/or receiver if those have also been specified.
    • if a Projection between the specified sender and receiver does not already exist, it is initialized; if it does already exist, the request to add it is ignored, however requests to shadow it and/or mark it as a`feedback` Projection are implemented (in case it has not already been done for the existing Projection).

Note

If projection is an instantiated Projection (i.e., not in deferred_init) and one already exists between its sender and receiver a warning is generated.

Parameters:
  • sender (Mechanism, Composition, or OutputState) – the sender of projection
  • projection (Projection, matrix) – the projection to add
  • receiver (Mechanism, Composition, or InputState) – the receiver of projection
  • feedback (bool) – When False (default) all Nodes within a cycle containing this Projection execute in parallel. This means that each Projections within the cycle actually passes to its receiver the value of its sender from the previous execution. When True, this Projection “breaks” the cycle, such that all Nodes execute in sequence, and only the Projection marked as ‘feedback’ passes to its receiver the value of its sender from the previous execution.
Returns:

Return type:

projection if added, else None

add_projections(projections=None)

Calls add_projection for each Projection in the projections list. Each Projection must have its sender and receiver already specified. If an item in the list is a list of projections, called recursively on that list.

Parameters:projections (list of Projections) – list of Projections to be added to the Composition
add_reinforcement_learning_pathway(pathway, learning_rate=0.05, error_function=None, learning_update: <typecheck.tc_predicates.any object at 0x12040a9e8> = 'online')

Convenience method that calls add_linear_learning_pathway with **learning_function**=`Reinforcement`

Parameters:
  • pathway (List) – list containing either [Node1, Node2] or [Node1, MappingProjection, Node2]. If a projection is specified, that projection is the learned projection. Otherwise, a default MappingProjection is automatically generated for the learned projection.
  • learning_rate (float : default 0.05) – specifies the learning_rate used for the ReinforcementLearning function of the Learning Mechanism in the pathway.
  • error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (value) of the TARGET Mechanism in the pathway).
  • learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameter of the learned_projection is updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanism in the pathway, and its LearningProjection (see learning_enabled for meaning of values).
Returns:

  • A dictionary of components that were automatically generated and added to the Composition in order to
  • implement ReinforcementLearning in the pathway.
  • {LEARNING_MECHANISM (learning_mechanism,) – COMPARATOR_MECHANISM: comparator, TARGET_MECHANISM: target, LEARNED_PROJECTION: learned_projection}

add_td_learning_pathway(pathway, learning_rate=0.05, error_function=None, learning_update: <typecheck.tc_predicates.any object at 0x12040aba8> = 'online')

Convenience method that calls add_linear_learning_pathway with **learning_function**=`TDLearning`

Parameters:
  • pathway (List) – list containing either [Node1, Node2] or [Node1, MappingProjection, Node2]. If a projection is specified, that projection is the learned projection. Otherwise, a default MappingProjection is automatically generated for the learned projection.
  • learning_rate (float : default 0.05) – specifies the learning_rate used for the TDLearning function of the Learning Mechanism in the pathway.
  • error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (value) of the TARGET Mechanism in the pathway).
  • learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameter of the learned_projection is updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanism in the pathway, and its LearningProjection (see learning_enabled for meaning of values).
Returns:

  • A dictionary of components that were automatically generated and added to the Composition in order to
  • implement TDLearning in the pathway.
  • {LEARNING_MECHANISM (learning_mechanism,) – COMPARATOR_MECHANISM: comparator, TARGET_MECHANISM: target, LEARNED_PROJECTION: learned_projection}

default_external_input_values

Returns the default values of all external InputStates that belong to the Input CompositionInterfaceMechanism

disable_all_history()

When run, disables history tracking for all Parameters of all Components used in this Composition

evaluate(predicted_input=None, control_allocation=None, num_simulation_trials=None, runtime_params=None, base_context=<psyneulink.core.globals.context.Context object>, context=None, execution_mode=False, return_results=False)

Runs a simulation of the Composition, with the specified control_allocation, excluding its controller in order to return the net_outcome of the Composition, according to its controller under that control_allocation. All values are reset to pre-simulation values at the end of the simulation.

execute(inputs=None, autodiff_stimuli=None, scheduler=None, termination_processing=None, call_before_time_step=None, call_before_pass=None, call_after_time_step=None, call_after_pass=None, context=None, base_context=<psyneulink.core.globals.context.Context object>, clamp_input='soft_clamp', runtime_params=None, skip_initialization=False, bin_execute=False)

Passes inputs to any Nodes receiving inputs directly from the user (via the “inputs” argument) then coordinates with the Scheduler to execute sets of nodes that are eligible to execute until termination conditions are met.

Parameters:
  • inputs ({ Mechanism or Composition : list }) – a dictionary containing a key-value pair for each node in the composition that receives inputs from the user. For each pair, the key is the node (Mechanism or Composition) and the value is an input, the shape of which must match the node’s default variable.
  • scheduler (Scheduler) – the scheduler object that owns the conditions that will instruct the execution of this Composition If not specified, the Composition will use its automatically generated scheduler.
  • context – context will be set to self.default_execution_id if unspecified
  • base_context – the context corresponding to the execution context from which this execution will be initialized, if values currently do not exist for context
  • call_before_time_step (callable) – called before each TIME_STEP is executed passed the current context (but it is not necessary for your callable to take)
  • call_after_time_step (callable) – called after each TIME_STEP is executed passed the current context (but it is not necessary for your callable to take)
  • call_before_pass (callable) – called before each PASS is executed passed the current context (but it is not necessary for your callable to take)
  • call_after_pass (callable) – called after each PASS is executed passed the current context (but it is not necessary for your callable to take)
Returns:

output value of the final Mechanism executed in the Composition

Return type:

various

external_input_states

Returns all external InputStates that belong to the Input CompositionInterfaceMechanism

external_input_values

Returns values of all external InputStates that belong to the Input CompositionInterfaceMechanism

get_nodes_by_role(role)

Returns a List of Composition Nodes in this Composition that have the role specified

Parameters:role (NodeRole) – the List of nodes having this role to return
Returns:
graph_processing

The Composition’s processing graph (contains only Mechanisms.

Getter:Returns the processing graph, and builds the graph if it needs updating since the last access.
input_state

Returns the index 0 InputState that belongs to the Input CompositionInterfaceMechanism

input_states

Returns all InputStates that belong to the Input CompositionInterfaceMechanism

input_values

Returns values of all InputStates that belong to the Input CompositionInterfaceMechanism

output_state

Returns the index 0 OutputState that belongs to the Output CompositionInterfaceMechanism

output_states

Returns all OutputStates that belong to the Output CompositionInterfaceMechanism

output_values

Returns values of all OutputStates that belong to the Output CompositionInterfaceMechanism

run(inputs=None, scheduler=None, termination_processing=None, num_trials=None, call_before_time_step=None, call_after_time_step=None, call_before_pass=None, call_after_pass=None, call_before_trial=None, call_after_trial=None, clamp_input='soft_clamp', bin_execute=False, log=False, initial_values=None, reinitialize_values=None, runtime_params=None, skip_initialization=False, animate=False, context=None, base_context=<psyneulink.core.globals.context.Context object>)

Pass inputs to Composition, then execute sets of nodes that are eligible to run until termination conditions are met. See Run for details of formatting input specifications. See Run for details of formatting input specifications. Use animate to generate a gif of the execution sequence.

inputs: { Mechanism : list } or { Composition : list }
a dictionary containing a key-value pair for each Node in the composition that receives inputs from the user. For each pair, the key is the Node and the value is a list of inputs. Each input in the list corresponds to a certain TRIAL.
scheduler : Scheduler
the scheduler object that owns the conditions that will instruct the execution of the Composition. If not specified, the Composition will use its automatically generated scheduler.
context
context will be set to self.default_execution_id if unspecified
base_context
the context corresponding to the execution context from which this execution will be initialized, if values currently do not exist for context
num_trials : int
typically, the composition will infer the number of trials from the length of its input specification. To reuse the same inputs across many trials, you may specify an input dictionary with lists of length 1, or use default inputs, and select a number of trials with num_trials.
call_before_time_step : callable
will be called before each TIME_STEP is executed.
call_after_time_step : callable
will be called after each TIME_STEP is executed.
call_before_pass : callable
will be called before each PASS is executed.
call_after_pass : callable
will be called after each PASS is executed.
call_before_trial : callable
will be called before each TRIAL is executed.
call_after_trial : callable
will be called after each TRIAL is executed.
initial_values : Dict[Node: Node Value]
sets the values of nodes before the start of the run. This is useful in cases where a node’s value is used before that node executes for the first time (usually due to recurrence or control).
runtime_params : Dict[Node: Dict[Parameter: Tuple(Value, Condition)]]

nested dictionary of (value, Condition) tuples for parameters of Nodes (Mechanisms or Compositions of the Composition; specifies alternate parameter values to be used only during this Run when the specified Condition is met.

Outer dictionary:
  • key - Node
  • value - Runtime Parameter Specification Dictionary
Runtime Parameter Specification Dictionary:
  • key - keyword corresponding to a parameter of the Node
  • value - tuple in which the index 0 item is the runtime parameter value, and the index 1 item is a Condition

See Runtime Parameters for more details and examples of valid dictionaries.

animate : dict or bool : False

specifies use of the show_graph method to generate a gif movie showing the sequence of Components executed in a run. A dict can be specified containing options to pass to the show_graph method; each key must be a legal argument for the show_graph method, and its value a specification for that argument. The entries listed below can also be included in the dict to specify parameters of the animation. If the animate argument is specified simply as True, defaults are used for all arguments of show_graph and the options below:

  • UNIT: EXECUTION_SET or COMPONENT (default=EXECUTION_SET) – specifies which Components to treat as active in each call to show_graph. COMPONENT generates an image for the execution of each Component. EXECUTION_SET generates an image for each execution_set, showing all of the Components in that set as active.
  • DURATION: float (default=0.75) – specifies the duration (in seconds) of each image in the movie.
  • NUM_RUNS: int (default=1) – specifies the number of runs to animate; by default, this is 1. If the number specified is less than the total number of runs executed, only the number specified are animated; if it is greater than the number of runs being executed, only the number being run are animated.
  • NUM_TRIALS: int (default=1) – specifies the number of trials to animate; by default, this is 1. If the number specified is less than the total number of trials being run, only the number specified are animated; if it is greater than the number of trials being run, only the number being run are animated.
  • MOVIE_DIR: str (default=project root dir) – specifies the directdory to be used for the movie file; by default a subdirectory of <root_dir>/show_graph_OUTPUT/GIFS is created using the name of the Composition, and the gif files are stored there.
  • MOVIE_NAME: str (default=name + ‘movie’) – specifies the name to be used for the movie file; it is automatically appended with ‘.gif’.
  • SAVE_IMAGES: bool (default=False) – specifies whether to save each of the images used to construct the animation in separate gif files, in addition to the file containing the animation.
  • SHOW: bool (default=False) – specifies whether to show the animation after it is constructed, using the OS’s default viewer.
log : bool, LogCondition

Sets the log_condition for every primary node and projection in this Composition, if it is not already set.

Note

as when setting the log_condition directly, a value of True will correspond to the EXECUTION LogCondition.

Returns:output value of the final Node executed in the composition
Return type:various
scheduler

A default Scheduler automatically generated by the Composition, used for the (processing phase of execution.

Getter:Returns the default scheduler, and builds it if it needs updating since the last access.
show_graph(show_node_structure=False, show_nested=True, show_controller=False, show_cim=False, show_learning=False, show_headers=True, show_dimensions=False, show_projection_labels=False, direction='BT', active_items=None, active_color=BOLD, input_color='green', output_color='red', input_and_output_color='brown', controller_color='blue', composition_color='pink', feedback_shape = 'septagon', cim_shape='square', output_fmt='pdf', context=None)

Show graphical display of Components in a Composition’s graph.

Note

This method relies on graphviz, which must be installed and imported (standard with PsyNeuLink pip install)

See Visualizing a Composition for details and examples.

Parameters:
  • show_node_structure (bool, VALUES, LABELS, FUNCTIONS, MECH_FUNCTION_PARAMS, STATE_FUNCTION_PARAMS, ROLES, or ALL : default False) –

    show a detailed representation of each Mechanisms in the graph, including its States; can have any of the following settings alone or in a list:

    • True – show States of Mechanism, but not information about the value or function of the Mechanism or its States.
    • VALUES – show the value of the Mechanism and the value of each of its States.
    • LABELS – show the value of the Mechanism and the value of each of its States, using any labels for the values of InputStates and OutputStates specified in the Mechanism’s input_labels_dict and output_labels_dict, respectively.
    • FUNCTIONS – show the function of the Mechanism and the function of its InputStates and OutputStates.
    • MECH_FUNCTION_PARAMS_ – show the parameters of the function for each Mechanism in the Composition (only applies if FUNCTIONS is True).
    • STATE_FUNCTION_PARAMS_ – show the parameters of the function for each State of each Mechanism in the Composition (only applies if FUNCTIONS is True).
    • ROLES – show the role of the Mechanism in the Composition (but not any of the other information; use ALL to show ROLES with other information).
    • ALL – shows the role, function, and value of the Mechanisms in the Composition and their States (using labels for the values, if specified – see above), including parameters for all functions.
  • show_nested (bool | dict : default ALL) – specifies whether any nested Composition(s) are shown in details as inset graphs. A dict can be used to specify any of the arguments allowed for show_graph to be used for the nested Composition(s); ALL passes all arguments specified for the main Composition to the nested one(s); True uses the default values of show_graph args for the nested Composition(s).
  • show_controller (bool : default False) – specifies whether or not to show the Composition’s controller and associated ObjectiveMechanism; these are displayed in the color specified for controller_color.
  • show_cim (bool : default False) – specifies whether or not to show the Composition’s input and out CompositionInterfaceMechanisms (CIMs)
  • show_learning (bool or ALL : default False) – specifies whether or not to show the learning components of the Compositoin; they will all be displayed in the color specified for learning_color. Projections that receive a LearningProjection will be shown as a diamond-shaped node. If set to ALL, all Projections associated with learning will be shown: the LearningProjections as well as from ProcessingMechanisms to LearningMechanisms that convey error and activation information; if set to True, only the LearningPojections are shown.
  • show_projection_labels (bool : default False) – specifies whether or not to show names of projections.
  • show_headers (bool : default True) – specifies whether or not to show headers in the subfields of a Mechanism’s node; only takes effect if show_node_structure is specified (see above).
  • show_dimensions (bool : default False) –

    specifies whether or not to show dimensions for the variable and value of each Component in the graph (and/or MappingProjections when show_learning is True); can have the following settings:

    • MECHANISMS – shows Mechanisms input and output dimensions. Input dimensions are shown in parentheses below the name of the Mechanism; each number represents the dimension of the variable for each InputState of the Mechanism; Output dimensions are shown above the name of the Mechanism; each number represents the dimension for value of each of OutputState of the Mechanism.
    • PROJECTIONS – shows MappingProjection matrix dimensions. Each is shown in (<dim>x<dim>…) format; for standard 2x2 “weight” matrix, the first entry is the number of rows (input dimension) and the second the number of columns (output dimension).
    • ALL – eqivalent to True; shows dimensions for both Mechanisms and Projections (see above for formats).
  • direction (keyword : default 'BT') – ‘BT’: bottom to top; ‘TB’: top to bottom; ‘LR’: left to right; and ‘RL`: right to left.
  • active_items (List[Component] : default None) – specifies one or more items in the graph to display in the color specified by active_color*.
  • active_color (keyword : default 'yellow') – specifies how to highlight the item(s) specified in active_items*: either a color recognized by GraphViz, or the keyword BOLD.
  • input_color (keyword : default 'green',) – specifies the display color for INPUT Nodes in the Composition
  • output_color (keyword : default 'red',) – specifies the display color for OUTPUT Nodes in the Composition
  • input_and_output_color (keyword : default 'brown') – specifies the display color of nodes that are both an INPUT and an OUTPUT Node in the Composition
  • controller_color (keyword : default 'blue') – specifies the color in which the controller components are displayed
  • learning_color (keyword : default 'orange') – specifies the color in which the learning components are displayed
  • composition_color (keyword : default 'brown') – specifies the display color of nodes that represent nested Compositions.
  • feedback_shape (keyword : default 'septagon') – specifies the display shape of nodes that are assigned the NodeRole FEEDBACK_SENDER.
  • cim_shape (default 'square') – specifies the display color input_CIM and output_CIM nodes
  • output_fmt (keyword : default 'pdf') – ‘pdf’: generate and open a pdf with the visualization; ‘jupyter’: return the object (for working in jupyter/ipython notebooks); ‘gv’: return graphviz object ‘gif’: return gif used for animation
Returns:

display of Composition – PDF: (placed in current directory) if output_fmt arg is ‘pdf’; Graphviz graph object if output_fmt arg is ‘gv’ or ‘jupyter’; gif if output_fmt arg is ‘gif’.

Return type:

pdf or Graphviz graph object

stateful_nodes

List of all nodes in the system that are currently marked as stateful. For Mechanisms, statefulness is determined by checking whether node.has_initializers is True. For Compositions, statefulness is determined by checking whether any of its nodes are stateful.

Returns:all stateful nodes in the system
Return type:List[Nodes]