• Github
Table of Contents
0.13.0.0
  • Welcome to PsyNeuLink
  • Basics and Primer
  • Quick Reference
  • Core
  • Library
  • Contributors Guide
  • Docs >
  • Composition
Shortcuts

Composition¶

Subclasses

  • AutodiffComposition
  • CompositionFunctionApproximator
  • ParameterEstimationComposition

Related

  • NodeRoles

  • Pathway
  • CompositionInterfaceMechanism
  • OptimizationControlMechanism
  • Scheduling
  • Visualization
  • Reporting

Contents¶

  • Overview

  • Creating a Composition
    • Using the Constructor

    • Adding Components and Pathways
      • Adding Components

      • Adding Pathways

    • Adding Nested Compositions

  • Composition Structure
    • Graph

    • Nodes

    • Nested Compositions
      • Probes

    • CompositionInterfaceMechanisms

    • Projections

    • Pathways

  • Controlling a Composition
    • Assigning a Controller

    • Controller Execution

  • Learning in a Composition
    • Learning Using PsyNeuLink Components
      • Unsupervised Learning

      • Supervised Learning
        • Supervised Learning Methods

        • Supervised Learning Components

        • Execution of Learning

    • Learning Using AutodiffCompositon

    • Learning Using UserDefinedFunctions

  • Executing a Composition
    • Execution Methods

    • Composition Inputs
      • Input formats (including targets for learning)
        • Input Dictionary

        • Specifying Inputs Programmatically

    • Execution Factors
      • Runtime Parameters

      • Cycles and Feedback
        • Cycles and Synchronous Execution

        • Feedback and Sequential Execution

      • Execution Contexts

      • Timing

      • Resetting Stateful Parameters

      • Compilation

    • Results, Reporting and Logging

  • Visualizing a Composition

  • Composition Examples
    • Creating a Composition

    • Run Composition

    • Learning

    • Input Formats

    • Runtime Parameters

    • Cycles and Feedback

    • Execution Contexts

    • Reset Paramters of Stateful Functions

    • Examples

  • Class Reference

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 pairs of 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¶

  • Using the Constructor

  • Adding Components and Pathways

  • Adding Nested Compositions

A Composition can be created by calling the constructor and specifying Components to be added, using either arguments of the constructor and/or methods that allow Components to be added once it has been constructed.

Hint

Although Components (Nodes and Projections) can be added individually to a Composition, it is often easier to use Pathways to construct a Composition, which in many cases can automaticially construct the Projections needed without having to specify those explicitly.

Using the Constructor¶

The following arguments of the Composition’s constructor can be used to add Compnents when it is constructed:

  • pathways

    adds one or more Pathways to the Composition; this is equivalent to constructing the Composition and then calling its add_pathways method, and can use the same forms of specification as the pathways argument of that method (see Pathway Specification for additonal details). If any learning Pathways are included, then the constructor’s disable_learning argument can be used to disable learning on those by default (though it will still allow learning to occur on any other Compositions, either nested within the current one, or within which the current one is nested (see Learning in a Composition for a full description).

  • nodes

    adds the specified Nodes to the Composition; this is equivalent to constructing the Composition and then calling its add_nodes method, and takes the same values as the nodes argument of that method (note that this does not construct Pathways for the specified nodes; the pathways arg or add_pathways method must be used to do so).

  • projections

    adds the specified Projections to the Composition; this is equivalent to constructing the Composition and then calling its add_projections method, and takes the same values as the projections argument of that method. In general, this is not neded – default Projections are created for Pathways and/or Nodes added to the Composition using the methods described above; however it can be useful for custom configurations, including the implementation of specific Projection `matrices

    <MappingProjection.matrix>`.

  • controller

    adds the specified ControlMechanism (typically an OptimizationControlMechanism) as the controller of the Composition, that can be used to simulate and optimize performance of the Composition. If this is specified, then the enable_controller, controller_mode, controller_condition and retain_old_simulation_data can be used to configure the controller’s operation (see Controlling a Composition for full description).

Adding Components and Pathways¶

  • Adding Components

  • Adding Pathways

The methods used for adding individual Components and Pathways to a Composition are described briefly below. Examples of their their use are provided in Creating a Composition.

The following methods can be used to add individual Components to an existing Composition:

  • add_node

    adds a Node to the Composition.

  • add_nodes

    adds mutiple Nodes to the Composition.

  • add_projection

    adds a Projection between a pair of Nodes in the Composition.

  • add_projections

    adds Projections between multiple pairs of Nodes in the Composition.

These methods can be used to add Pathways to an existing Composition:

  • add_pathways

    adds one or more Pathways to the Composition; this a convenience method, that determines the type of each Pathway, and calls the relevant ones of the following methods for each Pathway.

  • add_linear_processing_pathway

    adds and a list of Nodes and Projections to the Composition, inserting a default Projection between any adjacent set(s) of Nodes for which a Projection is not otherwise specified (see method documentation and Pathway Specification for additonal details); returns the Pathway added to the Composition.

  • add_linear_learning_pathway

    adds a list of Nodes and Projections to implement a learning pathway, including the learning components needed to implement the algorithm specified in its learning_function argument; returns the learning Pathway added to the Composition.

  • add_reinforcement_learning_pathway

    adds a list of Nodes and Projections, including the learning components needed to implement reinforcement learning in the specified pathway; returns the learning Pathway added to the Composition.

  • add_td_learning_pathway

    adds a list of Nodes and Projections, including the learning components needed to implement temporal differences method of reinforcement learning` in the specified pathway; returns the learning Pathway added to the Composition.

  • add_backpropagation_learning_pathway

    adds a list of Nodes and Projections, including the learning components needed to implement the backpropagation learning algorithm in the specified pathway; returns the learning Pathway added to the Composition.

Note

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

A Node can be removed from a Composition using the remove_node method.

Adding Nested Compositions¶

A Composition can be used as a Node of another Composition, either in the nodes argument of its consructor, in a Pathway specified in its pathways argument, or in one of the Composition’s addition methods. Projections can be specifed to and from the nested composition (or created automatically if specified in a Pathway) just as for any other Node.

Composition Structure¶

  • Graph

  • Nodes

  • Nested Compositions

  • Pathways

This section provides an overview of the structure of a Composition and its Components. Later sections describe these in greater detail, and how they are used to implement various forms of Composition.

Graph¶

The structure of a Composition is a computational graph, the Nodes of which are Mechanisms and/or nested Composition(s) that carry out computations; and the edges of which can be thought of as Composition’s Projections, that transmit the computational results from one Node to another Node (though see below for a fuller description). The information about a Composition’s structure is stored in its graph attribute, that is a Graph object describing its Nodes and the dependencies determined by its Projections. There are no restrictions on the structure of the graph, which can be acyclic or cyclic, and/or hierarchical (i.e., contain one or more nested Compositions) as described below. A Composition’s graph can be displayed using the Composition’s show_graph method (see Use of the show_graph Method).

Acyclic and Cyclic Graphs¶

Projections are always directed (that is, information is transimtted in only one direction). Therefore, if the Projections among the Nodes of the Composition never form a loop, then it is a directed acyclic graph (DAG), and the order in which its Nodes are executed can be determined by the structure of the graph itself. However if the Composition contains loops, then its structure is a cyclic graph, and how the Nodes in the loop are initialized and the order in which they execute must be determined in order to execute the graph. PsyNeuLink has procedures both for automatically detecting handling such cycles, and also for allowing the user to specify how this is done (see Cycles and Feedback).

Nodes¶

Every Node in a Composition’s graph must be either a Mechanism or a nested Composition. The Nodes of a Composition’s graph are listed in its nodes attribute. Each Node is assigned one or more NodeRoles that designate its status in the graph. Nodes are assigned one or more NodeRoles automatically when a Composition is constructed, and when Nodes or Pathways are added to it or new Projections are assigned to it. However, some of these can be explicitly assigned by specifying the desired NodeRole in any of the following places:

  • the required_roles argument of the Composition’s add_node or add_nodes methods;

  • a tuple specifying the Node in the pathways argument of the Composition’s constructor, a Pathway's constructor, or in one of the methods used to add a Pathway to the Composition (see Creating a Composition); the Node must be the first item of the tuple, and the NodeRole its 2nd item.

  • the roles argument of the require_node_roles called for an existing Node.

For example, by default, the ORIGIN Nodes of a Composition are assigned as its INPUT nodes (that is, ones that receive the external input when it is run), and similarly its TERMINAL Nodes are assigned as its OUTPUT Nodes (the values of which are reported as the results of running the Composition). However, any other Nodes can be specified as the INPUT or OUTPUT Nodes using the methods above, in addition to those assigned by default. It is also possible to exclude some roles from being assigned by default, using the exclude_node_roles method. The description of each NodeRole indicates whether it is modifiable using these methods. All of the roles assigned to a particular Node can be listed using the get_roles_by_node method, and all of the nodes assigned a particular role can be listed using the get_nodes_by_role method.

Nested Compositions¶

A nested Composition is one that is a Node within another Composition. When the outer Composition is executed, the nested Composition is executed when its Node in the outer is called to execute by the outer Composition’s scheduler. Any depth of nesting of Compositions withinothers is allowed.

Projections to Nodes in a nested Composition. Any Node within an outer Composition can send a Projection to any INPUT Node of any Composition that is enclosed within it (i.e., at any level of nesting). In addition, a ControlMechanism within an outer Composition can modulate the parameter (i.e., send a ControlProjection to the ParameterPort) of any Mechanism in a Composition nested within it, not just its INPUT Nodes.

Projections from Nodes in a nested Composition. The nodes of an outer Composition can also receive Projections from Nodes within a nested Composition. This is true for any OUTPUT of the nested Composition, and it is also true for any of its other Nodes if allow_probes is True (the default); if it is CONTROL, then only the controller of a Composition can receive Projections from Nodes in a nested Composition that are not OUTPUT Nodes.

  • Probes – Nodes that are not OUTPUT of a nested Composition, but project to ones in an outer Composition, are assigned PROBE in addition to their other roles in the nested Composition. The only difference between PROBE and OUTPUT Nodes is whether their output is included in the output_values and results attributes of the outermost Composition to which they project; this is determined by the include_probes_in_output attribute of the latter. If include_probes_in_output is False (the default), then the output of any PROBE Nodes are not included in the output_values or results for the outermost Composition to which they project (although they are still included in those attributes of the nested Compositions; see note below). In this respect, they can be thought of as “probing” - that is, providing access to “latent variables” of – the nested Composition to which they belong – the values of which that are not otherwise reported as part of the outermost Composition’s output or results. If include_probes_in_output is True, then any PROBE Nodes of any nested Compositions are treated the same as OUTPUT Nodes: their outputs are included in the output_values and results of the outermost Composition. PROBE Nodes can be visualized, along with any Projections treated differently from those of OUTPUT Nodes (i.e., when include_probes_in_output is False), using the Composition’s show_graph method, which displays them in their own color (pink by default).

    Hint

    PROBE Nodes are useful for model-based optimization using an, in which the value of one or more Nodes in a nested Composition may need to be monitored without being considered as

    part of the output or results of the Composition being optimized.

    Note

    The specification of include_probes_in_output only applies to a Composition that is not nested in another. At present, specification of the attribute for nested Compositions is not supported: the include_probes_in_output argument in the constructor for nested Compositions is ignored, and the attribute is automatically set to True.

    This is because Compositions require access to the values of all of the output_CIM of any Compositions nested within them (see below).

Inputs for nested Compositions. If a nested Composition is an INPUT Node of all of the Compositions within which it is nested, including the outermost one, then when the latter is executed, the inputs specified to its execution method must include the InputPorts of the nested Composition. These can be accessed using the Composition’s external_input_ports_of_all_input_nodes attribute.

Results from nested Compositions. If a nested Composition is an OUTPUT Node of all of the Compositions within which it is nested, including the outermost one, then when the latter is executed, both the output_values and results of the nested Composition are also included in those attributes of any intervening and the outermost Composition. If allow_probes is set (which it is by default), then the Composition’s include_probes_in_output attribute determines whether their values are also included in the output_values and results of the outermost Composition (see above).

Learning in nested Compositions. A nested Composition can also contain one or more learning Pathways, however a learning Pathway may not extend from an enclosing Composition to one nested within it or vice versa. The learning Pathways within a nested Composition are executed when that Composition is run, just like any other (see Execution of Learning).

CompositionInterfaceMechanisms¶

Every Composition has three CompositionInterfaceMechanisms, described below, that act as interfaces between it and the environment, or other Components if it is nested within another Composition. The CompositionInterfaceMechanisms of a Composition are created and assigned to it automatically when the Composition is constructed, and executed automatically when it executes (they should never be constructed or executed on their own).

  • input_CIM - this is assigned an InputPort and OutputPort for every INPUT Node of the Composition to which it belongs. The InputPorts receive input from either the environment or a Composition within which it is nested. If the Composition is itself an INPUT Node of an enclosing Composition, then its input must be included in the inputs to that Composition when it is executed. Every InputPort of an input_CIM is associated with an OutputPort that projects to a corresponding INPUT Node of the Composition.

  • parameter_CIM - this is assigned an InputPort and OutputPort for every Parameter of every Node of the Composition that is modulated by a ModulatoryMechanism (usually a ControlMechanism) outside of the Composition (i.e., from an enclosing Composition within which it is nested). The InputPort receives a Projection from a ModulatorySignal on the ModulatoryMechanism, and the paired OutputPort of the parameter_CIM conveys this via ModulatoryProjection to the ParameterPort for the Paremeter of the Mechanism to be modulated.

    The Projection from a ModulatoryMechanism to the InputPort of a parameter_CIM is the only instance in which a MappingProjection is used as an efferent projection of a ModulatoryMechanism.

  • output_CIM - this is assigned an InputPort and OutputPort for every OUTPUT Node of the Composition to which it belongs. Each InputPort receives input from an OUTPUT Node of the Composition, and its value is assigned as the value of a corresponding OutputPort. The latter are assigned to the output_values and results attributes of the Composition. If the Composition is nested within another, then the output_CIM’s output_ports send Projections to Components of the Composition within which it is nested. If it is an OUTPUT Node of the enclosing Composition, then its OutputPorts project the output_CIM of the enclosing Composition, its output_values are included in those of the enclosing Composition. If the Composition has an PROBE Nodes, then they too project to the Composition’s output_CIM. If the Composition is nested in another, then the values of the PROBE Nodes are also included in the Composition’s output_values; if it is an outer Composition (i.e. not nested in any other), then the Compositions’ include_probes_in_output attribute determines whether their values are included in its output_values and results attributes (see Probes for additional details).

Projections¶

Projections can be thought of as directed edges of the Composition’s graph, insofar as they are always from one Node to a single other Node, and serve to convey the results of the sender’s computation as input to the receiver. However, they are not edges in the strictest senese, for two reasons: First, they too can carry out (restricted) computations, such as matrix transformation by a MappingProjection. Second, they can be the receiver of a Projection, as in the case of a MappingProjection that receives a LearningProjection used to modify its matrix parameter. Nevertheless, since they define the connections and therefore dependencies among the Composition’s Nodes, they determine the structure of its graph. Subsets of Nodes connected by Projections can be defined as a Pathway as decribed under Pathways below).

Because Projections are not strictly edges, they are assigned to vertices in the Composition’s graph, along with its Nodes. The actual edges are implicit in the dependencies determined by the Projections, and listed in the graph’s dependency_dict.

Although individual Projections are directed, pairs of Nodes can be connected with Projections in each direction (forming a local cycle), and the AutoAssociativeProjection class of Projection can even connect a Node with itself. Projections can also connect the Node(s) of a Composition to one(s) nested within it. In general, these are to the INPUT Nodes and from the OUTPUT Nodes of a nested Composition, but if the Composition’s allow_probes attribute is not False, then Projections can be received from any Nodes within a nested Composition (see Probes for additional details). A ControlMechanism can also control (i.e., send a ControlProjection) to any Node within a nested Composition.

Projections can be specified between Mechanisms before they are added to a Composition. If both Mechanisms are later added to the same Composition, and the Projection between them is legal for the Composition, then the Projection between them is added to it and is used during its execution. However, if the Projection is not legal for the Composition (e.g., the Mechanisms are not assigned as INTERNAL Nodes of two different nested Compositions), the Projection will still be associated with the two Mechanisms (i.e., listed in their afferents and efferents attributes, respectively), but it is not added to the Composition and not used during its execution.

Hint

Projections that are associated with the Nodes of a Composition but are not in the Composition itself (and, accordingly, not listed it is projections attribute) can still be visualized using the Composition’s show_graph method, by specifying its show_projections_not_in_composition argument as True; Projections not in the Composition appear in red.

Although Projections can be specified to and from Nodes within a nested Composition, these are actually implemented as Projections to or from the nested Composition’s input_CIM, parameter_CIM or output_CIM, respectively; those, in turn, send or receive Projections to or from the specified Nodes within the nested Composition. PROBE Nodes of a nested Composition, like OUTPUT Nodes, project to the Node of an enclosing Composition via the nested Composition’s output_CIM, and those of any intervening Compositions if it is nested more than one level deep. The outputs of PROBE Nodes are included in the output_values and results of such intervening Compositions (since those values are derived from the output_ports of the Composition’s output_CIM. Specifying include_probes_in_output has no effect on this behavior for intervening Compositions; it only applies to the outermost Composition to which a PROBE Node projects (see Probes for additional details).

Pathways¶

A Pathway is an alternating sequence of Nodes and Projections in a Composition. Although a Composition is not required to have any Pathways, these are useful for constructing Compositions, and are required for implementing learning in a Composition. Pathways can be specified in the pathways argument of the Composition’s constructor, or using one of its Pathway addition methods. Pathways must be linear (that is, the cannot have branches), but they can be continguous, overlapping, intersecting, or disjoint, and can have one degree of converging and/or diverging branches (meaning that their branches can’t branch). Each Pathway has a name (that can be assigned when it is constructed) and a set of attributes, including a pathway attribute that lists the Nodes and Projections in the Pathway, a roles attribute that lists the PathwayRoles assigned to it (based on the NodeRoles assigned to its Nodes), and attributes for particular types of nodes (e.g., INPUT and OUTPUT) if the Pathway includes nodes assigned the corresponding NodeRoles. If a Pathway does not have a particular type of Node, then its attribute returns None. There are two types of Pathways: processing Pathways and learning Pathways. Processing Pathways are ones not configured for learning; learning Pathways are described under Learning in a Composition. All of the Pathways in a Composition are listed in its pathways attribute.

Controlling a Composition¶

  • Assigning a Controller

  • Controller Execution

A Composition can be assigned a controller. This must be an OptimizationControlMechanism, 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 is generally done automatically when the controller is is assigned. If enabled, the controller is executed either before or after all of the other Components in the Composition have been executed at a given TimeScale, and if its specified Condition has been met, as determined by the Composition’s controller_mode, controller_time_scale and controller_condition attributes. By default, a controller is enabled, and executes after the rest of the Composition (controller_mode= AFTER) at the end of every trial (controller_time_scale= TimeScale.TRIAL and controller_condition = Always()). However, controller_mode can be used to specify execution of the controller before the Composition; controller_time_scale can be used to specify execution at a particular TimeScale (that is at the beginning or end of every TIME_STEP, PASS); and controller_condition can be used to specify a particular Condition that must be satisified for the controller to execute. Arguments for all three of these attributes can be specified in the Composition’s constructor, or programmatically after it is constructed by assigning the desired value to the corresponding 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 the MappingProjections within a learning Pathway, which implements the conection weights (i.e., strengths of associations between representations in the Mechanisms) within a Pathway. If learning is implemented for a Composition, it can be executed calling the Composition’s learn method (see Execution of Learning and Executing a Composition for additional details).

Configuring Learning in a Composition¶

There are three ways of configuring learning in a Composition:

  1. using standard PsyNeuLink Components

  2. using the AutodiffComposition – a specialized subclass of Composition that executes learning using PyTorch

  3. 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 PsyNeuLink Components¶

  • Unsupervised Learning

  • Supervised Learning

When learning is implemented using standard PsyNeuLink Components, each calculation and/or operation involved in learning – including those responsible for computing errors, and for using those errors to modify the Projections between Mechanisms, is assigned to a different PsyNeuLink learning-related Component. These can be used to implement all types of learning. Learning is generally considered to fall into two broad classes: unsupervised, in which connections weights are modified by mere exposure to the inputs in order to capture structure and/or relationships among them; and supervised, which in which the connection weights are modified so that each input generates a desired output (see https://www.geeksforgeeks.org/supervised-unsupervised-learning/ for a useful summary). Both types of learning can be implemented in a Composition, using LearningMechanisms that compute the changes to make to the matrix parameter of MappingProjections being learned, and LearningProjections that apply those changes to those MappingProjections. In addition, supervised learning uses an ObjectiveMechanism – usually a ComparatorMechanism – to compute the error between the response generated by the last Mechanism in a learning Pathway (to the input provided to the first Mechanism in the Pathway) and the target stimulus used to specify the desired response. In most cases, the LearningMechanisms, LearningProjections and, where needed, ObjectiveMechanism are generated automatically, as described for each type of learning below. However, these can also be configured manually using their constructors, or modified by assigning values to their attributes.

Unsupervised Learning¶

Undersupervised learning is implemented using a RecurrentTransferMechanism, setting its enable_learning argument to True, and specifying the desired LearningFunction in its learning_function argument. The default is Hebbian, however others can be specified (such as ContrastiveHebbian or Kohonen). When a RecurrentTransferMechanism with learning enabled is added to a Composition, an AutoAssociativeLearningMechanism that that is appropriate for the specified learning_function is automatically constructured and added to the Composition, as is a LearningProjection from the AutoAssociativeLearningMechanism to the RecurrentTransferMechanism’s recurrent_projection. When the Composition is run and the RecurrentTransferMechanism is executed, its AutoAssociativeLearningMechanism is also executed, which updates the matrix of its recurrent_projection in response to its input.

Supervised Learning¶

  • Supervised Learning Methods

  • Supervised Learning Components

  • Execution of Learning

Supervised Learning Methods¶

Supervised learning is implemented in a Composition by specifying a learning Pathway in the pathways argumemt of the Composition’s constructor, its add_pathways method, or one of its learning methods. If the constructor or add_pathways method is used, then the Pathway specification must be the first item in a tuple, followed by a LearningFunction as its 2nd item that specfies the type of learning. Alternatively, a learning Pathway can be added to a Composition by specifying the Pathway to be learned in the one of the Composition’s learning methods, of which there are currently three:

  • add_reinforcement_learning_pathway – uses Reinforcement;

  • add_td_learning_pathway – uses TDLearning;

  • add_backpropagation_learning_pathway – uses BackPropagation.

Each uses the Composition’s add_linear_processing_pathway method to create a learning Pathway using the corresponding LearningFunction.

Supervised Learning Pathways¶

A learning pathway is a contiguous sequence of ProcessingMechanisms and the MappingProjections between them, in which supervised learning is used to modify the matrix parameter of the MappingProjections in the sequence, so that the input to the first ProcessingMechanism in the sequence generates an output from the last ProcessingMechanism that matches as closely as possible a target value specified as input in the Composition’s learn method. The Mechanisms in the pathway must be compatible with learning (that is, their function must be compatible with the function of the LearningMechanism for the MappingProjections they receive (see Learning Function). The Composition’s learning methods return a learning Pathway, in which its learning_components attribute is assigned a dict containing the set of learning components generated for the Pathway, as described below.

Supervised Learning Components¶

For each learning pathway specified in the pathways argument of a Composition’s constructor or one of its learning methods, it creates the following Components, and assigns to them the NodeRoles indicated:

  • TARGET_MECHANISM – receives the desired value for the OUTPUT_MECHANISM, that is used by the OBJECTIVE_MECHANISM as the target in computing the error signal (see above); that value must be specified as an input to the TARGET_MECHANISM, either in the inputs argument of the Composition’s learn method, or in its targets argument in an entry for either the TARGET_MECHANISM or the OUTPUT_MECHANISM (see below); the Mechanism is assigned the NodeRoles TARGET and LEARNING in the Composition.

  • a MappingProjection that projects from the TARGET_MECHANISM to the TARGET InputPort of the OBJECTIVE_MECHANISM.

  • a MappingProjection that projects from the last ProcessingMechanism in the learning Pathway to the SAMPLE InputPort of the OBJECTIVE_MECHANISM.

  • OBJECTIVE_MECHANISM – usually a ComparatorMechanism, used to calculate an error signal (i.e., loss) for the sequence by comparing the value received by the ComparatorMechanism’s SAMPLE InputPort (from the output of the last Processing Mechanism in the learning Pathway) with the value received in the OBJECTIVE_MECHANISM’s TARGET InputPort (from the TARGET_MECHANISM generated by the method – see below); this is assigned the NodeRole LEARNING in the Composition.

  • LEARNING_MECHANISMS – a LearningMechanism for each MappingProjection in the sequence, each of which calculates the learning_signal used to modify the matrix parameter for the coresponding MappingProjection, along with a LearningSignal and LearningProjection that convey the learning_signal to the MappingProjection’s MATRIX ParameterPort; depending on learning method, additional MappingProjections may be created to and/or from the LearningMechanism – see Learning Configurations for details); these are assigned the NodeRole LEARNING in the Composition.

  • LEARNING_FUNCTION – the LearningFunction used by each of the LEARNING_MECHANISMS in the learning pathway.

  • LEARNED_PROJECTIONS – a LearningProjection from each LearningMechanism to the MappingProjection for which it modifies it s`matrix <MappingProjection.matrix>` parameter.

It also assigns the following item to the list of learning_components for the pathway:

  • OUTPUT_MECHANISM – the final Node in the learning Pathway, the target value for which is specified as input to the TARGET_MECHANISM; the Node is assigned the NodeRoles OUTPUT in the Composition.

The items with names listed above are placed in a dict that is assigned to the learning_components attribute of the Pathway returned by the learning method used to create the Pathway; they key for each item in the dict is the name of the item (as listed above), and the object(s) created of that type are its value (see Single layer learning for a more detailed description and figure showing these Components).

If the learning Pathway <Composition_Learning_Pathway>` involves more than two ProcessingMechanisms (e.g. using add_backpropagation_learning_pathway for a multilayered neural network), then multiple LearningMechanisms are created, along with MappingProjections that provide them with the error_signal from the preceding LearningMechanism, and LearningProjections that modify the corresponding MappingProjections (LEARNED_PROJECTIONs) in the learning Pathway, as shown for an example in the figure below. These additional learning components are listed in the LEARNING_MECHANISMS and LEARNED_PROJECTIONS entries of the dictionary assigned to the learning_components attribute of the learning Pathway return by the learning method.

Figure: Supervised Learning Components

Schematic of LearningMechanism and LearningProjections in a Process

Components for supervised learning Pathway: the Pathway has three Mechanisms generated by a call to a supervised learning method (e.g., add_backpropagation_learning_pathway(pathway=[A,B,C])), with NodeRole assigned to each Node in the Composition’s graph (in italics below Mechanism type) and the names of the learning components returned by the learning method (capitalized and in italics, above each Mechanism).¶

The description above (and example >below) pertain to simple linear sequences. However, more complex configurations, with convergent, divergent and/or intersecting sequences can be built using multiple calls to the learning method (see example in Basics and Primer). In each the learning method determines how the sequence to be added relates to any existing ones with which it abuts or intersects, and automatically creates andconfigures the relevant learning components so that the error terms are properly computed and propagated by each LearningMechanism to the next in the configuration. It is important to note that, in doing so, the status of a Mechanism in the final configuration takes precedence over its status in any of the individual sequences specified in the learning methods when building the Composition. In particular, whereas ordinarily the last ProcessingMechanism of a sequence specified in a learning method projects to a OBJECTIVE_MECHANISM, this may be superceded if multiple sequences are created. This is the case if: i) the Mechanism is in a seqence that is contiguous (i.e., abuts or intersects) with others already in the Composition, ii) the Mechanism appears in any of those other sequences and, iii) it is not the last Mechanism in all of them; in that in that case, it will not project to a OBJECTIVE_MECHANISM (see figure below for an example). Furthermore, if it is the last Mechanism in all of them (that is, all of the specified pathways converge on that Mechanism), only one OBJECTIVE_MECHANISM is created for that Mechanism (i.e., not one for each sequence). Finally, it should be noted that, by default, learning components are not assigned the NodeRole of OUTPUT even though they may be the TERMINAL Mechanism of a Composition; conversely, even though the last Mechanism of a learning Pathway projects to an OBJECTIVE_MECHANISM, and thus is not the TERMINAL Node of a Composition, if it does not project to any other Mechanisms in the Composition it is nevertheless assigned as an OUTPUT of the Composition. That is, Mechanisms that would otherwise have been the TERMINAL Mechanism of a Composition preserve their role as an OUTPUT Node of the Composition if they are part of a learning Pathway eventhough they project to another Mechanism (the OBJECTIVE_MECHANISM) in the Composition.

OUTPUT vs. TERMINAL Roles in Learning Configuration

Schematic of Mechanisms and Projections involved in learning

Configuration of Components generated by the creation of two intersecting learning Pathways (e.g., add_backpropagation_learning_pathway(pathway=[A,B]) and add_backpropagation_learning_pathway(pathway=[D,B,C])). Mechanism B is the last Mechanism of the sequence specified for the first pathway, and so would project to a ComparatorMechanism, and would be assigned as an OUTPUT Node of the Composition, if that pathway was created on its own. However, since Mechanims B is also in the middle of the sequence specified for the second pathway, it does not project to a ComparatorMechanism, and is relegated to being an INTERNAL Node of the Composition Mechanism C is now the one that projects to the ComparatorMechanism and assigned as the OUTPUT Node.¶

Execution of Learning¶

For learning to occur when a Composition is run, its learn method must be used instead of the run method, and its disable_learning attribute must be False. When the learn method is used, all Components unrelated to learning are executed in the same way as with the run method. If the Composition has any nested Composition that have learning Pathways, then learning also occurs on all of those for which the disable_learning attribute is False. This is true even if the disable_learning attribute is True for which the Composition on which the learn method was called.

When a Composition is run that contains one or more learning Pathways, all of the ProcessingMechanisms for a pathway are executed first, and then its learning components. This is shown in an animation of the XOR network from the example above:

Composition with Learning

Animation of Composition with learning

Animation of XOR Composition in example above when it is executed by calling its learn method with the argument animate={'show_learning':True}.¶

Note

Since the learning components are not executed until after the processing components, the change to the weights of the MappingProjections in a learning pathway are not made until after it has executed. Thus, as with execution of a Projection, those changes will not be observed in the values of their matrix parameters until after they are next executed (see Lazy Evaluation for an explanation of “lazy” updating).

Learning Using AutodiffCompositon¶

AutodiffCompositions provide the ability to execute backpropagation learning much more efficiently than using a standard Composition. An AutodiffComposition is constructed in the same way, but there is no need to specify any learning components>` or using any learning methods – in fact, they should not be specified (see warning) – an AutodiffComposition automatically creates backpropagation learning pathways from all input to all output Nodes. While learning in an AutodiffComposition is restricted to the BackPropagation learning algorithm, its loss function can be specified (using the **loss_spec** parameter of its constructor), which implements different kinds of `supervised learning (for example, Loss.MSE can be used for regression, or Loss.CROSS_ENTROPY for classification).

The advantage of using an AutodiffComposition is that it allows a model to be implemented in PsyNeuLink, and then exploit the acceleration of optimized implementations of learning. This can be achieved by executing the learn method in one of two modes (specified using its execution_mode argument): using direct compilation (execution_mode = ExecutionMode.LLVMRun); or by automatically translating the model to PyTorch for training (execution_mode = ExecutionMode.PyTorch). The advantage of these modes is that they can provide up to three orders of magnitude speed-up in training a model. However, there are restrictions on the kinds of Compositions that be implemented in this way. The features of the different ways to implement and execute learning are outlined in the following table, and described in more detail in AutodiffComposition.

Composition

AutodiffComposition

Python

Direct Compilation

PyTorch

execution_mode =

ExecutionMode.Python

ExecutionMode.LLVMRun

ExecutionMode.PyTorch

learn()

run()

Python interpreted

Python interpreted

LLVM compiled

LLVM compiled

PyTorch compiled

Python interpreted

Speed:

slow

fastest

fast

Supports:

  • Backpropagation

  • Reinforcement learning

  • Unspervised learning

  • modulation, inspection

  • Backpropagation

  • Backpropagation

  • RNN, inclduing LSTM

  • Unsupervised learning

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 Mechanism, 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. It must 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).

Executing a Composition¶

  • Execution Methods

  • Composition Inputs
    • Input Dictionary

    • Specifying Inputs Programmatically

  • Execution Factors
    • Runtime Parameters

    • Cycles and Feedback

    • Execution Contexts

    • Timing

    • Resetting Stateful Parameters

    • Compilation

  • Results, Reporting and Logging

There are three methods for executing a Composition:

  • run - executes one or more TRIALs without learning;

  • learn - executes one or more TRIALs with learning, if the network is configured for learning.

  • execute - executes a single TRIAL without learning.

The run and learn methods are the most commonly used. Both of these can execute multiple trials (specified in their num_trials argument), calling the Composition’s execute method for each TRIAL. The execute method can also be called directly, but this is useful mostly for debugging.

Hint

Once a Composition has been constructed, it can be called directly. If it is called with no arguments, and has executed previously, the result of the last TRIAL of execution is returned; otherwise None is returned. If it is called with arguments, then either run or learn is called, based on the arguments provided: If the Composition has any learning_pathways, and the relevant TARGET_MECHANISMs are specified in the inputs argument, then learn is called; otherwise, run is called. In either case, the return value of the corresponding method is returned.

Number of trials. If the the execute method is used, a single TRIAL is executed; if the inputs specifies more than one TRIALs worth of input, an error is generated. For the run and learn, the num_trials argument can be used to specify an exact number of TRIALs to execute; if its value execeeds the number of inputs provided for each Node in the inputs argument, then the inputs are recycled from the beginning of the lists, until the number of TRIALs specified in num_trials has been executed. If num_trials is not specified, then a number of TRIALs is executed equal to the number of inputs provided for each Node in inputs argument.

Learning. If a Composition is configured for learning then, for learning to occur, its learn method must be used in place of the run method, and its disable_learning attribute must be False (the default). A set of targets must also be specified (see below). The run and execute methods can also be used to execute a Composition that has been configured for learning, but no learning will occur, irrespective of the value of the disable_learning attribute.

The sections that follow describe the formats that can be used for inputs, factors that impact execution, and how the results of execution are recorded and reported.

Composition Inputs¶

  • Input Dictionary

  • Specifying Inputs Programmatically

All methods of executing a Composition require specification of an inputs argument (and a targets argument for the learn method), which designates the values assigned to the INPUT (and, for learning, the TARGET) Nodes of the Composition. These are provided to the Composition each time it is executed; that is, for each TRIAL. A TRIAL is defined as the opportunity for every Node in the Composition to execute the current set of inputs. The inputs for each TRIAL can be specified using an input dictionary; for the run and learn methods, they can also be specified programmatically. Irrespective of format, the same number of inputs must be specified for every INPUT Node, unless only one value is specified for a Node (in which case that value is repeated as the input to that Node for every TRIALs executed). If the inputs argument is not specified for the run or execute methods, the default_variable for each INPUT Node is used as its input on TRIAL. If it is not specified for the learn method, an error is generated unless its targets argument is specified (see below). The Composition’s get_input_format() method can be used to show an example for how inputs should be formatted for the Composition, as well as the INPUT Nodes to which they are assigned. The formats are described in more detail below.

Input formats (including targets for learning)¶

There are two ways to specify inputs:

  • using a dictionary, in which the inputs are specified or each TRIAL explicitly;

  • programmtically, using a function, generator or generator function that constructs the inputs dynamically on a TRIAL by TRIAL basis.

The inputs argument of the run and learn methods (and the targets argument of the learn method) can be specified in either way; however, only the dictionary format can be used for the execute method, since it executes only one TRIAL at a time, and therefore can only accept inputs for asingle TRIAL.

Inputs and input_ports. All formats must specify the inputs to be assigned, on each TRIAL, to all of the external InputPorts of the Composition’s INPUT Nodes. These are InputPorts belonging to its INPUT Nodes at all levels of nesting, that are not designated as internal_only. They are listed in the Composition’s external_input_ports_of_all_input_nodes attribute, as well as the external_input_ports attribute of each Mechanism that is an INPUT Node of the Composition or any nested Composition within it The format required can also be seen using the get_input_format() method.

Note

Most Mechanisms have only a single InputPort, and thus require only a single input to be specified for them for each TRIAL. However some Mechanisms have more than one InputPort (for example, a ComparatorMechanism), in which case inputs can be specified for some or all of them (see below). Conversely, some Mechanisms have InputPorts that are designated as internal_only (for example, the input_port for a RecurrentTransferMechanism, if its has_recurrent_input_port attribute is True), in which case no input should be specified for those input_ports. Similar considerations extend to the external_input_ports_of_all_input_nodes of a nested Composition, based on the Mechanisms (and/or additionally nested Compositions) thatcomprise its set of INPUT Nodes.

The factors above determine the format of each entry in an inputs dictionary, or the return value of the function or generator used for programmatic specification of inputs, as described in detail below (also see examples).

Input Dictionary¶

The simplest way to specificy inputs (including targets for learning) is using a dict, in which each entry specifies the inputs to a given INPUT Node. The key for each entry of the dict is either an INPUT Node or the InputPort of one, and the value is the input to be provided to it for each TRIAL of execution. A diciontary can have entries for either an INPUT Node or one or more of its InputPorts, but not both. Entries can be for any INPUT Node (or the Inputport(s) of one) at any level of nesting within the Composition, so long it is nested under INPUT Nodes at all levels of nesting (that is, an INPUT Node of a nested Composition can only be included if the nested Composition is a INPUT Node of the Composition to which it belongs). Any INPUT Nodes for which no input is specified (that is, for which there are no entries in the inputs dictionary) are assigned their default_external_inputs on each TRIAL of execution; similarly, if the dictionary contains entries for some but not all of the InputPorts of a Node, the remaining InputPorts are assigned their default_input on each TRIAL of execution. See below for additional information concerning entries for Nodes and entries for InputPorts).

Input values. The value of each entry is an ndarray or nested list containing the inputs to that Node or InputPort. For Nodes, the value is a 3d array (or correspondingly nested list), in which the outermost items are 2d arrays containing the 1d array of input values to each of the Node’s InputPorts for a given TRIAL. For entries specifying InputPorts, the value is a 2d array, containing 1d arrays with the input to the InputPort for each TRIAL. A given entry can specify either a single TRIAL's worth of input (i.e., a single item in its outermost dimension), or inputs for every TRIAL to be executed (in which the i-th item represents the input to the INPUT Node, or one of its InputPorts, on TRIAL i). All entries that contain more than a single trial’s worth of input must contain exactly the same number of values – i.e.,inputs for the same number of trials. For entries that contain a single input value, that value will be provided repeatedly as the input to the specified Component for every TRIAL when the Composition is executed (as determined by the number of input values specified for other entries and/or the num_trials argument of the Composition’s run method (see number of trials above).

Node entries. The key must be an INPUT Node of the Composition, or the name of one (i.e., the str in its name attribute), and the value must specify the input to all of its InputPorts (other than those designated as internal_only; see note above) for one or all TRIALs of execution. The values for each TRIAL must be compatible with each of the corresponding InputPorts (listed in the external_input_ports attribute of a Mechanism, and similarly in the external_input_ports_of_all_input_nodes attribute of a Composition). More specifically, the shape of each item in the outer dimension (i.e., the input for each TRIAL, as described above) must be compatible with the shape of the Node’s external_input_shape attribute if it is Mechanism, and similarly the external_input_shape attribute of a Composition). While these are always 2d arrays, the number and size of the 1d arrays within them (corresponding to each InputPort) may vary; in some case shorthand notations are allowed, as illustrated in the examples below.

Example input dict specification showing inputs specified for each Node and its InputPorts

Example input dict specification, in which the first entry is for Mechanism a with one InputPort that takes an array of length 2 as its input, and for which two TRIALs worth of input are specified ([1.0, 2.0] and [3,0, 4.0]); the second entry is for Mechanism b with two InputPorts, one of which takes an array of length 1 as its input and the other an array of length 2, and for which two TRIALs worth of input are also specified ([[1.0], [2.0, 3.0]] and [[4.0], [5.0, 6.0]]); and, finaly, a third entry is for Mechanism c with only one InputPort that takes an array of length 1 as its input, and for which only one input is specified ([1.0]), which is therefore provided as the input to Mechanism c on every TRIAL.¶

InputPort Entries. The key must be an external InputPort for an INPUT Node of the Composition, or the full_name of one, and the value must specify the input for one or all TRIALs of execution. Any or all of the InputPorts for an`INPUT <NodeRole>` Node can be specified, but an inputs dictionary cannot have specifications for both the Node and any of its InputPorts. If the name of an InputPort is used as the key, its the str in its full_name attribute must be used, to ensure disambiguation from any similarly named InputPorts of other Nodes. Specifying InputPorts individually (instead of specifying all of them in a single entry for a Node) can be if only some InputPorts should receive inputs, or the input for some needs to remain constant across TRIALs (by providing it with only one input value) while the input to others vary (i.e., by providing input_values for every TRIAL). The value of each entry must be a 2d array or nested list containing the input for either a single TRIAL or all TRIALs, each of which must match the input_shape of the InputPort. As with Nodes, if there are entries for some but not all of a Node’s InputPorts, the ones not specified are assigned their default_input values for every TRIAL of execution.

Input Labels. In general, the value of inputs should be numeric arrays; however, some Mechanisms have an input_labels_dict that specifies a mapping from strings (labels) to numeric values, in which those strings can be used to specify inputs to that Mechanism (these are translated to their numeric values on execution). However, such labels are specific to a given Mechanism; use of strings as input to a Mechanism that does not have an input_labels_dict specified, or use of a string that is not listed in the dictionary for that Mechanism generates and error.

Target Inputs for learning. Inputs must also be specified for the TARGET_MECHANISM of each learning Pathway in the Composition. This can be done in either the inputs argument or targets argument of the learn method. If the inputs argument is used, it must include an entry for each TARGET_MECHANISM; if the targets argument is used, it must be assigned a dictionary containing entries in which the key is either an OUTPUT_MECHANISM (i.e., the final Node) of a learning Pathway, or the corresponding TARGET_MECHANISM. The value of each entry specifies the inputs for each trial, formatted asdescribed above.

The input format required for a Composition, and the INPUT Nodes to which inputs are assigned, can be seen using its get_input_format method.

Specifying Inputs Programmatically¶

Inputs can also be specified programmticaly, in a TRIAL by TRIAL manner, using a function, generator, or generator function.

A function used as input must take as its sole argument the current TRIAL number and return a value that satisfies all rules above for standard input specification. The only difference is that on each execution, the function must return the input values for each INPUT Node for a single TRIAL.

Note

Default behavior when passing a function as input to a Composition is to execute for only one TRIAL. Remember to set the num_trials argument of Composition.run if you intend to cycle through multiple TRIALs.

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 = pnl.Composition(name='comp')

>>> comp.add_linear_processing_pathway(pathway1)

>>> def function_as_input(trial_num):
...     a_inputs = [[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]]
...     this_trials_inputs = {
...         a: a_inputs[trial_num]
...     }
...     return this_trials_inputs

>>> comp.run(inputs=function_as_input,
...          num_trials=2)

A generator can also be used as input. On each yield, it should return a value that satisfies all rules above for standard input specification. The only difference is that on each execution, the generator must yield the input values for each INPUT Node for a single TRIAL.

Note

Default behavior when passing a generator is to execute until the generator is exhausted. If the num_trials argument of Composition.run is set, the Composition will execute EITHER until exhaustion, or until num_trials has been reached - whichever comes first.

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 = pnl.Composition(name='comp')

>>> comp.add_linear_processing_pathway(pathway1)

>>> def generator_as_input():
...    a_inputs = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]
...    for i in range(len(a_inputs)):
...        this_trials_inputs = {a: a_inputs[i]}
...        yield this_trials_inputs

>>> generator_instance = generator_as_input()

>>> # Because the num_trials argument is set to 2, the below call to run will result in only 2 executions of
... # comp, even though it would take three executions to exhaust the generator.
>>> comp.run(inputs=generator_instance,
...          num_trials=2)

If a generator function is used, the Composition will instantiate the generator and use that as its input. Thus, the returned generator instance of a generator function must follow the same rules as a generator instance passed directly to the Composition.

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 = pnl.Composition(name='comp')

>>> comp.add_linear_processing_pathway(pathway1)

>>> def generator_function_as_input():
...    a_inputs = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
...    for i in range(len(a_inputs)):
...        this_trials_inputs = {a: a_inputs[i]}
...        yield this_trials_inputs

>>> comp.run(inputs=generator_function_as_input)

Execution Factors¶

  • Runtime Parameters

  • Cycles and Feedback

  • Execution Contexts

  • Timing

  • Resetting Stateful Parameters

  • Compilation

Runtime Parameters¶

The value of one or more of a Composition’s Nodes can be temporarily modified during execution using the runtime_params argument of one of its execution methods. These are handled as described for Runtime Parameters of Mechanisms, with the addition that one or more Conditions can be specified such that a value will apply only when the specificied Conditions are satisfied; otherwise the parameter’s previously assigned value (or, if none, then its default) will be used, and those values are always restored after execution.

Runtime parameter values for a Composition are specified in a dictionary assigned to the runtime_params argument of a Composition’s execution method. The key of each entry is a Node of the Composition, and the value is a subdictionary specifying the runtime_params argument that will be passed to the Node when it is executed. The format of the dictionary for each Node follows that for a Mechanism’s runtime specification dictionary, except that in addition to specifying the value of a parameter directly (in which case, the value will apply throughout the execution), its value can also be placed in a tuple together with a Condition specifying when that value should be applied, as follows:

  • Dictionary assigned to runtime_parms argument: {<Node>: Runtime Parameter Specification Dictionary}
    • key - Node

    • value - Runtime Parameter Specification Dictionary

  • Runtime Parameter Specification Dictionary: {<parameter name>: (<parameter value>, Condition)}
    • key - str name of a Parameter of the Node, its function, or a keyword specifying a subdictionary containing runtime parameter specifications for Component(s) of the Node (see below);

    • value - (<parameter value>, Condition), <parameter value>, or subdictionary (see below) Condition specifies when the value is applied; otherwise, its previously assigned value or default is used; if the parameter values appears alone in a tuple or outside of one, then the Condition Always() is applied.

See Runtime Parameter Specification Dictionary for additional details.

As in a standard runtime parameter specification dictionary, the key for an entry can be used to specify a subdictionary specifying the runtime parameters for a Mechanism’s Ports, and/or any of their afferent Projections (see Runtime specification ditionary: parameters of a Mechanism’s Ports and Projections). The subdictionaries used to specify those can be placed placed in a tuple, as can any of the specification of parameter values within them. A tuple used to specify a subdictionary determines when any of the parameters specified within it are eligible to apply: If its Condition is not satisfied, then none of the parameters specified within it will apply; if its Condition is satisfied, then any parameter specified within it for which the Condition is satisified will also apply.

Cycles and Feedback¶

  • Cycles and Synchronous Execution

  • Feedback and Sequential Execution

If Projections among any or all of the Nodes in a Composition form loops — that is, there are any cycles in its graph — then the order in which the Nodes are executed must be determined. This is handled in one of two ways:

  • Flatten cycle - if the cycle does not have any feedback Projections, then the cycle is “flattened” and all of the Nodes are executed synchronously.

  • Break cycle - if cycle has any feedback Projections, they are used to break the cycle at those points, and the remaining Projections are used to execute the Nodes sequentially, with the receiver of each feedback Projection executed first, its sender executed last, and the receiver getting the sender’s value on its next execution.

Each of these approaches is described in greater detail below.

Cycles and Synchronous Execution¶

Cycles. A cycle is formed when the Projections among a set of Nodes form a loop, and none of the Projections is designated as a feedback Projection. Any cycle nested within another is added to the one in which it is nested, and all are treated as part of the same cycle. All Nodes within a cycle are assigned the NodeRole CYCLE.

Note

A RecurrentTransferMechanism (and its subclaseses) are treated as single-Node cylces, formed by their AutoAssociativeProjection (since the latter is subclass of MappingProjection and thus not designated as feedback (see below).

Synchronous execution. Cycles are “flattened” for execution, meaning that all of the Nodes within a cycle are executed in the same TIME_STEP). The input that each Node in a cycle receives from those that project to it from within the cycle is the value of those Nodes when the cycle was last executed in the same execution context; this ensures not only that the execute in synchrony, but that the inputs received from any Nodes within the cycle are synchronized (i.e., from the same earlier TIME_STEP of execution). However, this presents a problem for the first execution of the cycle since, by definition, none of the Nodes have a value from a previous execution. In that case, each sender passes the value to which it has been initialized which, by default, is its default value. However, this can be overridden, as described below.

Note

Although all the Nodes in a cycle receive either the initial value or previous value of other Nodes in the cycle, they receive the current value of any Nodes that project to them from outisde the cycle, and pass their current value (i.e., the ones computed in the current execution of the cycle) to any Nodes to which they project outside of the cycle. The former means that any Nodes within the cycle that receive such input are “a step ahead” of those within the cycle and also, unless the use a StatefulFunction, others within the cycle will not see the effects of that input within or across TRIALS.

Initialization. The initialization of Nodes in a cycle using their default values can be overridden using the initialize_cycle_values argument of the Composition’s run or learn methods. This can be used to specify an initial value for any Node in a cycle. On the first call to run or learn, nodes specified in initialize_cycle_values are initialized using the assigned values, and any Nodes in the cycle that are not specified are assigned their default value. In subsequent calls to run or learn, Nodes specified in initialize_cycle_values will be re-initialized to the assigned values for the first execution of the cycle in that run, whereas any Nodes not specified will retain the last value they were assigned in the uprevious call to run or learn.

Nodes in a cycle can also be initialized outside of a call to run or learn using the initialize method.

Note

If a Mechanism belonging to a cycle in a Composition is first executed on its own (i.e., using its own execute method), the value it is assigned will be used as its initial value when it is executed within the Composition, unless an execution_id is assigned to the context argument of the Mechanism’s execute method when it is called. This is because the first time a Mechanism is executed in a Composition, its initial value is copied from the value last assigned in the None context. As described aove, this can be overridden by specifying an initial value for the Mechanism in the initialize_cycle_values argument of the call to the Composition’s run or learn methods.

Feedback and Sequential Execution¶

Feedback designation. If any Projections in a loop are designated as feedback they are used to break the cycle of execution that would otherwise be formed, and the Nodes are executed sequentially as described below. Each Node that sends a feedback Projection is assigned the NodeRole FEEDBACK_SENDER, and the receiver is assigned the NodeRole FEEDBACK_RECEIVER. By default, MappingProjections are not specified as feedback, and therefore loops containing only MappingProjections are left as cycles. In contrast, ModulatoryProjections are designated as feedback by default, and therefore any loops containing one or more ModulatoryProjections are broken, with the Mechanism that is modulated designated as the FEEDBACK_RECEIVER and the ModulatoryMechanism that projects to it designated as the FEEDBACK_SENDER. However, either of these default behaviors can be overidden, by specifying the feedback status of a Projection explicitly, either in a tuple with the Projection where it is specified in a Pathway or in the Composition’s add_projections method, or by using the feedback argument of the Composition’s add_projection method. Specifying True or the keyword FEEDBACK forces its assignment as a feedback Projection, whereas False precludes it from being assigned as a feedback Projection (e.g., a ControlProjection that otherwise forms a cycle will no longer do so).

Warning

Designating a Projection as feeedback that is not in a loop is allowed, but will issue a warning and can produce unexpected results. Designating more than one Projection as feedback within a loop is also permitted, by can also lead to complex and unexpected results. In both cases, the FEEDBACK_RECEIVER for any Projection designated as feedback will receive a value from the Projection that is based either on the FEEDBACK_SENDER's initial_value (the first time it is executed) or its previous value (in subsequent executions), rather than its most recently computed value whether or not it is in a cycle (see below).

Sequential execution. The FEEDBACK_RECEIVER is the first of the Nodes that were in a loop to execute in a given PASS, receiving a value from the FEEDBACK_SENDER as described below. It is followed in each subsequent TIME_STEP by the next Node in the sequence, with the FEEDBACK_SENDER executing last.

Initialization. The receiver of a feedback Projection (its FEEDBACK_RECEIVER) is treated in the same way as a CYCLE Node: the first time it executes, it receives input from the FEEDBACK_SENDER based on the value to which it was initialized . On subsequent executions, its input from the FEEDBACK_SENDER is based on the value of that Node after it was last executed in the same execution context.

The FEEDBACK_SENDERs of a Composition are listed in its feedback_senders attribute, and its FEEDBACK_RECEIVERs in feedback_senders. These can also be listed using the Composition’s get_nodes_by_role method. The feedback Projections of a Composition are listed in its feedback_projections attribute, and the feedback status of a Projection in a Composition is returned by its get_feedback_status method.

Execution Contexts¶

A Composition is always executed in a designated execution context, specified by an execution_id that can be provided to the context argument of the method used to execute the Composition. Execution contexts make several capabilities possible, the two most important of which are:

  • a Component can be assigned to, and executed in more than one Composition, preserving its value and that of its parameters independently for each of the Compositions to which it is assigned;

  • the same Composition can be exectued independently in different contexts; this can be used for parallelizing parameter estimation, both for data fitting (see ParamEstimationFunction), and for simulating the Composition in model-based optimization (see OptimizationControlMechanism).

If no execution_id is specified, the default execution_id is used, which is generally the Composition’s name; however, any hashable value (e.g., a string, a number, or Component) can be used. That execution_id can then be used to retrieve the value of any of the Composition’s Components or their parameters that were assigned during the execution. If a Component is executed outside of a Composition (e.g, a Mechanism is executed on its own using its execute method), then any assignments to its value and/or that of its parameters is given an execution_id of None.

Note

If the value of a Component or a parameter is queried using dot notation, then its most recently assigned value is returned. To retrieve the value associated with a particular execution context, the parameter’s get method must be used: <Component>.parameters.<parameter_name>.get(execution_id), where value can be used as the parameter_name to retrieve the Component’s value, and the name of any of its other parameters to get their value.

See Execution Contexts for examples.

Initialization of Execution Contexts

  • The parameter values for any execution context can be copied into another execution context by using Component._initialize_from_context, which when called on a Component copies the values for all its parameters and recursively for all of the Component’s _dependent_components.

  • _dependent_components should be added to for any new Component that requires other Components to function properly (beyond “standard” things like Component.function, or Mechanism.input_ports, as these are added in the proper classes’ _dependent_components).

    • The intent is that with _dependent_components set properly, calling obj._initialize_from_context(new_context, base_context) should be sufficient to run obj under new_context.

    • A good example of a “nonstandard” override is OptimizationControlMechanism._dependent_components

Timing¶

When run is called by a Composition, it calls that Composition’s execute method once for each input (or set of inputs) specified in the call to run, which constitutes a TRIAL of execution. For each TRIAL, the Component makes repeated calls to its scheduler, executing the Components it specifies in each TIME_STEP, until every Component has been executed at least once or another termination condition is met. The scheduler can be used in combination with Condition specifications for individual Components to execute different Components at different time scales.

Resetting Stateful Parameters¶

Stateful Functions (such as IntegratorFunctions and “non-parametric” MemoryFunctions) have a previous_value attribute that maintains a record of the Function’s values for each execution context in which it is executed, within and between calls to the Composition’s execute methods. This record can be cleared and previous_value reset to either the Function’s default value or another one, using either the Composition’s reset method or in arguments to its run and learn methods, as described below (see Reset Paramters of Stateful Functions for examples):

  • reset – this is a method of the Composition that calls the reset method of Nodes in the Composition that have a StatefulFunction, each of which resets the stateful parameters of those Functions. of its StatefulFunction. If it is called without any arguments, it calls the reset method for every Node in the Composition that has a StatefulFunction. It can also be called with a dictionary that specifies a subsset of Nodes to reset (see format descdribed for reset_stateful_functions_when below).

  • reset_stateful_functions_when and reset_stateful_functions_to – these are arguments of the Composition’s run and learn methods, that can be used to specify the Conditions under which the reset method of all or a particular subset of Nodes are called during that run, and optionally the values they are assigned when reset. As with runtime_params, these specifications apply only for the duration of the call to run or learn, and the reset_stateful_function_when of all Nodes are restored to their prior values upon completion.

    • reset_stateful_functions_when – this specifies the Condition(s) under which the reset method will be called for Nodes with stateful. If a single Condition is specified, it is applied to all of the Composition’s Nodes that have stateful; a dictionary can also be specified, in which the key for each entry is a Node, its value is a Condition under which that Node’s reset method should be called.

      Note

      If a single Condition is specified, it applies only to Nodes for which the reset_stateful_function_when attribute has not otherwise been specified. If a dictionary is specified, then the Condition specified for each Node applies to that Node, superceding any prior specification of its reset_stateful_function_when attribute for the duration of the call to run or learn.

    • reset_stateful_functions_to – this specifies the values used by each Node to reset the stateful parameters of its StatefulFunction(s). It must be a dictionary of {Node:value} pairs, in which the value specifies the value(s) passed to the reset method of the specified Node. If the reset method of a Node takes more than one value (see Note below), then a list of values must be provided (i.e., as {node:[value_0, value_1,… value_n]}) that matches the number of arguments taken by the reset method. Any Nodes not specified in the dictionary are reset using their default value(s).

      Note

      The reset method of most Nodes with a StatefulFunction takes only a single value, that is used to reset the previous_value attribute of the Function. However some (such as those that use DualAdaptiveIntegrator) take more than one value. For such Nodes, a list of values must be specified as the value of their dicitonary entry in reset_stateful_functions_to.

    The reset_stateful_functions_when and reset_stateful_functions_to arguments can be used in conjunction or independently of one another. For example, the Condition(s) under which a Mechanism with a StatefulFunction is reset using to its default values can be specified by including it in reset_stateful_functions_when but not reset_stateful_functions_to. Conversely, the value to which the StatefulFunction of a Mechanism is reset can be specified without changing the Condition under which this occurs, by including it in reset_stateful_functions_to but not reset_stateful_functions_when – in that case, the Condition specified by its own reset_stateful_function_when parameter will be used.

Compilation¶

By default, a Composition is executed using the Python interpreter used to run the script from which it is called. In many cases, a Composition can also be executed in a compiled mode. While this can add some time to initiate execution, execution itself can be several orders of magnitude faster than using the Python interpreter. Thus, using a compiled mode can be useful for executing Compositions that are complex and/or for large numbers of TRIALs. Compilation is supported for most CPUs (including x86, arm64, and powerpc64le). Several modes can be specified, that that tradeoff power (i.e., degree of speed-up) against level of support (i.e., likelihood of success). Most PsyNeuLink Components and methods are supported for compilation; however, Python native functions and methods (e.g., used to specify the function of a Component) are not supported at present. Users who wish to compile custom functions should refer to compiled User Defined Functions for more information. See below and Compilation for additional details regarding the use of compiled modes of execution, and Vesely et al. (2022) for more information about the approach taken to compilation.

Warning

Compiled modes are continuing to be developed and refined, and therefore it is still possible that there are bugs that will not cause compilation to fail, but could produce erroneous results. Therefore, it is strongly advised that if compilation is used, suitable tests are conducted that the results generated are identical to those generated when the Composition is executed using the Python interpreter.

Users are strongly urged to report any compilation failures to psyneulinkhelp@princeton.edu, or as an issue here. Known failure conditions are listed here.

The execution_mode argument of an execution method specifies whether to use a compiled mode and, if so, which. If True is specified, an attempt is made to use the most powerful mode (LLVMRun) and, if that fails, to try progressively less powerful modes (issueing a warning indicating the unsupported feature that caused the failure), reverting to the Python interpreter if all compiled modes fail. If a particular mode is specified and fails, an error is generated indicating the unsupported feature that failed. The compiled modes, in order of their power, are:

  • True – try to use the one that yields the greatesst improvement, progressively reverting to less powerful but more forgiving modes, in the order listed below, for each that fails;

  • ExecutionMode.LLVMRun - compile and run multiple TRIALs; if successful, the compiled binary is semantically equivalent to the execution of the run method using the Python interpreter;

  • ExecutionMode.LLVMExec – compile and run each TRIAL, using the Python interpreter to iterate over them; if successful, the compiled binary for each TRIAL is semantically equivalent the execution of the execute method using the Python interpreter;

  • ExecutionMode.LLVM – compile and run Node of the Composition and their Projections, using the Python interpreter to call the Composition’s scheduler, execute each Node and iterate over TRIALs; note that, in this mode, scheduling Conditions that rely on Node Parameters is not supported;

  • ExecutionMode.Python (same as False; the default) – use the Python interpreter to execute the Composition.

  • ExecutionMode.PyTorch – used only for AutodiffComposition: executes learn

    using PyTorch and run using Python interpreter (see below for additional details).

    Warning

    For clarity, ExecutionMode.PyTorch should only be used when executing an AutodiffComposition; using it with a standard Composition is possible, but it will not have the expected effect of executing its learn method using PyTorch.

  • ExecutionMode.PTXrun – compile multiple TRIALs for execution on GPU (see below for additional details).

  • ExecutionMode.PTXExec – compile individual TRIALs for execution on GPU (see below for additional details).

PyTorch support. When using an AutodiffComposition, ExecutionMode.PyTorch can be used to execute its learn method using Pytorch; however, its run method will execute using the Python interpreter. See Learning Using AutodiffCompositon for additional details.

GPU support. In addition to compilation for CPUs, support is being developed for CUDA capable Invidia GPUs. This can be invoked by specifying either ExecutionMode.PTXRun or ExecutionMode.PTXExec oin the execution_mode argument of a Composition execution method, which are equivalent to the LLVM counterparts but run in a single thread of a CUDA capable GPU. This requires that a working pycuda package is installed, and that CUDA execution is explicitly enabled by setting the PNL_LLVM_DEBUG environment variable to cuda. At present compilation using these modes runs on a single GPU thread, and therefore does not produce any performance benefits over running in compiled mode on a CPU; (see this for progress extending support of parallization in compiled modes).

Results, Reporting and Logging¶

Results

Executing a Composition returns the results of the last TRIAL executed. If either run or learn is called, the results of all TRIALS executed are available in the Composition’s results attribute. More specifically, at the end of a TRIAL (a list of the output_values for all of its OUTPUT Nodes) are added to the Composition’s results attribute, and the output_values for the last TRIAL executed is returned by the execution method. The output_values of the last TRIAL for each OUTPUT can be seen using the Composition’s get_results_by_nodes method.

Reporting

A report of the results of each TRIAL can be generated as the Composition is executing, using the report_output and report_progress arguments of any of the execution methods. report_output (specified using ReportOutput options) generates a report of the input and output of the Composition and its Nodes, and optionally their Parameters (specified in the report_params arg using ReportParams options); report_progress (specified using ReportProgress options) shows a progress bar indicating how many TRIALS have been executed and an estimate of the time remaining to completion. These options are all OFF by default (see Reporting for additional details).

Logging

The values of individual Components (and their parameters) assigned during execution can also be recorded in their log attribute using the Log facility.

Visualizing a Composition¶

The show_graph method generates a display of the graph structure of Nodes and Projections in the Composition based on the Composition’s graph (see Visualization for additional details).

Composition Examples¶

  • Creating a Composition

  • Run Composition

  • Learning

  • Input Formats

  • Runtime Parameters

  • Cycles and Feedback

  • Execution Contexts

  • Reset Paramters of Stateful Functions

  • Composition_Examples_Visualization

Creating a Composition¶

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 using 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)

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:

>>> 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 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)

Learning¶

The following example implements a simple three-layered network that learns the XOR function (see figure):

# Construct Composition:
>>> input = TransferMechanism(name='Input', default_variable=np.zeros(2))
>>> hidden = TransferMechanism(name='Hidden', default_variable=np.zeros(10), function=Logistic())
>>> output = TransferMechanism(name='Output', default_variable=np.zeros(1), function=Logistic())
>>> input_weights = MappingProjection(name='Input Weights', matrix=np.random.rand(2,10))
>>> output_weights = MappingProjection(name='Output Weights', matrix=np.random.rand(10,1))
>>> xor_comp = Composition('XOR Composition')
>>> backprop_pathway = xor_comp.add_backpropagation_learning_pathway(
>>>                       pathway=[input, input_weights, hidden, output_weights, output])

# Create inputs:            Trial 1  Trial 2  Trial 3  Trial 4
>>> xor_inputs = {'stimuli':[[0, 0],  [0, 1],  [1, 0],  [1, 1]],
>>>               'targets':[  [0],     [1],     [1],     [0] ]}
>>> xor_comp.learn(inputs={input:xor_inputs['stimuli'],
>>>                      backprop_pathway.target:xor_inputs['targets']},
>>>              num_trials=1,
>>>              animate={'show_learning':True})

Input Formats¶

  • Examples of Input Dictionary Specifications

  • Examples of Programmatic Input Specification

Examples of Input Dictionary Specifications¶

The following is an example in which the inputs argument of the run method is specified as an input dictionary, with entries for the two INPUT Nodes of the Composition:

>>> 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', pathways=[patway1, 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)

Since the specification of the default_variable for Mechanism a is a single array of length 2, it is constructed with a single InputPort (see InputPorts) that takes an array of that shape as its input; therefore, the input value specified for each TRIAL is a length 2 array ([1.0, 1.0]). In contrast, since the default_variable for Mechanism b is two length 1 arrays, so it is constructed with two InputPorts, each of which takes a length 1 array as its input; therefore, the input specified for each TRIAL must be two length 1 arrays. See figure for an illustration of the format for an input dictionary.

Note

A Node's external_input_variables attribute is always a 2d list in which the index i element is the variable of the i’th element of the Node’s external_input_ports attribute. For Mechanisms, the external_input_variables is often the same as its variable. However, some Mechanisms may have InputPorts marked as internal_only which are excluded from its external_input_ports and therefore its external_input_variables, and so should not receive an input value. The same considerations extend to the external_input_ports_of_all_input_nodes and external_input_variables of a Composition, based on the Mechanisms and/or nested Compositions that comprise its INPUT Nodes.

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 is not specified, the Composition executes five times., and num_trials = 7, the Composition 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 InputPort

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 InputPort:

>>> 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 InputPort’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)

Examples of Programmatic Input Specification¶

[EXAMPLES TO BE ADDED]

Cycles and Feedback¶

[EXAMPLES TO BE ADDED]

Runtime Parameters¶

If a runtime parameter is meant to be used throughout the Run, then the Condition may be omitted and the Always() Condition will be assigned by default:

>>> import psyneulink as pnl
>>> T = pnl.TransferMechanism()
>>> C = pnl.Composition(pathways=[T])
>>> T.function.slope  # slope starts out at 1.0
1.0
>>> # During the following run, 10.0 will be used as the slope
>>> C.run(inputs={T: 2.0},
...       runtime_params={T: {"slope": 10.0}})
[array([20.])]
>>> T.function.slope  # After the run, T.slope resets to 1.0
1.0

Otherwise, the runtime parameter value will be used on all executions of the Run during which the Condition is True:

>>> T = pnl.TransferMechanism()
>>> C = pnl.Composition(pathways=[T])
>>> T.function.intercept     # intercept starts out at 0.0
0.0
>>> T.function.slope         # slope starts out at 1.0
1.0
>>> C.run(inputs={T: 2.0},
...       runtime_params={T: {"intercept": (5.0, pnl.AfterTrial(1)),
...                           "slope": (2.0, pnl.AtTrial(3))}},
...       num_trials=5)
[array([7.])]
>>> C.results
[[array([2.])], [array([2.])], [array([7.])], [array([9.])], [array([7.])]]

The table below shows how runtime parameters were applied to the intercept and slope parameters of Mechanism T in the example above.

Trial 0

Trial 1

Trial 2

Trial 3

Trial 4

Intercept

0.0

0.0

5.0

5.0

5.0

Slope

1.0

1.0

1.0

2.0

0.0

Value

2.0

2.0

7.0

9.0

7.0

as indicated by the results of S.run(), the original parameter values were used on trials 0 and 1, the runtime intercept was used on trials 2, 3, and 4, and the runtime slope was used on trial 3.

Note

Runtime parameter values are subject to the same type, value, and shape requirements as the original parameter value.

Execution Contexts¶

An execution context is a scope of execution which has its own set of values for Components and their parameters. This is designed to prevent computations from interfering with each other, when Components are reused, which often occurs when using multiple or nested Compositions, or running simulations. Each execution context is or is associated with an execution_id, which is often a user-readable string. An execution_id can be specified in a call to Composition.run, or left unspecified, in which case the Composition’s default execution_id would be used. When looking for values after a run, it’s important to know the execution context you are interested in, as shown below.

>>> import psyneulink as pnl
>>> c = pnl.Composition()
>>> d = pnl.Composition()
>>> t = pnl.TransferMechanism()
>>> c.add_node(t)
>>> d.add_node(t)

>>> t.execute(1)
array([[1.]])
>>> c.run({t: 5})
[[array([5.])]]
>>> d.run({t: 10})
[[array([10.])]]
>>> c.run({t: 20}, context='custom execution id')
[[array([20.])]]

# context None
>>> print(t.parameters.value.get())
[[1.]]
>>> print(t.parameters.value.get(c))
[[5.]]
>>> print(t.parameters.value.get(d))
[[10.]]
>>> print(t.parameters.value.get('custom execution id'))
[[20.]]Composition_Controller

Reset Paramters of Stateful Functions¶

Example composition with two Mechanisms containing stateful functions:

>>> A = TransferMechanism(
>>>     name='A',
>>>     integrator_mode=True,
>>>     integration_rate=0.5
>>> )
>>> B = TransferMechanism(
>>>     name='B',
>>>     integrator_mode=True,
>>>     integration_rate=0.5
>>> )
>>> C = TransferMechanism(name='C')
>>>
>>> comp = Composition(
>>>     pathways=[[A, C], [B, C]]
>>> )

Example 1) A blanket reset of all stateful functions to their default values:

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     num_trials=3
>>> )
>>>
>>> # Trial 1: 0.5, Trial 2: 0.75, Trial 3: 0.875
>>> print(A.value)
>>> # [[0.875]]
>>>
>>> comp.reset()
>>>
>>> # The Mechanisms' stateful functions are now in their default states, which is identical
>>> # to their states prior to Trial 1. Thus, if we call run again with the same inputs,
>>> # we see the same results that we saw on Trial 1.
>>>
>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>> )
>>>
>>> # Trial 3: 0.5
>>> print(A.value)
>>> # [[0.5]]

Example 2) A blanket reset of all stateful functions to custom values:

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     num_trials=3
>>> )
>>>
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875
>>> print(A.value)
>>> # [[0.875]]
>>> # Mechanism B is currently identical to Mechanism A
>>> print(B.value)
>>> # [[0.875]]
>>>
>>> # Reset Mechanism A to 0.5 and Mechanism B to 0.75, corresponding to their values at the end of
>>> # trials 0 and 1, respectively. Thus, if we call run again with the same inputs, the values of the
>>> # Mechanisms will match their values after trials 1 and 2, respectively.
>>> comp.reset({A: 0.5,
>>>             B: 0.75})
>>>
>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>> )
>>>
>>> # Trial 3: 0.75
>>> print(A.value)
>>> # [[0.75]]
>>>
>>> # Trial 3: 0.875
>>> print(B.value)
>>> # [[0.875]]

Example 3) Schedule resets for both Mechanisms to their default values, to occur at different times

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     reset_stateful_functions_when = {
>>>         A: AtTrial(1),
>>>         B: AtTrial(2)
>>>     },
>>>     num_trials=5
>>> )
>>> # Mechanism A - resets to its default (0) at the beginning of Trial 1. Its value at the end of Trial 1 will
>>> # be exactly one step of integration forward from its default.
>>> # Trial 0: 0.5, Trial 1: 0.5, Trial 2: 0.75, Trial 3: 0.875, Trial 4: 0.9375
>>> print(A.value)
>>> # [[0.9375]]
>>>
>>> # Mechanism B - resets to its default (0) at the beginning of Trial 2. Its value at the end of Trial 2 will
>>> # be exactly one step of integration forward from its default.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.5, Trial 3: 0.75. Trial 4: 0.875
>>> print(B.value)
>>> # [[0.875]]

Example 4) Schedule resets for both Mechanisms to custom values, to occur at different times

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     reset_stateful_functions_when={
>>>         A: AtTrial(3),
>>>         B: AtTrial(4)
>>>     },
>>>     reset_stateful_functions_to={
>>>         A: 0.5,
>>>         B: 0.5
>>>     },
>>>     num_trials=5
>>> )
>>> # Mechanism A - resets to 0.5 at the beginning of Trial 3. Its value at the end of Trial 3 will
>>> # be exactly one step of integration forward from 0.5.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875, Trial 3: 0.75, Trial 4:  0.875
>>> print(A.value)
>>> # [[0.875]]
>>>
>>> # Mechanism B - resets to 0.5 at the beginning of Trial 4. Its value at the end of Trial 4 will
>>> # be exactly one step of integration forward from 0.5.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875, Trial 3: 0.9375. Trial 4: 0.75
>>> print(B.value)
>>> # [[0.75]]

Class Reference¶

class psyneulink.core.compositions.composition.Composition(pathways=None, nodes=None, projections=None, allow_probes=True, include_probes_in_output=False, disable_learning=False, controller=None, enable_controller=None, controller_mode='after', controller_time_scale=TimeScale.ENVIRONMENT_STATE_UPDATE, controller_condition=<psyneulink.core.scheduling.condition.Always object>, retain_old_simulation_data=None, show_graph_attributes=None, name=None, prefs=None, termination_processing=None, **param_defaults)¶

Base class for Composition.

Parameters
  • pathways (Pathway specification or list[Pathway specification...]) –

    specifies one or more Pathways to add to the Compositions. A list containing Node and possible Projection specifications at its top level is treated as a single Pathway; a list containing any nested lists or other forms of Pathway specification is treated as multiple pathways (see pathways as well as Pathway specification for additional details).

    The design pattern for use of sets and lists in specifying the pathways argument are:
    • sets comprise Nodes that all occupy the same (parallel) position within a processing Pathway;

    • lists comprise sequences of Nodes; embedded list are either ignored or a generate an error (see below) (this is because lists of Nodes are interpreted as Pathways and Pathways cannot be nested, which would be redundant since the same can be accomplished by simply including the items “inline” within a single list)

    • if the Pathway specification contains (in its outer list):
      • only a single item or set of items, each is treated as a SINGLETON <NodeRole.SINGLETON> in a Pathway;

      • one or more lists, the items in each list are treated as separate (parallel) pathways;

      • singly-nested lists ([[[A,B]],[[C,D]]]}), they are collapsed and treated as a Pathway;

      • any list with more than one list nested within it ([[[A,B],[C,D]}), an error is generated;

      • Pathway objects are treated as a list (if its pathway attribute is a set, it is wrapped in a list)

    (see tests for examples)

  • nodes (Mechanism, Composition or list[Mechanism, Composition] : default None) – specifies one or more Nodes to add to the Composition; these are each treated as SINGLETONs unless they are explicitly assigned Projections.

  • projections (Projection or list[Projection] : default None) – specifies one or more Projections to add to the Composition; these are not functional unless they are explicitly assigned a sender and receiver.

  • allow_probes (bool : default True) – specifies whether Projections are allowed from Nodes of a nested Composition other than its OUTPUT <NodeRole.OUTPUT>` Nodes to Nodes in outer Composition(s) (see allow_probes for additional information).

  • include_probes_in_output (bool : default False) – specifies whether the outputs of PROBE Nodes within a nested Composition are included in the output_values and results of the Composition to which they project If False, the outputs of PROBE Nodes are excluded from those attributes; if True (the default) they are included (see Probes for additional details).

  • disable_learning (bool : default False) – specifies whether LearningMechanisms in the Composition are executed when run in learning mode.

  • controller (OptimizationControlMechanism : default None) – specifies the OptimizationControlMechanism to use as the Composition's controller.

  • enable_controller (bool : default None) – specifies whether the Composition’s controller is executed when the Composition is run. Set to True by default if controller specified (see enable_controller for additional details).

  • controller_mode (enum.Enum[BEFORE|AFTER] : default AFTER) – specifies whether the controller is executed before or after the rest of the Composition when it is run, at the TimeScale specified by controller_time_scale). Must be either the keyword BEFORE or AFTER (see controller_mode for additional details).

  • controller_time_scale (TimeScale[TIME_STEP, PASS, TRIAL, RUN] : default TRIAL) – specifies the frequency at which the controller is executed, either before or after the Composition is run as specified by controller_mode (see controller_time_scale for additional details).

  • controller_condition (Condition : default Always()) – specifies a specific Condition for whether the Composition’s controller is executed in a trial (see controller_condition for additional details).

  • retain_old_simulation_data (bool : default False) – specifies whether or not to retain Parameter values generated during simulations of the Composition (see retain_old_simulation_data for additional details).

  • show_graph_attributes (dict : None) – specifies features of how the Composition is displayed when its show_graph method is called or animate is specified in a call to its run method (see ShowGraph for list of attributes and their values).

  • 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¶

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

Type

Graph

nodes¶

a list of all Nodes in the Composition.

Type

ContentAddressableList[Mechanism or Composition]

node_ordering¶

a list of all Nodes in the order in which they were added to the Composition.

Type

list[Mechanism or Composition]

allow_probes¶

indicates whether Projections are allowed to Nodes in the Composition from ones of a nested Composition other than its OUTPUT <NodeRole.OUTPUT>` Nodes. If allow_probes is False, Projections can be received from only the OUTPUT Nodes of a nested Composition; if it is True (the default), Projections can be received from any Nodes of a nested Composition, including its INPUT and INTERNAL Nodes; if it is assigned CONTROL, then only the Composition’s controller or its objective_mechanism can receive Projections from such Nodes. Any Nodes of a nested Composition that project to an enclosing Composition, other than its OUTPUT Nodes, are assigned PROBE in addition to their other roles (see Probes for additional information).

Type

bool or CONTROL

include_probes_in_output¶

determines whether the outputs of PROBE Nodes within a nested Composition are included in the output_values and results of the Composition to which they project. If False, the outputs of PROBE Nodes are excluded from those attributes; if True (the default) they are included (see Probes for additional details).

Type

bool : default False

required_node_roles¶

a list of tuples, each containing a Node and a NodeRole assigned to it.

Type

list[(Mechanism or Composition, NodeRole)]

excluded_node_roles¶

a list of tuples, each containing a Node and a NodeRole that is excluded from being assigned to it.

Type

list[(Mechanism or Composition, NodeRole)]

feedback_senders¶

list of Nodes that have one or more efferent Projections designated as feedback.

Type

ContentAddressableList[Node]

feedback_receivers¶

list of Nodes that have one or more afferents designated as feedback.

Type

ContentAddressableList[Node]

feedback_projections¶

list of Projections in the Composition designated as feedback.

Type

ContentAddressableList[Projection]

mechanisms¶

list of Mechanisms in Composition, that provides access to some of they key attributes.

Type

MechanismList

random_variables¶

list of Components in Composition with variables that call a randomization function.

These are Components with a seed Parameter.

Type

list[Component]

pathways¶

a list of all Pathways in the Composition that were specified in the pathways argument of the Composition’s constructor and/or one of its Pathway addition methods; each item is a list of Nodes (Mechanisms and/or Compositions) intercolated with the Projection(s) between each pair of Nodes; if both Nodes are Mechanisms, then only a single Projection can be specified; if either is a Composition then, under some circumstances, there can be a set of Projections, specifying how the INPUT Node(s) of the sender project to the OUTPUT Node(s) of the receiver (see add_linear_processing_pathway for additional details).

Type

ContentAddressableList[Pathway]

projections¶

a list of all of the Projections activated for the Composition; this includes all of the Projections among Nodes within the Composition, as well as from its input_CIM to it INPUT Nodes;from its parameter_CIM to the corresponding ParameterPorts; from its OUTPUT Nodes to its output_CIM; and, if it is nested in another Composition, then the Projections to its input_CIM and from its output_CIM to other Nodes in the Comopsition within which it is nested.

Type

ContentAddressableList[Projection]

input_CIM¶

mediates input values for the INPUT Nodes of the Composition. If the Composition is nested, then the input_CIM and its InputPorts (see input_CIM for additional details).

Type

CompositionInterfaceMechanism

input_CIM_ports¶

a dictionary in which the key of each entry is the InputPort of an INPUT Node in the Composition, and its value is a list containing two items:

  • the InputPort of the input_CIM that receives the input destined for that INPUT Node – either from the input specified for the Node in a call to one of the Composition’s execution methods, or from a MappingProjection from a Node in an enclosing Composition that has specified the INPUT Node as its receiver;

  • the OutputPort of the input_CIM that sends a MappingProjection to the InputPort of the INPUT Node.

Type

dict

parameter_CIM¶

mediates modulatory values for all Nodes of the Composition. If the Composition is nested, then the parameter_CIM and its InputPorts serve as proxies for the Composition itself for its afferent ModulatoryProjections (see parameter_CIM for additional details).

Type

CompositionInterfaceMechanism

parameter_CIM_ports¶

a dictionary in which keys are ParameterPorts of Nodes in the Composition, and values are lists containing two items:

  • the InputPort of the parameter_CIM that receives a MappingProjection from a ModulatorySignal of a ModulatoryMechanism in the enclosing Composition;

  • the OutputPort of the parameter_CIM that sends a ModulatoryProjection to the ParameterPort of the Node in the Composition with the parameter to be modulated.

Type

dict

afferents¶

a list of all of the Projections to either the Composition’s input_CIM (PathwayProjections and ModulatoryProjections).

Type

ContentAddressableList[Projection]

external_input_ports¶

a list of the InputPorts of the Composition’s input_CIM; these receive input provided to the Composition when it is executed, either from the inputs argument of one of its execution methods or, if it is a nested Composition, then from any Nodes in the outer composition that project to the nested Composition (either itself, as a Node in the outer Composition, or to any of its own Nodes).

Type

list[InputPort]

external_input_ports_of_all_input_nodes¶

a list of all external InputPort of all INPUT Nodes of the Composition, including any that in nested Compositions within it (i.e., within INPUT Nodes at all levels of nesting). Note that the InputPorts listed are those of the actual Mechanisms projected to by the ones listed in external_input_ports.

Type

list[InputPort]

external_input_shape¶

a list of the input_shapes of all of the InputPorts listed in external_input_ports (and are the same as the shapes of those listed in external_input_ports_of_all_input_nodes); any input to the Composition must be compatible with these, whether received from the inputs argument of one of the Composition’s execution methods or, if it is a nested Composition, from the enclosing Composition.

Type

list[1d array]

external_input_variables¶

a list of the variables associated with the InputPorts listed in external_input_ports.

Type

list[2d array]

external_input_values¶

a list of the values of associated of the InputPorts listed in external_input_ports.

Type

list[1d array]

external_input_values¶

a list of the values of associated with the InputPorts listed in external_input_ports.

Type

list[InputPort]

output_CIM¶

aggregates output values from the OUTPUT nodes of the Composition. If the Composition is nested, then the output_CIM and its OutputPorts serve as proxies for Composition itself in terms of efferent projections (see output_CIM for additional details).

Type

CompositionInterfaceMechanism

output_CIM_ports¶

a dictionary in which the key of each entry is the OutputPort of an OUTPUT Node in the Composition, and its value is a list containing two items:

  • the InputPort of the output_CIM that receives a MappingProjection from the OutputPort of the OUTPUT Node;

  • the OutputPort of the output_CIM that is either recorded in the results attrribute of the Composition, or sends a MappingProjection to a Node in the enclosing Composition that has specified the OUTPUT Node as its sender.

Type

dict

efferents¶

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

Type

ContentAddressableList[Projection]

cims¶

a list containing references to the Composition’s input_CIM, parameter_CIM, and output_CIM (see CompositionInterfaceMechanisms for additional details).

Type

list

env¶

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

Type

Gym Forager Environment : default: None

shadows¶

a dictionary in which the keys are all Nodes in the Composition, and the values of each is a list of any Nodes that shadow it’s input.

Type

dict

controller¶

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

Type

OptimizationControlMechanism

enable_controller¶

determines whether the Composition’s controller is executed when the Composition is run. Set to True by default if controller is specified. Setting it to False suppresses exectuion of the controller (see Controller Execution for additional details, including timing of execution).

Type

bool

controller_mode¶

determines whether the controller is executed before or after the rest of the Composition when it is run, at the TimeScale determined by controller_time_scale (see Controller Execution for additional details).

Type

BEFORE or AFTER

controller_time_scale¶

deterines the frequency at which the controller is executed, either before or after the Composition as determined by controller_mode (see Controller Execution for additional details).

Type

TimeScale[TIME_STEP, PASS, TRIAL, RUN] : default TRIAL

controller_condition¶

determines whether the controller is executed in a given trial. The default is Always(), which executes the controller on every trial (see Controller Execution for additional details).

Type

Condition

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¶

stores all execution_ids used by the Composition.

Type

set

disable_learning¶

determines whether LearningMechanisms in the Composition are executed when run in learning mode.

Type

bool : default False

learning_components¶

a list of 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.

Type

list[list]

learned_components¶

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.

Type

list[list]

results¶

a list of the output_values of the OUTPUT Nodes in the Composition for every TRIAL executed in a call to run. Each item in the outermos list is a list of values for a given trial; each item within a trial corresponds to the output_values of an OUTPUT Mechanism for that trial.

Type

list[list[list]]

output_values¶

a list of the output_values of the OUTPUT Nodes in the Composition for the last TRIAL executed in a call to one of the Composition’s execution methods, and the value returned by that method; this is the same as results[0], and provides consistency of access to the values of a Composition’s Nodes when one or more is a nested Composition.

Type

list[list]

simulation_results¶

a list of the results for simulations of the Composition when it is executed using its evaluate method by an OptimizationControlMechanism.

Type

list[list[list]]

retain_old_simulation_data¶

if True, all Parameter values generated during simulations are saved; if False, simulation values are deleted unless otherwise specified by individual Parameters.

Type

bool

recorded_reports¶

contains output and/or progress reports from execution(s) of Composition if RECORD is specified in the report_to_devices argument of a Composition execution method.

Type

str

rich_diverted_reports¶

contains output and/or progress reports from execution(s) of Composition if DIVERT is specified in the report_to_devices argument of a Composition execution method.

Type

str

input_specification¶

stores the inputs for executions of the Composition when it is executed using its run method.

Type

None or dict or list or generator or function

name¶

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).

Type

str

prefs¶

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 Preferences for details).

Type

PreferenceSet or specification dict

class _CompilationData(owner, parent=None)¶
property 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.

property scheduler¶

A default Scheduler automatically generated by the Composition, and used for its execution when it is run.

Getter

Returns the default scheduler, and builds it if it needs updating since the last access.

_analyze_graph(context=None)¶

Assigns NodeRoles to nodes based on the structure of the Graph.

By default, if _analyze_graph determines that a Node is ORIGIN, it is also given the role INPUT. Similarly, if _analyze_graph determines that a Node is TERMINAL, it is also given the role OUTPUT.

However, if the required_roles argument of add_node is used to set any Node in the Composition to INPUT, then the ORIGIN nodes are not set to INPUT by default. If the required_roles argument of add_node is used to set any Node in the Composition to OUTPUT, then the TERMINAL nodes are not set to OUTPUT by default.

_update_processing_graph()¶

Constructs the processing graph (the graph that contains only Nodes as vertices) from the composition’s full graph

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

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

Parameters
  • node (Mechanism 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, context=None)¶

Add a list of Nodes to the Composition.

Parameters
  • nodes (list) – the nodes to be added to the Composition. Each item of the list must be a Mechanism, 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_required_node_role(node, role, context=None)¶

Assign the NodeRole specified by role to node. Remove exclusion of that NodeRole if it had previously been specified in exclude_node_roles.

Parameters
  • node (Node) – Node to which role should be assigned.

  • role (NodeRole) – NodeRole to assign to node.

require_node_roles(node, roles, context=None)¶

Assign the NodeRole(s) specified in roles to node. Remove exclusion of those NodeRoles if it any had previously been specified in exclude_node_roles.

Parameters
  • node (Node) – Node to which role should be assigned.

  • roles (NodeRole or list[NodeRole]) – NodeRole(s) to assign to node.

exclude_node_roles(node, roles, context)¶

Excludes the NodeRole(s) specified in roles from being assigned to node.

Removes specified roles if they had been previous assigned either by default as a required_node_role or using the required_node_roles method.

Parameters
  • node (Node) – Node from which role should be removed.

  • roles (NodeRole or list[NodeRole]) – NodeRole(s) to remove and/or exclude from node.

get_roles_by_node(node)¶

Return a list of NodeRoles assigned to node.

Parameters

node (Node) – Node for which assigned NodeRoles are desired.

Returns

list of NodeRoles assigned to node.

Return type

List[Mechanisms and/or Compositions]

get_nodes_by_role(role)¶

Return a list of Nodes in the Composition that are assigned the NodeRole specified in role.

Parameters

role (NodeRole) – role for which Nodes are desired.

Returns

list of Nodes assigned the NodeRole specified in role

Return type

list[Mechanisms and/or Compositions]

_get_nested_nodes_with_same_roles_at_all_levels(comp, include_roles, exclude_roles=None)¶

Return all Nodes from nested Compositions that have include_roles but not exclude_roles at all levels. Note: need to do this recursively, checking roles on the “way down,” since a Node may have a role in a

deeply nested Composition, but that Composition itself may not have the same role in the Composition within which it is nested (e.g., a Node might be an INPUT Node of a nested Composition, but that nested Composition may not be an INPUT Node of the Composition in which it is nested).

_get_input_nodes_by_CIM_input_order()¶

Return a list with the INPUT Nodes of the Composition in the same order as their corresponding InputPorts on Composition’s input_CIM.

_get_input_receivers(comp=None, type='Port', comp_as_node=False)¶

Return all INPUT Nodes [or their InputPorts] of comp, [including those for any nested Compositions]. If type is PORT, return all InputPorts for all INPUT Nodes, including for nested Compositions. If type is NODE, return all INPUT Nodes, including for nested Compositions as determined by comp_as_node:

if an INPUT Node is a Composition, and comp_as_node is: - False, include the nested Composition’s INPUT Nodes, but not the Composition - True, include the nested Composition but not its INPUT Nodes - ALL, include the nested Composition AND its INPUT Nodes

_get_external_cim_input_port(port, outer_comp=None)¶

Get input_CIM.input_port of outer(most) Composition that projects to port in nested Composition. port must be an InputPort that receives a single path_afferent Projection from an input_CIM. Search up nesting hierarchy to find the input_CIM of comp nested in outer_comp or of the outermost Composition. Return tuple with:

input_CIM.input_port of the input_CIM of comp nested in outer_comp or of the outermost Composition input_CIM.output_port corresponding to input_CIM.input_port (for ease of tracking Node to which it projects)

_get_nested_nodes(nested_nodes=NotImplemented, root_composition=NotImplemented, visited_compositions=NotImplemented)¶
Recursively search and return all nodes of all nested Compositions

in a tuple with Composition in which they are nested.

:return

A list of tuples in format (node, composition) containing all nodes of all nested compositions.

_handle_allow_probes_for_control(node)¶

Reconcile allow_probes for Composition and any ControlMechanisms assigned to it, including controller.

_get_nested_compositions(nested_compositions=NotImplemented, visited_compositions=NotImplemented)¶

Recursively search for and return all nested compositions.

:return

A list of nested compositions.

_get_all_nodes()¶

Return all nodes, including those within nested Compositions at any level Note: this is distinct from the _all_nodes property, which returns all nodes at the top level

_is_in_composition(component, nested=True)¶

Return True if component is in Composition, including any nested Compositions if nested is True Include input_CIM and output_CIM for self and all nested Compositions

_determine_origin_and_terminal_nodes_from_consideration_queue()¶

Assigns NodeRole.ORIGIN to all nodes in the first entry of the consideration queue and NodeRole.TERMINAL to all nodes in the last entry of the consideration queue. The ObjectiveMechanism of a Composition’s controller may not be NodeRole.TERMINAL, so if the ObjectiveMechanism is the only node in the last entry of the consideration queue, then the second-to-last entry is NodeRole.TERMINAL instead.

_add_node_aux_components(node, context=None)¶

Add aux_components of node to Composition.

Returns

Return type

list containing references to all invalid aux components

_get_invalid_aux_components(node)¶

Return any Components in aux_components for a node that references items not (yet) in this Composition

_complete_init_of_partially_initialized_nodes(context=None)¶
Attempt to complete initialization of aux_components for any nodes with

aux_components that were not previously compatible with Composition

_determine_node_roles(context=None)¶

Assign NodeRoles to Nodes in Composition

Note

Assignments are not subject to user-modification (i.e., “programmatic assignment”) unless otherwise noted.

Assignment criteria:

ORIGIN:
  • all Nodes that are in first consideration_set (i.e., self.scheduler.consideration_queue[0]).

INPUT:
  • all ORIGIN Nodes for which INPUT has not been removed and/or excluded using exclude_node_roles();

  • all Nodes for which INPUT has been assigned as a required_node_role by user (i.e., in self.required_node_roles[NodeRole.INPUT].

SINGLETON:
  • all Nodes that are both ORIGIN and TERMINAL

INTERNAL:
  • all Nodes that are neither ORIGIN nor TERMINAL

CYCLE:
  • all Nodes that identified as being in a cycle by self.graph_processing (i.e., in self.graph_processing.cycle_vertices)

FEEDBACK_SENDER:
  • all Nodes that send a Projection designated as feedback by self.graph_processing OR specified as feedback by user

FEEDBACK_RECEIVER:
  • all Nodes that receive a Projection designated as feedback by self.graph_processing OR specified as feedback by user

CONTROL_OBJECTIVE
  • ObjectiveMechanism assigned CONTROL_OBJECTIVE as a required_node_role in ControlMechanism’s _instantiate_objective_mechanism()

Note

  • not the same as CONTROLLER_OBJECTIVE

  • all project to a ControlMechanism

CONTROLLER_OBJECTIVE
  • ObjectiveMechanism assigned CONTROLLER_OBJECTIVE as a required_node_role in add_controller()

Note

  • also assigned CONTROL_OBJECTIVE

  • not the same as CONTROL_OBJECTIVE

LEARNING
  • all Nodes for which LEARNING is assigned as a required_noded_role in add_linear_learning_pathway() or _create_terminal_backprop_learning_components()

TARGET
  • all Nodes for which TARGET has been assigned as a required_noded_role in add_linear_learning_pathway() or _create_terminal_backprop_learning_components()

Note

  • receive a Projection from input_CIM, and project to LEARNING_OBJECTIVE and output_CIM

  • also assigned ORIGIN, INPUT, LEARNING, OUTPUT, and TERMINAL

LEARNING_OBJECTIVE
  • all Nodes for which LEARNING_OBJECTIVE is assigned required_noded_role in add_linear_learning_pathway(), _create_non_terminal_backprop_learning_components, or _create_terminal_backprop_learning_components()

Note

  • also assigned LEARNING

  • must project to a LearningMechanism

OUTPUT:
  • all TERMINAL Nodes unless they are: - a ModulatoryMechanism (i.e., ControlMechanism or LearningMechanism) - an ObjectiveMechanisms associated with ModulatoryMechanism

  • all Nodes that project only to: - a ModulatoryMechanism - an ObjectiveMechanism designated CONTROL_OBJECTIVE, CONTROLLER_OBJECTIVE or LEARNING_OBJECTIVE ? unless it is the ??TARGET_MECHANISM for a ‘learning pathway <Composition_Learning_Pathway>`

    this is currently the case, but is inconsistent with the analog in Control, where monitored Mechanisms are allowed to be OUTPUT; therefore, might be worth allowing TARGET_MECHANISM to be assigned as OUTPUT

  • all Nodes for which OUTPUT has been assigned as a required_node_role, inclUding by user (i.e., in self.required_node_roles[NodeRole.OUTPUT]

TERMINAL:
  • all Nodes that - are not an ObjectiveMechanism assigned the role CONTROLLER_OBJECTIVE - or have no efferent projections OR - or for which any efferent projections are either:

    • to output_CIM OR

    • assigned as feedback (i.e., self.graph.comp_to_vertex[efferent].feedback == EdgeType.FEEDBACK

_get_external_modulatory_projections()¶
Returns

list of Modulatory Projections that originate from enclosing Compositions and that modulate a parameter of a Node of the current Composition

Return type

list[Modulatory Projections]

_create_CIM_ports(context=None)¶
  • remove the default InputPort and OutputPort from the CIMs if this is the first time that real InputPorts and OutputPorts are being added to the CIMs

  • create a corresponding InputPort and OutputPort on the input_CIM for each InputPort of each INPUT node. Connect the OutputPort on the input_CIM to the INPUT node’s corresponding InputPort via a standard MappingProjection.

  • create a corresponding InputPort and OutputPort on the output_CIM for each OutputPort of each OUTPUT node. Connect the OUTPUT node’s OutputPort to the output_CIM’s corresponding InputPort via a standard MappingProjection.

  • create a corresponding InputPort and ControlSignal on the parameter_CIM for each InputPort of each node in the Composition that receives a modulatory projection from an enclosing Composition. Connect the original ControlSignal to the parameter_CIM’s corresponding InputPort via a standard MappingProjection, then activate the projections that are created automatically during instantiation of the ControlSignals to carry that signal to the target ParameterPort.

  • build three dictionaries:

    1. input_CIM_ports = { INPUT Node InputPort: (InputCIM InputPort, InputCIM OutputPort) }

    2. output_CIM_ports = { OUTPUT Node OutputPort: (OutputCIM InputPort, OutputCIM OutputPort) }

    3. parameter_CIM_ports = { ( Signal Owner, Signal Receiver ): (ParameterCIM InputPort, ParameterCIM OutputPort) }

  • if the Node has any shadows, create the appropriate projections as needed.

  • delete all of the above for any node Ports which were previously, but are no longer, classified as INPUT/OUTPUT

_get_nested_node_CIM_port(node, node_port, role)¶

Check for node in nested Composition Assign NodeRole.PROBE to relevant nodes if allow_probes is specified (see handle_probes below) Return relevant port of relevant CIM if found and nested Composition in which it was found; else None’s

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_projection(projection=None, sender=None, receiver=None, default_matrix=None, feedback=False, learning_projection=False, name=None, allow_duplicates=False, context=None)¶

Add projection to the Composition.

If projection is not specified, and one does not already exist between sender and receiver create a default MappingProjection between them, using default_projection_matrix if specified (otherwise default for MappingProjection is used).

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

    • if 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 Composition, 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 and the request is ignored.

Duplicates are determined by the Ports to which they project, not the Mechanisms (to allow multiple Projections to exist between the same pair of Mechanisms using different Ports). .. If an already instantiated Projection is passed to add_projection and is a duplicate of an existing one, it is detected and suppressed, with a warning, in Port._instantiate_projections_to_port. .. If a Projection with deferred_init status is a duplicate, it is fully suppressed here, as these are generated by add_linear_processing_pathway if the pathway overlaps with an existing one, and so warnings are unnecessary and would be confusing to users.

Parameters
  • projection (Projection, list, array, matrix, RandomMatrix, MATRIX_KEYWORD) – the projection to add.

  • sender (Mechanism, Composition, or OutputPort) – the sender of projection.

  • receiver (Mechanism, Composition, or InputPort) – the receiver of projection.

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – matrix to use in creating default; overrides default for MappingProjection.

  • default_projection_matrix – specifies matrix to use in creating default Projection if none is specifed in projection and one does not already exist between sender and receive (see Specifying the Matrix Parameter for details of specification).

  • feedback (bool or FEEDBACK : False) – if False, the Projection is never designated as a feedback Projection, even if that may have been the default behavior (e.g., for a ControlProjection that forms a loop; if True or FEEDBACK, and the Projection is in a loop, it is always designated as a feedback Projection, and used to break" the cycle.

Returns

Projection if added, else None

Return type

Projection

_update_shadow_projections(context=None)¶

Instantiate any missing shadow_projections that have been specified in Composition

_check_for_projection_assignments(context=None)¶

Check that all Projections and Ports with require_projection_in_composition attribute are configured. Validate that all InputPorts with require_projection_in_composition == True have an afferent Projection. Validate that all OutputPorts with require_projection_in_composition == True have an efferent Projection. Validate that all Projections have senders and receivers. Issue warning if any Projections are to/from nodes not in Composition.projections

_check_for_unused_projections(context)¶

Warn if there are any Nodes in the Composition, or any nested within it, that are not used.

get_feedback_status(projection)¶

Return True if projection is designated as a feedback Projection in the Composition, else False.

_check_for_existing_projections(projection=None, sender=None, receiver=None, in_composition=True)¶

Check for Projection with same sender and receiver If in_composition is True, return only Projections found in the current Composition If in_composition is False, return only Projections that are found outside the current Composition

Return Projection or list of Projections that satisfies the conditions, else False

_check_for_unnecessary_feedback_projections()¶

Warn if there exist projections in the graph that the user labeled as EdgeType.FEEDBACK (True) but are not in a cycle

_get_source(projection)¶

Return tuple with port, node and comp of sender for projection (possibly in a nested Composition).

_get_destination(projection)¶

Return tuple with port, node and comp of receiver for projection (possibly in a nested Composition).

add_pathway(pathway)¶

Add an existing Pathway to the Composition

Parameters

pathway (the Pathway to be added) –

add_pathways(pathways, context=None)¶

Add pathways to the Composition.

Parameters

pathways (Pathway or list[Pathway]) – specifies one or more Pathways to add to the Composition. Any valid form of Pathway specification can be used. A set can also be used, all elements of which are Nodes, in which case a separate Pathway is constructed for each.

Returns

List of Pathways added to the Composition.

Return type

list[Pathway]

add_linear_processing_pathway(pathway, default_projection_matrix=None, name=None, context=None, *args)¶

Add sequence of Nodes with optionally intercolated Projections.

A Pathway is specified as a list, each element of which is either a Node or set of Nodes, possibly intercolated with specifications of Projections between them. The Node(s) specified in each entry of the list project to the Node(s) specified in the next entry (see Pathway Specification for details).

Note

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

Parameters
  • pathway (Node, list or Pathway) – specifies the Nodes, and optionally Projections, used to construct a processing Pathway. Any standard form of Pathway specification can be used, however if a 2-item (Pathway, LearningFunction) tuple is used, the LearningFunction is ignored (this should be used with add_linear_learning_pathway if a learning Pathway is desired). A Pathway object can also be used; again, however, any learning-related specifications are ignored, as are its name if the name argument of add_linear_processing_pathway is specified.

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – specifies matrix to use for any unspecified Projections (overrides default matrix for MappingProjection) if a default projection is not otherwise specified (see Pathway Projection Specifications; see Specifying the Matrix Parameter for details of specification)

  • name (str) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

Pathway added to Composition.

Return type

Pathway

add_linear_learning_pathway(pathway, learning_function, loss_function=None, learning_rate=0.05, error_function=<class 'psyneulink.core.components.functions.nonstateful.combinationfunctions.LinearCombination'>, learning_update='after', default_projection_matrix=None, name=None, context=None)¶

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 is a custom 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 a more detailed description of how learning is implemented in a Composition, including the learning components that are created, as well as other learning methods that can be used to implement specific algorithms.

The learning components created are placed in a dict the following entries:

OUTPUT_MECHANISM: ProcessingMechanism (assigned to output TARGET_MECHANISM: ProcessingMechanism (assigned to target OBJECTIVE_MECHANISM: ComparatorMechanism (assigned to learning_objective LEARNING_MECHANISMS: LearningMechanism or list[LearningMechanism] LEARNING_FUNCTION: LearningFunction used by all LEARNING_MECHSNISMS in the Pathway LEARNED_PROJECTIONS: Projection or list[Projections]

that is assigned to the learning_components attribute of the Pathway returned.

Parameters
  • pathway (List or Pathway) – specifies the learning Pathway for which the Projections will be learned; can be specified as a Pathway or as a list of Nodes and, optionally, Projections between them (see list).

  • learning_function (LearningFunction) – specifies the type of LearningFunction to use for the LearningMechanism constructued for each MappingProjection in the pathway.

  • loss_function (Loss : default Loss.MSE) – specifies the loss function used if BackPropagation is specified as the learning_function (see add_backpropagation_learning_pathway).

  • learning_rate (float : default 0.05) – specifies the learning_rate used for the learning_function of the LearningMechanism 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).

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – specifies matrix to use for any unspecified Projections (overrides default matrix for MappingProjection) if a default projection is not otherwise specified (see Pathway Projection Specifications; see Specifying the Matrix Parameter for details of specification)

  • name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

learning Pathway <Composition_Learning_Pathway>` added to the Composition.

Return type

Pathway

add_reinforcement_learning_pathway(pathway, learning_rate=0.05, error_function=None, learning_update='online', default_projection_matrix=None, name=None)¶

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.

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – specifies matrix to use for any unspecified Projections (overrides default matrix for MappingProjection) if a default projection is not otherwise specified (see Pathway Projection Specifications; see Specifying the Matrix Parameter for details of specification)

  • learning_rate (float : default 0.05) – specifies the learning_rate used for the ReinforcementLearning function of the LearningMechanism 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).

  • name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

Reinforcement learning Pathway <Composition_Learning_Pathway>` added to the Composition.

Return type

Pathway

add_td_learning_pathway(pathway, learning_rate=0.05, error_function=None, learning_update='online', default_projection_matrix=None, name=None)¶

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 LearningMechanism 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).

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – specifies matrix to use for any unspecified Projections (overrides default matrix for MappingProjection) if a default projection is not otherwise specified (see Pathway Projection Specifications; see Specifying the Matrix Parameter for details of specification)

  • name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

TD Reinforcement learning Pathway <Composition_Learning_Pathway>` added to the Composition.

Return type

Pathway

add_backpropagation_learning_pathway(pathway, learning_rate=0.05, error_function=None, loss_function=Loss.MSE, learning_update='after', default_projection_matrix=None, name=None)¶

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

Parameters
  • pathway (List) – specifies nodes of the Pathway for the learning pathway (see add_linear_processing_pathway for details of specification). Any MappingProjections specified or constructed for the Pathway are assigned as learned_projections.

  • learning_rate (float : default 0.05) – specifies the learning_rate used for the Backpropagation function of the LearningMechanisms 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 (last) Mechanism in the pathway).

  • loss_function (Loss : default Loss.MSE) – specifies the loss function used in computing the error term; see Loss for values.

  • learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameters of the learned_projections are updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanisms in the pathway, and their LearningProjections (see learning_enabled for meaning of values).

  • default_projection_matrix (list, array, function, RandomMatrix or MATRIX_KEYWORD : default None) – specifies matrix to use for any unspecified Projections (overrides default matrix for MappingProjection) if a default projection is not otherwise specified (see Pathway Projection Specifications; see Specifying the Matrix Parameter for details of specification)

  • name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

BackPropagation learning Pathway <Composition_Learning_Pathway>` added to the Composition.

Return type

Pathway

_create_learning_related_mechanisms(input_source, output_source, error_function, learning_function, learned_projection, learning_rate, learning_update)¶

Creates TARGET_MECHANISM, ComparatorMechanism and LearningMechanism for RL and TD learning

_create_learning_related_projections(input_source, output_source, target, comparator, learning_mechanism)¶

Construct MappingProjections among learning components for pathway

_create_learning_projection(learning_mechanism, learned_projection)¶

Construct LearningProjections from LearningMechanisms to learned_projections in a learning pathway

infer_backpropagation_learning_pathways()¶

Convenience method that automatically creates backpropapagation learning pathways for every Input Node –> Output Node pathway

_create_terminal_backprop_learning_components(input_source, output_source, error_function, loss_function, learned_projection, learning_rate, learning_update, context)¶

Create ComparatorMechanism, LearningMechanism and LearningProjection for Component in learning Pathway

_get_back_prop_error_sources(receiver_activity_mech, learning_mech=None, context=None)¶

Add any LearningMechanisms associated with efferent projection from receiver_activity_mech

add_controller(controller, context=None)¶

Add a ControlMechanism as the controller of the Composition.

This gives the ControlMechanism access to the Composition’s evaluate method. This allows subclasses of ControlMechanism that can use this (such as OptimizationControlMechanism) to execute simulations of the Composition (that is, executions in an execution context separate from the one used by the execution method called by the user) to evaluate the influence of parameters on performance.

It also assigns a ControlSignal for any Parameters of a Mechanism specified for control, and a ControlProjection to its correponding ParameterPort.

The ControlMechanism is assigned the NodeRole CONTROLLER.

_instantiate_deferred_init_control(node, context=None)¶

If node is a Composition with a controller, activate its nodes’ deferred init control specs for its controller. If it does not have a controller, but self does, activate them for self’s controller.

If node is a Node that has deferred init control specs and self has a controller, activate the deferred init control specs for self’s controller.

Called recursively on nodes that are nested Compositions.

Returns

Return type

list of hanging control specs that were not able to be assigned for a controller at any level of nesting.

_get_monitor_for_control_nodes()¶

Return dict of {nodes : ControlMechanism that monitors it} for any nodes monitored for control in Composition

_get_control_signals_for_composition()¶

Return list of ControlSignals specified by Nodes in the Composition

Generate list of ControlSignal specifications from ParameterPorts of Mechanisms specified for control. The specifications can be:

ControlProjections (with deferred_init()) # FIX: 9/14/19 - THIS SHOULD ALREADY HAVE BEEN PARSED INTO ControlProjection WITH DEFFERRED_INIT: # OTHERWISE, NEED TO ADD HANDLING OF IT BELOW ControlSignals (e.g., in a 2-item tuple specification for the parameter); CONTROL keyword Note:

The initialization of the ControlProjection and, if specified, the ControlSignal are completed in the call to controller_instantiate_control_signal() in add_controller.

Mechanism can be in the Composition itself, or in a nested Composition that does not have its own controller.

_get_controller(comp=None, context=None)¶

Get controller for which the current Composition is an agent_rep. Recursively search enclosing Compositions for controller if self does not have one. Use context.composition if there is no controller. This is needed for agent_rep that is nested within the Composition to which the controller belongs.

_instantiate_control_projections(context)¶

Add any ControlProjections for control specified locally on nodes in Composition

_route_control_projection_through_intermediary_pcims(projection, sender, sender_mechanism, receiver, graph_receiver, context)¶

Takes as input a specification for a projection to a parameter port that is nested n-levels below its sender, instantiates and activates ports and projections on intermediary pcims, and returns a new projection specification from the original sender to the relevant input port of the pcim of the Composition located in the same level of nesting.

_check_controller_initialization_status(context=None)¶

Checks initialization status of controller (if applicable) all Projections or Ports in the Composition

evaluate(predicted_input=None, control_allocation=None, num_trials=1, runtime_params=None, base_context=<psyneulink.core.globals.context.Context object>, context=None, execution_mode=ExecutionMode.Python, return_results=False, block_simulate=False)¶

Run Composition and compute net_outcomes

Runs the Composition in simulation mode (i.e., excluding its controller) using the predicted_input (state_feature_values and specified control_allocation for each run. The Composition is run for *num_trials.

If predicted_input is not specified, and block_simulate is set to True, the controller attempts to use the entire input set provided to the run method of the Composition as input for the call to run. If it is not, the controller uses the inputs slated for its next or previous execution, depending on whether the controller_mode of the Composition is set to before or after, respectively.

Note

Block simulation can not be used if the Composition’s stimuli were specified as a generator. If block_simulate is set to True and the input type for the Composition was a generator, block simulation will be disabled for the current execution of evaluate.

The net_outcome for each run is calculated using the controller’s <ControlMechanism.compute_net_outcome>` function. Each run is executed independently, using the same predicted_inputs and control_allocation, and a randomly and independently sampled seed for the random number generator. All values are reset to pre-simulation values at the end of the simulation.

Returns the net_outcome of a run of the agent_rep. If return_results is True, an array with the results of each run is also returned.

_infer_target_nodes(targets)¶

Maps targets onto target mechanisms (as needed by learning)

Returns

Dict mapping TargetMechanisms -> target values

Return type

dict

_parse_learning_spec(inputs, targets)¶

Converts learning inputs and targets to a standardized form

Returns

  • dict – Dict mapping mechanisms to values (with TargetMechanisms inferred from output nodes if needed)

  • int – Number of input sets in dict for each input node in the Composition

_parse_generator_function(inputs)¶

Instantiates and parses generator from generator function

Returns

  • generator – Generator instance that will be used to yield inputs

  • int – a large int (sys.maxsize), used in place of the number of input sets, since it is impossible to determine a priori how many times a generator will yield

_parse_generator(inputs)¶
Returns

  • generator – Generator instance that will be used to yield inputs

  • int – a large int (sys.maxsize), used in place of the number of input sets, since it is impossible to determine a priori how many times a generator will yield

_parse_list(inputs)¶
Validates that conditions are met to use a list as input, i.e. that there is only one input node. If so, convert

list to input dict and parse

Returns

  • dict – Parsed and standardized input dict

  • int – Number of input sets in dict for each input node in the Composition

_parse_string(inputs)¶

Validate that conditions are met to use a string as input, i.e. that there is only one input node and that node’s default input port has a label matching the provided string. If so, convert the string to an input dict and parse.

Returns

  • dict – Parsed and standardized input dict

  • int – Number of input sets in dict for each input node in the Composition

_parse_function(inputs)¶
Returns

  • function – Function that will be used to yield inputs

  • int – Functions must always return 1 trial of input per call, so this always returns 1

_validate_single_input(receiver, input)¶

Validate a single input for a single receiver. If the input is specified without an outer list (i.e. Composition.run(inputs = [1, 1]) instead of

Composition.run(inputs = [[1], [1]]), add an extra dimension to the input

Returns

The input, with an added dimension if necessary, if the input is valid. None if the input is not valid.

Return type

None or np.ndarray or list

_parse_input_dict(inputs, context=None)¶
Validate and parse a dict provided as input to a Composition into a standardized form to be used throughout

its execution

Returns

  • dict – Parsed and standardized input dict

  • int – Number of input sets (i.e., trials’ worths of inputs) in dict for each input node in the Composition

_parse_labels(inputs, mech=None, port=None, context=None)¶

Traverse input dict and resolve any input or output labels to their numeric values If port is passed, inputs is only for a single port, so manage accordingly

Returns

The input dict, with inputs with labels replaced by corresponding numeric values

Return type

dict

_validate_input_dict_keys(inputs)¶

Validate that keys of inputs are all legal: - they are all InputPorts, Mechanisms or Compositions; - they are all (or InputPorts of) INPUT Nodes of Composition at any level of nesting; - an InputPort and the Mechanism to which it belongs are not both specified; - an InputPort of an input_CIM and the Composition to which it belongs are not both specified; - an InputPort or Mechanism and any Composition under which it is nested are not both specified.

_instantiate_input_dict(inputs)¶

Implement dict with all INPUT Node of Composition as keys and their assigned inputs or defaults as values inputs can contain specifications for inputs to InputPorts, Mechanisms and/or nested Compositions,

that can be at any level of nesting within self.

Consolidate any entries of inputs with InputPorts as keys to Mechanism or Composition entries If any INPUT Nodes of Composition are not included, add them to the input_dict using their default values. InputPort entries must specify either a single trial or the same number as all other InPorts for that Node:

  • preprocess InputPorts for a Node to determine maximum number of trials specified, and use to set mech_shape

  • if more than one trial is specified for any InputPort, assign fillers to ones that specify only one trial

(this does not apply to Mechanism or Composition specifications, as they are tested in validate_input_shapes)

Return input_dict, with added entries for any INPUT Nodes or InputPorts for which input was not provided

_flatten_nested_dicts(inputs)¶
Converts inputs provided in the form of a dict for a nested Composition to a list corresponding to the

Composition’s input CIM ports

Returns

The input dict, with nested dicts corresponding to nested Compositions converted to lists

Return type

dict

_validate_input_shapes(inputs)¶

Validates that all inputs provided in input dict are valid

Returns

The input dict, with shapes corrected if necessary.

Return type

dict

_parse_run_inputs(inputs, context=None)¶

Takes user-provided input for entire run and parses it according to its type

Returns

  • Parsed input dict

  • The number of inputs sets included in the input

_parse_trial_inputs(inputs, trial_num)¶

Extracts inputs for a single trial and parses it in accordance with its type

Returns

Input dict parsed for a single trial of a Composition’s execution

Return type

dict

_validate_execution_inputs(inputs)¶

Validates and returns the formatted input dict for a single execution

Returns

Input dict parsed for a single trial of a Composition’s execution

Return type

dict

run(inputs=None, num_trials=None, initialize_cycle_values=None, reset_stateful_functions_to=None, reset_stateful_functions_when=<psyneulink.core.scheduling.condition.Never object>, skip_initialization=False, clamp_input='soft_clamp', runtime_params=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, termination_processing=None, skip_analyze_graph=False, report_output=ReportOutput.OFF, report_params=ReportParams.OFF, report_progress=ReportProgress.OFF, report_simulations=ReportSimulations.OFF, report_to_devices=None, animate=False, log=False, scheduler=None, scheduling_mode=None, execution_mode=ExecutionMode.Python, default_absolute_time_unit=None, 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 Executing a Composition for details of formatting input specifications.

Use get_input_format method to see example of input format.

Use animate to generate a gif of the execution sequence.

inputs: Dict{INPUT Nodelist}, function or generatordefault None specifies

the inputs to each INPUT Node of the Composition in each TRIAL executed during the run (see Composition Inputs for additional information about format, and get_input_format method for generating an example of the input format for the Composition). If inputs is not specified, the default_variable for each INPUT Node is used as its input on TRIAL.

num_trialsintdefault 1

typically, the composition will infer the number of trials from the length of its input specification. To reuse the same inputs across many trials, an input dictionary can be specified with lists of length 1, or use default inputs, and select a number of trials with num_trials.

initialize_cycle_valuesDict { Node: Node Value }default None

sets the value of specified Nodes before the start of the run. All specified Nodes must be in a cycle (i.e., designated with with NodeRole CYCLE; otherwise, a warning is issued and the specification is ignored). If a Node in a cycle is not specified, it is assigned its default values when initialized (see Cycles and Feedback additional details).

reset_stateful_functions_toDict { NodeObject | iterable [Object] }default None

object or iterable of objects to be passed as arguments to nodes’ reset methods when their respective reset_stateful_function_when conditions are met. These are used to seed the stateful attributes of Mechanisms that have stateful functions. If a node’s reset_stateful_function_when condition is set to Never, but they are listed in the reset_stateful_functions_to dict, then they will be reset once at the beginning of the run, using the provided values. For a more in depth explanation of this argument, see Resetting Parameters of stateful.

reset_stateful_functions_whenDict { Node: Condition } | Conditiondefault Never()

if type is dict, sets the reset_stateful_function_when attribute for each key Node to its corresponding value Condition. if type is Condition, sets the reset_stateful_function_when attribute for all nodes in the Composition that currently have their reset_stateful_function_when conditions set to Never. in either case, the specified Conditions persist only for the duration of the run, after which the nodes’ reset_stateful_functions_when attributes are returned to their previous Conditions. For a more in depth explanation of this argument, see Resetting Parameters of stateful.

skip_initialization : bool : default False

clamp_inputenum.Enum[SOFT_CLAMP|HARD_CLAMP|PULSE_CLAMP|NO_CLAMP]default SOFT_CLAMP

specifies how inputs are handled for the Composition’s INPUT Nodes.

runtime_paramsDict[Node: Dict[Parameter: Tuple(Value, Condition)]]default None

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 (see Runtime Parameters for additional informaton).

call_before_time_stepcallabledefault None

specifies fuction to call before each TIME_STEP is executed.

call_after_time_stepcallabledefault None

specifies fuction to call after each TIME_STEP is executed.

call_before_passcallabledefault None

specifies fuction to call before each PASS is executed.

call_after_passcallabledefault None

specifies fuction to call after each PASS is executed.

call_before_trialcallabledefault None

specifies fuction to call before each TRIAL is executed.

call_after_trialcallabledefault None

specifies fuction to call after each TRIAL is executed.

termination_processingConditiondefault None

specifies termination Conditions to be used for the current RUN. To change these conditions for all future runs, use Composition.termination_processing (or Scheduler.termination_conds)

skip_analyze_graphbooldefault False

setting to True suppresses call to _analyze_graph()

report_outputReportOutputdefault ReportOutput.OFF

specifies whether to show output of the Composition and its Nodes trial-by-trial as it is generated; see Output Reporting for additional details and ReportOutput for options.

report_paramsReportParamsdefault ReportParams.OFF

specifies whether to show values the Parameters of the Composition and its Nodes as part of the output report; see Output Reporting for additional details and ReportParams for options.

report_progressReportProgressdefault ReportProgress.OFF

specifies whether to report progress of execution in real time; see Progress Reporting for additional details.

report_simulationsReportSimulationsdefault ReportSimulatons.OFF

specifies whether to show output and/or progress for simulations executed by the Composition’s controller; see Simulations for additional details.

report_to_deviceslist(ReportDevices)default ReportDevices.CONSOLE

specifies where output and progress should be reported; see Report_To_Devices for additional details and ReportDevices for options.

animatedict or booldefault False

specifies use of the show_graph method to generate a gif movie showing the sequence of Components executed in a run (see example). A dict can be specified containing options to pass to the show_graph method in order to customize the display of the graph in the animation. Each key of the dict 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. See Animation for additional information.

  • 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.

logbool or LogConditiondefault False

Sets the log_condition for every primary node and projection in the 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.

schedulerSchedulerdefault None

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.

scheduling_modeSchedulingMode[STANDARD|EXACT_TIME]default None

if specified, sets the scheduling mode for the current and all future runs of the Composition. See Execution

execution_modebool or ExecutionModedefault ExecutionMode.Python

specifies whether to run using the Python interpreter or a compiled mode. False uses the Python interpreter; True tries LLVM compilation modes, in order of power, progressively reverting to less powerful modes (in the order of the options listed), and to Python if no compilation mode succeeds; see ExecutionMode for other options, and Compilation Modes for a more detailed explanation of their operation.

default_absolute_time_unitpint.Quantity1ms

if not otherwise determined by any absolute conditions, specifies the absolute duration of a TIME_STEP. See Scheduler.default_absolute_time_unit

contextexecution_iddefault default_execution_id

context in which the Composition will be executed; set to self.default_execution_id ifunspecified.

base_contextexecution_idContext(execution_id=None)

the context corresponding to the execution context from which this execution will be initialized, if values currently do not exist for context

2d list of values of OUTPUT Nodes at end of last triallist[list]

each item in the list is the output_values for an OUTPUT Node of the Composition, listed in the order listed in get_nodes_by_role(NodeRole.OUTPUT).

Note

The results attribute of the Composition contains a list of the outputs for all trials.

learn(inputs, targets=None, num_trials=None, epochs=1, learning_rate=None, minibatch_size=1, patience=None, min_delta=0, context=None, execution_mode=ExecutionMode.Python, randomize_minibatches=False, call_before_minibatch=None, call_after_minibatch=None, *args, **kwargs)¶

Runs the composition in learning mode - that is, any components with disable_learning False will be executed in learning mode. See Learning in a Composition for details.

Parameters
  • inputs ({Node:list }) –

    a dictionary containing a key-value pair for each Node (Mechanism or Composition) in the composition that receives inputs from the user. There are several equally valid ways that this dict can be structured:

    1. For each pair, the key is the and the value is an input, the shape of which must match the Node’s default variable. This is identical to the input dict in the run method (see Input Dictionary for additional details).

    2. A dict with keys ‘inputs’, ‘targets’, and ‘epochs’. The inputs key stores a dict that is the same same structure as input specification (1) of learn. The targets and epochs keys should contain values of the same shape as targets and epochs.

  • targets ({Node:list }) – a dictionary containing a key-value pair for each Node in the Composition that receives target values as input to the Composition for training learning pathways. The key of each entry can be either the TARGET_MECHANISM for a learning pathway or the final Node in that Pathway, and the value is the target value used for that Node on each trial (see target inputs for additional details concerning the formatting of targets).

  • num_trials (int (default=None)) – typically, the Composition infers the number of trials to execute from the length of its input specification. However, num_trials can be used to enforce an exact number of trials to execute; if it is greater than there are inputs then inputs will be repeated (see Composition Inputs for additional information).

  • epochs (int (default=1)) – specifies the number of training epochs (that is, repetitions of the batched input set) to run with

  • learning_rate (float : default None) – specifies the learning_rate used by all learning pathways when the Composition’s learn method is called. This overrides the `learning_rate specified for any individual Pathways at construction, but only applies for the current execution of the learn method.

  • minibatch_size (int (default=1)) – specifies the size of the minibatches to use. The input trials will be batched and run, after which learning mechanisms with learning mode TRIAL will update weights

  • randomize_minibatch (bool (default=False)) – specifies whether the order of the input trials should be randomized on each epoch

  • patience (int or None (default=None)) – used for early stopping of training; If a model has more than patience bad consecutive epochs, then learn will prematurely return. A bad epoch is determined by the min_delta value

  • min_delta (float (default=0)) – the minimum reduction in average loss that an epoch must provide in order to qualify as a ‘good’ epoch; Any reduction less than this value is considered to be a bad epoch. Used for early stopping of training, in combination with patience.

  • 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 (Optional[optional]) – context will be set to self.default_execution_id if unspecified

  • call_before_minibatch (callable) – called before each minibatch is executed

  • call_after_minibatch (callable) – called after each minibatch is executed

  • report_output (ReportOutput : default ReportOutput.OFF) – specifies whether to show output of the Composition and its Nodes trial-by-trial as it is generated; see Output Reporting for additional details and ReportOutput for options.

  • report_params (ReportParams : default ReportParams.OFF) – specifies whether to show values the Parameters of the Composition and its Nodes as part of the output report; see Output Reporting for additional details and ReportParams for options.

  • report_progress (ReportProgress : default ReportProgress.OFF) – specifies whether to report progress of execution in real time; see Progress Reporting for additional details.

  • report_simulations (ReportSimulatons : default ReportSimulations.OFF) – specifies whether to show output and/or progress for simulations executed by the Composition’s controller; see Simulations for additional details.

  • report_to_devices (list(ReportDevices) : default ReportDevices.CONSOLE) – specifies where output and progress should be reported; see Report_To_Device for additional details and ReportDevices for options.

Returns

the results of the final epoch of training

Return type

list

execute(inputs=None, scheduler=None, termination_processing=None, call_before_time_step=None, call_before_pass=None, call_after_time_step=None, call_after_pass=None, reset_stateful_functions_to=None, context=None, base_context=<psyneulink.core.globals.context.Context object>, clamp_input='soft_clamp', runtime_params=None, skip_initialization=False, execution_mode=ExecutionMode.Python, report_output=ReportOutput.OFF, report_params=ReportParams.OFF, report_progress=ReportProgress.OFF, report_simulations=ReportSimulations.OFF, report_to_devices=None, report=None, report_num=None)¶

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 ({ Node: list } : default None) – 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 (a Mechanism or Composition) and the value is an input, the shape of which must match the Node’s default variable. If inputs is not specified, the default_variable for each INPUT Node is used as its input (see Input Formats for additional details).

  • clamp_input (SOFT_CLAMP : default SOFT_CLAMP) –

  • runtime_params (Dict[Node: Dict[Parameter: Tuple(Value, Condition)]] : default None) – specifies alternate parameter values to be used only during this EXECUTION when the specified Condition is met (see Runtime Parameters for more details and examples of valid dictionaries).

  • skip_initialization (: default False) –

  • scheduler (Scheduler : default None) – 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 (execution_id : default default_execution_id) – execution context in which the Composition will be executed.

  • base_context (execution_id : Context(execution_id=None)) – 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 : default None) – 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 : default None) – 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 : default None) – called before each PASS is executed passed the current context (but it is not necessary for your callable to take).

  • call_after_pass (callable : default None) – called after each PASS is executed passed the current context (but it is not necessary for your callable to take).

  • execution_mode (enum.Enum[Auto|LLVM|LLVMexec|Python|PTXExec] : default Python) – specifies whether to run using the Python interpreter or a compiled mode. see execution_mode argument of run method for additional details.

  • report_output (ReportOutput : default ReportOutput.OFF) – specifies whether to show output of the Composition and its Nodes for the execution; see Output Reporting for additional details and ReportOutput for options.

  • report_params (ReportParams : default ReportParams.OFF) – specifies whether to show values the Parameters of the Composition and its Nodes for the execution; see Output Reporting for additional details and ReportParams for options.

  • report_progress (ReportProgress : default ReportProgress.OFF) – specifies whether to report progress of the execution; see Progress Reporting for additional details.

  • report_simulations (ReportSimulations : default ReportSimulations.OFF) – specifies whether to show output and/or progress for simulations executed by the Composition’s controller; see Simulations for additional details.

  • report_to_devices (list(ReportDevices) : default ReportDevices.CONSOLE) – specifies where output and progress should be reported; see Report_To_Devices for additional details and ReportDevices for options.

Returns

  • output_values (List)

  • These are the values of the Composition’s output_CIM.output_ports, excluding those the source of which

  • are from a (potentially nested) Node with NodeRole.PROBE in its enclosing Composition.

get_input_format(form='dict', num_trials=1, use_labels=False, use_names=False, show_nested_input_nodes=False, alias=None)¶

Return dict or string with format of dict used by inputs argument of run method.

Parameters
  • form (DICT or TEXT : default DICT) – specifies the form in which the exampple is returned; DICT (the default) returns a dict (with num_trials worth of default values for each INPUT Node) formatted for use as the inputs arg of the Compositon’s run method; TEXT returns a user-readable text description of the format (optionally with inputs required for INPUT Nodes of any nested Compositions (see show_nested_input_nodes below).

  • num_trials (int or FULL : default 1) – specifies number of trials’ worth of inputs to include in returned item. If FULL is specified, use_labels is automatically set to True, and num_trials is set to number of labels in the input_label_dict with the largest number of labels specified; if none of the INPUT Mechanisms in the Composition (including any nested ones) have an input_label_dict specified, num_trials is set to the default (1).

  • use_labels (bool : default False) –

    if True, shows labels instead of values for Mechanisms that have an input_label_dict. For num_trials = 1, a representative label is shown; for num_trials > 1, a different label is used for each trial shown, cycling through the set if num_trials is greater than the number of labels. If **num_trials = FULL, trials will be included.

    it is set to the number of labels in the largest list specified in any input_label_dict specified for an INPUT Mechanism;

  • use_names (bool : default False) – use Node name as key for Node if form = DICT.

  • show_nested_input_nodes (bool : default False) – show hierarchical display of Nodes in nested Compositions with names of destination INPUT Nodes and representative inputs, followed by the actual format used for the run method.

Returns

  • Either a dict formatted appropriately for assignment as the inputs argument of the Composition’s `run()

  • method (form = *DICT, the default), or string showing the format required by the inputs argument*

  • <Composition.run>` (form = TEXT).

get_results_by_nodes(nodes=None, use_names=False, use_labels=False, alias=None)¶

Return ordered dict with origin Node and current value of each item in results.

Note

Items are listed in the order of their values in the Composition’s results attribute, irrespective of the order in which they appear in the nodes argument if specified.

Parameters
  • nodes (List[Mechanism or str], Mechanism or str : default None) – specifies Nodes for which to report the value; can be a reference to a Mechanism, its name, or a list of either or both. If None (the default), the values of all OUTPUT Nodes are reported.

  • use_names (bool : default False) – specifies whether to use the names of Nodes rather than references to them as keys.

  • use_labels (bool : default False) – specifies whether to use labels to report the values of Nodes for Mechanisms Mechanism that have an output_labels_dict attribute.

Returns

Node output_values – dict , the keys of which are either Mechanisms or the names of them, and values are their output_values.

Return type

Dict[Mechanism:value]

reset(values=None, include_unspecified_nodes=True, context=NotImplemented)¶

If the component’s execute method involves execution of an IntegratorFunction Function, this method effectively begins the function’s accumulation over again at the specified value, and may update related values on the component, depending on the component type. Otherwise, it simply reassigns the Component’s value based on its default_variable.

initialize(values=None, include_unspecified_nodes=True, context=None)¶

Initializes the values of nodes within cycles. If include_unspecified_nodes is True and a value is provided for a given node, the node will be initialized to that value. If include_unspecified_nodes is True and a value is not provided, the node will be initialized to its default value. If include_unspecified_nodes is False, then all nodes must have corresponding initialization values. The DEFAULT keyword can be used in lieu of a numerical value to reset a node’s value to its default.

If a context is not provided, the most recent context under which the Composition has executed will be used.

Parameters
  • values (Dict { Node: Node Value }) – A dictionary contaning key-value pairs of Nodes and initialization values. Nodes within cycles that are not included in this dict will be initialized to their default values.

  • include_unspecified_nodes (bool) – Specifies whether all nodes within cycles should be initialized or only ones specified in the provided values dictionary.

  • context (Context) – The context under which the nodes should be initialized. context will be set to self.most_recent_execution_context if one is not specified.

disable_all_history()¶

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

_is_learning(context)¶

Returns true if the composition can learn in the given context

_build_variable_for_input_CIM(inputs)¶

Assign values from input dictionary to the InputPorts of the Input CIM, then execute the Input CIM

_assign_execution_ids(context=None)¶

assigns the same execution id to each Node in the composition’s processing graph as well as the CIMs. he execution id is either specified in the user’s call to run(), or from the Composition’s default_execution_id

_parse_runtime_params_conditions(runtime_params)¶

Validate runtime_params and assign Always() for any params that don’t have a Condition already specified. Recursively process subdicts (Port- or Project-specific dictionaries of params).

_get_satisfied_runtime_param_values(runtime_params, scheduler, context)¶

Return dict with values for all runtime_params the Conditions of which are currently satisfied. Recursively parse nested dictionaries for which Condition on dict is satisfied.

as_mdf_model(simple_edge_format=True)¶

Creates a ModECI MDF Model representing this Composition

Parameters
  • simple_edge_format (bool, optional) – If True, Projections

  • True. (with non-identity matrices are constructed as . Defaults to) –

Returns

a ModECI Model representing this Composition

Return type

modeci_mdf.Model

property input_ports¶

Return all InputPorts that belong to the Input CompositionInterfaceMechanism

property input_port¶

Return the index 0 InputPort that belongs to the Input CompositionInterfaceMechanism

property input_values¶

Return values of all InputPorts that belong to the Input CompositionInterfaceMechanism

property output_port¶

Return the index 0 OutputPort that belongs to the Output CompositionInterfaceMechanism

property output_ports¶

Return all OutputPorts that belong to the Output CompositionInterfaceMechanism

property output_values¶

Return values of all OutputPorts that belong to the Output CompositionInterfaceMechanism in the most recently executed context

property shadowing_dict¶

Return dict with shadowing ports as the keys and the ports they shadow as values.

property external_input_shape¶

Alias for _default_external_input_shape

property _default_external_input_shape¶

Return default_input_shape of all external InputPorts that belong to Input CompositionInterfaceMechanism

property external_input_variables¶

Return variables of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property default_external_input_variables¶

Return default variables of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property external_input_values¶

Return values of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property default_external_input_values¶

Return the default values of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property stateful_nodes¶

List of all nodes in the Composition 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 `Composition`

Return type

List[Node]

property stateful_parameters¶

A list of all of this object’s parameters whose values may change during runtime

property random_variables¶

Return list of Components with seed Parameters (i.e., ones that that call a random function).

property _dependent_components¶

Returns a set of Components that will be executed if this Component is executed

make_likelihood_function(*args, **kwargs)¶

This method invokes make_likelihood_function() on the composition.

class psyneulink.core.compositions.composition.NodeRole(value)¶

Roles assigned to Nodes of a Composition.

ORIGIN¶

A Node that does not receive any Projections from any other Nodes within its own Composition, though if it is in a nested Composition it may receive Projections from the outer Composition. Execution of a `Composition always begins with an ORIGIN Node. A Composition may have many ORIGIN Nodes. This role cannot be modified programmatically.

INPUT¶

A Node that receives input from outside its Composition, either from the Composition’s run method or, if it is in a nested Composition, from the outer Composition. By default, the ORIGIN Nodes of a Composition are also its INPUT Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have many INPUT Nodes. Note that any Node that shadows an INPUT Node is itself also assigned the role of INPUT Node.

PROBE¶

A Node that is neither ORIGIN nor TERMINAL but that is treated as an

SINGLETON¶

A Node that is both an ORIGIN and a TERMINAL. This role cannot be modified programmatically.

INTERNAL¶

A Node that is neither INPUT nor OUTPUT. Note that it can also be ORIGIN, TERMINAL or SINGLETON, if it has no afferent or efferent Projections or neither, respectively. This role cannot be modified programmatically.

CYCLE¶

A Node that belongs to a cycle. This role cannot be modified programmatically.

FEEDBACK_SENDER¶

A Node with one or more efferent Projections designated as feedback in the Composition. This means that the Node executes last in the sequence of Nodes that would otherwise form a cycle. This role cannot be modified directly, but is modified if the feedback status` of the Projection is explicitly specified.

FEEDBACK_RECEIVER¶

A Node with one or more afferent Projections designated as feedback in the Composition. This means that the Node executes first in the sequence of Nodes that would otherwise form a cycle. This role cannot be modified directly, but is modified if the feedback status` of the Projection is explicitly specified.

CONTROL_OBJECTIVE¶

A Node that is an ObjectiveMechanism associated with a ControlMechanism other than the Composition’s controller (if it has one).

CONTROLLER¶

A Node that is the controller of a Composition. This role cannot be modified programmatically.

CONTROLLER_OBJECTIVE¶

A Node that is an ObjectiveMechanism associated with a Composition’s controller.

LEARNING¶

A Node that is only executed when learning is enabled; if it is not also assigned TARGET or LEARNING_OBJECTIVE, then it is a LearningMechanism. This role can, but generally should not be modified programmatically.

TARGET¶

A Node that receives the target for a learning pathway specifying the desired output of the OUTPUT_MECHANISM for that pathway (see TARGET_MECHANISM). This role can, but generally should not be modified programmatically.

LEARNING_OBJECTIVE¶

A Node that is the ObjectiveMechanism of a learning Pathway; usually a ComparatorMechanism (see OBJECTIVE_MECHANISM). This role can, but generally should not be modified programmatically.

PROBE¶

An INTERNAL Node that is permitted to have Projections from it to the Composition’s output_CIM, but – unlike an OUTPUT Node – the output_values of which are not included in the Composition’s results attribute (see allow_probes for an example.

OUTPUT¶

A Node the output_values of which are included in the Composition’s results attribute. By default, the TERMINAL Nodes of a Composition are also its OUTPUT Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have many OUTPUT Nodes.

TERMINAL¶

A Node that does not send any Projections to any other Nodes within its own Composition, though if it is in a nested Composition it may send Projections to the outer Composition. A Composition may have many TERMINAL Nodes. The ObjectiveMechanism associated with the Composition’s controller (assigned the role CONTROLLER_OBJECTIVE) cannot be a TERMINAL Node of a Composition. Execution of a Composition itself always ends with a TERMINAL Node, although the controller and its associated ObjectiveMechanism may execute after that; some TERMINAL Nodes may also execute earlier (i.e., if they belong to a Pathway that is shorter than the longest one in the Composition). This role cannot be modified programmatically.

class psyneulink.core.compositions.composition.Graph¶

A Graph of vertices and edges.

comp_to_vertex¶

maps Component in the graph to the Vertices that represent them.

Type

Dict[Component : Vertex]

vertices¶

the Vertices contained in this Graph; each can be a Node or a Projection.

Type

List[Vertex]

dependency_dict¶

maps each of the graph’s Components to the others from which it receives input (i.e., their value). For a Node, this is one or more Projections; for a Projection, it is a single Node.

Type

Dict[Component : Set(Component)]

copy()¶
Returns

  • A copy of the Graph. Vertices are distinct from their originals, and point to the same

  • `Component <Component>` object (Graph)

get_parents_from_component(component)¶
Parameters

component (Component) – the Component whose parents will be returned

Returns

list of the parent Vertices of the Vertex associated with component.

Return type

list[Vertex]

get_children_from_component(component)¶
Parameters

component (Component) – the Component whose children will be returned

Returns

list of the child Vertices of the Vertex associated with component.

Return type

list[Vertex]

prune_feedback_edges()¶

Produces an acyclic graph from this Graph. Feedback edges are pruned, as well as any edges that are potentially feedback that are in cycles. After these edges are removed, if cycles still remain, they are “flattened.” That is, each edge in the cycle is pruned, and each the dependencies of each Node in the cycle are set to the pre-flattened union of all cyclic nodes’ parents that are themselves not in a cycle.

Returns

a tuple containing - the acyclic dependency dictionary produced from this Graph - a dependency dictionary containing only the edges removed to create the acyclic graph - the unmodified cyclic dependency dictionary of this Graph


© Copyright 2016, Jonathan D. Cohen.

Built with Sphinx using a theme provided by Read the Docs.
  • Composition
    • Contents
    • Overview
    • Creating a Composition
      • Using the Constructor
      • Adding Components and Pathways
      • Adding Nested Compositions
    • Composition Structure
      • Graph
        • Acyclic and Cyclic Graphs
      • Nodes
      • Nested Compositions
      • CompositionInterfaceMechanisms
      • Projections
      • Pathways
    • Controlling a Composition
      • Assigning a Controller
      • Controller Execution
    • Learning in a Composition
      • Configuring Learning in a Composition
      • Learning Using PsyNeuLink Components
        • Unsupervised Learning
        • Supervised Learning
          • Supervised Learning Methods
          • Supervised Learning Pathways
          • Supervised Learning Components
          • Execution of Learning
      • Learning Using AutodiffCompositon
      • Learning Using UserDefinedFunctions
    • Executing a Composition
      • Composition Inputs
        • Input formats (including targets for learning)
          • Input Dictionary
          • Specifying Inputs Programmatically
      • Execution Factors
        • Runtime Parameters
        • Cycles and Feedback
          • Cycles and Synchronous Execution
          • Feedback and Sequential Execution
        • Execution Contexts
        • Timing
        • Resetting Stateful Parameters
        • Compilation
      • Results, Reporting and Logging
    • Visualizing a Composition
    • Composition Examples
      • Creating a Composition
      • Run Composition
      • Learning
      • Input Formats
        • Examples of Input Dictionary Specifications
        • Examples of Programmatic Input Specification
      • Cycles and Feedback
      • Runtime Parameters
      • Execution Contexts
      • Reset Paramters of Stateful Functions
    • Class Reference
  • Github