Composition¶
Contents¶
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¶
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 oradd_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 Projectionmatrices
.
- 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¶
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:
adds a Node to the Composition.
adds mutiple Nodes to the Composition.
adds a Projection between a pair of Nodes in the Composition.
adds Projections between multiple pairs of Nodes in the Composition.
These methods can be used to add Pathways to an existing Composition:
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.
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.
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.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¶
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
oradd_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.
The get_required_roles_by_node
method lists the NodeRoles
that have been assigned to a Node using the
require_node_roles
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 assignedPROBE
in addition to their otherroles
in the nested Composition. The only difference betweenPROBE
andOUTPUT
Nodes is whether their output is included in theoutput_values
andresults
attributes of the outermost Composition to which they project; this is determined by theinclude_probes_in_output
attribute of the latter. Ifinclude_probes_in_output
is False (the default), then the output of anyPROBE
Nodes are not included in theoutput_values
orresults
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 are not otherwise reported as part of the outermost Composition’s output or results. Ifinclude_probes_in_output
is True, then anyPROBE
Nodes of any nested Compositions are treated the same asOUTPUT
Nodes: their outputs are included in theoutput_values
andresults
of the outermost Composition.PROBE
Nodes can be visualized, along with any Projections treated differently from those ofOUTPUT
Nodes (i.e., wheninclude_probes_in_output
is False), using the Composition’sshow_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 aspart 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).
Note
A Node can be both a
PROBE
and anOUTPUT
Node of a nested Composition, if it has someoutput_ports
that project only to Nodes in the outer Composition (those are treated the same was as Projections from anOUTPUT
Node), as well as other(s) that project to Nodes both within the nested Composition and to the outer Composition (those are treated in the same way asPROBE
Nodes).
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 Supervised 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 everyINPUT
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 anINPUT
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 correspondingINPUT
Node of the Composition.
parameter_CIM
- this is assigned an InputPort and OutputPort for everyParameter
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 everyOUTPUT
Node of the Composition to which it belongs. Each InputPort receives input from anOUTPUT
Node of the Composition, and itsvalue
is assigned as thevalue
of a corresponding OutputPort. The latter are assigned to theoutput_values
andresults
attributes of the Composition. If the Composition is nested within another, then the output_CIM’soutput_ports
send Projections to Components of the Composition within which it is nested. If it is anOUTPUT
Node of the enclosing Composition, then its OutputPorts project theoutput_CIM
of the enclosing Composition, itsoutput_values
are included in those of the enclosing Composition. If the Composition has anPROBE
Nodes, then they too project to the Composition’s output_CIM. If the Composition is nested in another, then thevalues
of thePROBE
Nodes are also included in the Composition’soutput_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 itsoutput_values
andresults
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’sshow_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¶
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 by calling the Composition’s learn
method (see
Execution of Supervised Learning and Executing a Composition for additional details). The rate at which learning
occurs is determined by the learning_rate parameter, which can be assigned in various ways and is described under
Learning Rate at the end of this section.
Configuring Learning in a Composition¶
There are three ways of configuring learning in a Composition, using:
standard PsyNeuLink Components, for presentational and/or instructional purposes; supports both Supervised Learning and Unsupervised Learning, but executes slowly and does not support learning that spans nested compositions.
an AutodiffComposition, a subclass of Composition that executes learning substantially more efficiently, and supports learning that spans nested compositions, but is currently restricted to Supervised Learning.
UserDefinedFunctions, that provide full flexiblity.
Implementing learning using PsyNeuLink compoments is meant as a complement to more standard implementations of learning in neural networks, such as PyTorch or TensorFlow, that 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, which can be useful in instructional settings, where each computation associtated with learning can be individually examined. However, the cost is that execution is extremely inefficient (due to the lack of parallelization). To execute learning on a scale typical of standard deep learning applicatons, an AutodiffComposition should be used. This can executed using either direct compilation or by translating the model to, and execiting it using PyTorch. Both of these provide as much as three orders of magnitude acceleration (comparable to standard machine learning environments). Finally, for full flexiblity, learning can be impelmented using one or more UserDefinedFunctions, that can be assigned to PyTorch functions, or ones in any other Python environment that implements learning and accepts and returns tensors. Each of these approaches is described in more detail in the three sections that follow, and summarized in a table that compares their advantages and disadvantages.
Learning Using PsyNeuLink Components¶
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 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:
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 theOUTPUT_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’slearn
method, or in its targets argument in an entry for either the TARGET_MECHANISM or the OUTPUT_MECHANISM (see below); the Mechanism is assigned theNodeRoles
TARGET
andLEARNING
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 thematrix
parameter for the coresponding MappingProjection, along with a LearningSignal and LearningProjection that convey thelearning_signal
to the MappingProjection’s MATRIXParameterPort
; depending on learning method, additional MappingProjections may be created to and/or from the LearningMechanism – see Learning Configurations for details); these are assigned theNodeRole
LEARNING
in the Composition.
LEARNING_FUNCTION – the
LearningFunction
used by each of theLEARNING_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:
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
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 superseded 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
Execution of Supervised 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 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
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).
The Compositon’s learn
method takes all of the same arguments as its run
method, as well as additonal ones that are specific to learning. Also like run
, it returns the
output_values
of the Composition after the last trial of execution. The results for the
last epoch of learning are stored in its learning_results
attribute.
Learning Rate¶
The rate at which learning occurs in a learning pathway is determined by the
learning_rate Parameter of the LearningMechanism(s) in that
Pathway. If it is not specified, then the default value for the LearningMechanism’s function
is used, which is determined by the kind of learning in that Pathway. However, the
learning_rate can be specified in several other ways, both at construction and/or execution. At construction, it can
be specified using the learning_rate argument of the Compostion’s constructor, in which case it serves as the
default learning_rate for all learning pathways; it can also be specified in the learning_rate argument of a
learning construction method, in which case it applies to only the LearningMechanisms
in that Pathway. Specifications for a Pathway take precedence over the specification in the Composition’s constructor.
The learning_rate can also be specified at execution, in the Composition’s learn
method,
in which case it applies to all learning pathways during that (and only that) execution, and supersedes any
specifications made at construction. It can also be specified for one or more individual LearningMechanisms (which
applies to the matrix
parameter (“connection weights”) of the MappingProjection for
which each LearningMechanism is responsible), by assigning a value directly to the LearningMechanism’s learning_rate
Parameter. This supersedes any other specifications of learning_rate, including
in the Composition’s learn() method, and applies to all subsequent executions of learning, allowing different
LearningMechanisms (and their corresponding MappingProjections) within a Composition to be assigned different
learning_rates. The table below shows the precedence for the specificadtion of learning_rates.
Learning Rate Precedence Hierarchy |
|
Highest: |
|
|
|
|
|
|
|
Lowest: |
|
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 use any learning methods – in fact, they cannot be specified (see warning) – an AutodiffComposition automatically constructs all of the components
needed for learning While learning in an AutodiffComposition is currently 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, while
exploiting 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. Use of the PyTorch
mode also
supports learning of nested Compositions (see Nesting). However, there
are restrictions on the kinds of Compositions that be implemented in this way (see Only one OutputPort per Node).
The table below summarizes the different ways to implement and execute learning, and features specific to each;
these are described in more detail in AutodiffComposition.
The learning_rate
for an AutodiffComposition can be specified in its constructor
(which assigns it as the default) or in its learn
method, in which case it applies to
that execution only.
Note
Using
ExecutionMode.Python
in an AutodffComposition is the same as using a standard Composition, allowing an AutodffComposition to be run in any mode (e.g., for comparison and/or compatibility purposes).Warning
ExecutionMode.LLVM
andExecutionMode.PyTorch
can only be used in thelearn
method of an AutodiffComposition; specifying them in thelearn <Composition.learn>`()
method of a standard Composition causes an error.
Comparison of Learning Modes¶
Composition |
AutodiffComposition |
||
---|---|---|---|
Python |
LLVM mode (Direct Compilation) |
||
execution_mode= |
|||
Python interpreted Python interpreted |
LLVM compiled LLVM compiled |
PyTorch compiled Python interpreted |
|
Speed: |
slow |
fastest |
fast |
Supports: |
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¶
There are three methods for executing a Composition:
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 eitherrun
orlearn
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, thenlearn
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 TRIAL
s 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 TRIAL
s 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 TRIAL
s specified in num_trials has been executed. If num_trials is not specified,
then a number of TRIAL
s 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¶
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 TRIAL
s 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
byTRIAL
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 asinternal_only
(for example, theinput_port
for a RecurrentTransferMechanism, if itshas_recurrent_input_port
attribute is True), in which case no input should be specified for those input_ports. Similar considerations extend to theexternal_input_ports_of_all_input_nodes
of a nested Composition, based on the Mechanisms (and/or additionally nested Compositions) thatcomprise its set ofINPUT
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 TRIAL
s 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.
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 TRIAL
s 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 TRIAL
s (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 TRIAL
s,
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
.
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¶
In addition to the learning_rate, the values of other Parameter`s of a Composition's Mechanisms (including but not limited to its `LearningMechanism`s) 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, itsfunction
, 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¶
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, itssender
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 they 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 they 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 anexecution_id
is assigned to the context argument of the Mechanism’sexecute
method when it is called. This is because the first time a Mechanism is executed in a Composition, its initial value is copied from thevalue
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’srun
orlearn
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: in a tuple with the Projection specification (e.g. where it is specified
in a Pathway or in the monitor_for_control argument
of a ControlMechanism); in the Composition’s add_projections
method; by using the
feedback argument of the Composition’s add_projection
method; or in the constructor
of the Projection itself using its feedback argument. 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, but 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 theFEEDBACK_SENDER
's initial_value (the first time it is executed) or its previousvalue
(in subsequent executions), rather than its most recently computedvalue
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_SENDER
s of a Composition are listed in its feedback_senders
attribute,
and its FEEDBACK_RECEIVER
s 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 can be ascertained using the Composition’s 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’sget
method must be used:<Component>.parameters.<parameter_name>.get(execution_id)
, wherevalue
can be used as the parameter_name to retrieve the Component’svalue
, 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, callingobj._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 thereset
method of Nodes in the Composition that have a StatefulFunction, each of which resets the stateful parameters of those Functions. If it is called without any arguments, it calls thereset
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 described for reset_stateful_functions_when below).reset_stateful_functions_when and reset_stateful_functions_to – these are arguments of the Composition’s
run
andlearn
methods, that can be used to specify the Conditions under which thereset
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 torun
orlearn
, and thereset_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 withstateful
. If a single Condition is specified, it is applied to all of the Composition’s Nodes that havestateful
; 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’sreset
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 itsreset_stateful_function_when
attribute for the duration of the call torun
orlearn
.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 thereset
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 thereset
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 theprevious_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 TRIAL
s. 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 multipleTRIAL
s; if successful, the compiled binary is semantically equivalent to the execution of therun
method using the Python interpreter;
ExecutionMode.LLVMExec
– compile and run eachTRIAL
, using the Python interpreter to iterate over them; if successful, the compiled binary for eachTRIAL
is semantically equivalent the execution of theexecute
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’sscheduler
, execute each Node and iterate overTRIAL
s; 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: executeslearn
using
PyTorch
andrun
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 itslearn
method using PyTorch.
ExecutionMode.PTXrun
– compile multipleTRIAL
s 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 ExecutionMode.PTXRun
in 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 not explicitly disabled by
setting the PNL_LLVM_DEBUG
environment variable to nocuda
.
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¶
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¶
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’sexternal_input_ports
attribute. For Mechanisms, theexternal_input_variables
is often the same as itsvariable
. However, some Mechanisms may have InputPorts marked asinternal_only
which are excluded from itsexternal_input_ports
and therefore itsexternal_input_variables
, and so should not receive an input value. The same considerations extend to theexternal_input_ports_of_all_input_nodes
andexternal_input_variables
of a Composition, based on the Mechanisms and/or nested Compositions that comprise itsINPUT
Nodes.
If num_trials is not in use, the number of inputs provided determines the number of TRIAL
s 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 TRIAL
s 0 and 1 are used again on TRIAL
s 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:
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)
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
TRIAL
s
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)
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, learning_rate=None, minibatch_size=1, optimizations_per_minibatch=1, 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
SINGLETON
s 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
andreceiver
.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 theoutput_values
andresults
of the Composition to which they project If False, the outputs ofPROBE
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
.learning_rate (float or int : default None) – specifies the learning_rate to be used by LearningMechanisms in the Composition that do not have their own
learning_rate
otherwise specified (see Learning Rate for additional details).minibatch_size (int : default 1) – specifies the default for the Composition for the number of distinct inputs from the training set used to compute the
error_signal
in one step of learning; it can be overridden by specifying the minibatch_size argument in thelearn
method (seeminibatch_size
for additional details.optimizations_per_minibatch (int : default 1) – specifies the default for the Composition for the number of repetitions of each stimulus in the training set is used to compute the
error_signal
for a givenminibatch
; it can be overridden by specifying the minibatch_size argument in thelearn
method (seeoptimizations_per_minibatch
for additional details.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 (seeenable_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 theTimeScale
specified by controller_time_scale). Must be either the keyword BEFORE or AFTER (seecontroller_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 (seecontroller_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 (seecontroller_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 itsrun
method (seeShowGraph
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; seeprefs
for details.
- graph¶
the full
Graph
associated with the Composition. Contains both Nodes (Mechanisms or Compositions) and Projections.- Type
- 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 itsINPUT
andINTERNAL
Nodes; if it is assigned CONTROL, then only the Composition’scontroller
or itsobjective_mechanism
can receive Projections from such Nodes. Any Nodes of a nested Composition that project to an enclosing Composition, other than itsOUTPUT
Nodes, are assignedPROBE
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 theoutput_values
andresults
of the Composition to which they project. If False, the outputs ofPROBE
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 theOUTPUT
Node(s) of the receiver (seeadd_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 itsparameter_CIM
to the correspondingParameterPorts
; from its OUTPUT Nodes to itsoutput_CIM
; and, if it is nested in another Composition, then the Projections to itsinput_CIM
and from itsoutput_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 itsInputPorts
(see input_CIM for additional details).
- 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 thatINPUT
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 theINPUT
Node as itsreceiver
;the OutputPort of the
input_CIM
that sends a MappingProjection to the InputPort of theINPUT
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).
- 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., withinINPUT
Nodes at all levels of nesting). Note that the InputPorts listed are those of the actual Mechanisms projected to by the ones listed inexternal_input_ports
.- Type
list[InputPort]
- external_input_shape¶
a list of the
input_shape
s of all of the InputPorts listed inexternal_input_ports
(and are the same as the shapes of those listed inexternal_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
variable
s associated with the InputPorts listed inexternal_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).
- 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 theresults
attrribute of the Composition, or sends a MappingProjection to a Node in the enclosing Composition that has specified theOUTPUT
Node as itssender
.
- 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
, andoutput_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).
- enable_controller¶
determines whether the Composition’s
controller
is executed when the Composition is run. Set to True by default ifcontroller
is specified. Setting it to False suppresses exectuion of thecontroller
(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 theTimeScale
determined bycontroller_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 bycontroller_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 isAlways()
, which executes the controller on every trial (see Controller Execution for additional details).- Type
- 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_rate¶
if specified, used as the default value for the
learning_rate
of LearningMechanisms in the Composition that do not have their learning_rate otherwise specified; it is superseded by the learning_rate argument of a learning construction method, and can also be overriden by specifying the learning_rate argument in a call to thelearn
method of a Composition or direct specification of thelearning_rate
Parameter of a LearningMechanism (see Learning Rate for additional details).- Type
float or int
- minibatch_size¶
determines the number of input stimuli from the training set used to compute the
error_signal
in one gradient step of learning if this is not specified in the call tolearn
(seeminibatch
for additional details).- Type
int
- optimizations_per_minibatch¶
determines the number of repetitions of each stimulus in the training set used to compute an
error_signal
for single gradient step in learning if this is not specified in the call tolearn
(seeminibatch
for additional details).- Type
int
- 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 inlearning_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 theOUTPUT
Nodes in the Composition for everyTRIAL
executed in a call torun
. Each item in the outermost list is a list of values for a given trial; each item within a trial corresponds to theoutput_values
of anOUTPUT
Mechanism for that trial.- Type
list[list[list]]
- output_values¶
a list of the
output_values
of theOUTPUT
Nodes in the Composition for the lastTRIAL
executed in a call to one of the Composition’s execution methods, and the value returned by that method; this is the same asresults
[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]
- learning_results¶
a list of the
output_values
of theOUTPUT
Nodes in the Composition for everyTRIAL
of the last epoch of learning executed in a call tolearn
. Each item in the outermost list is a list of values for a given trial; each item within a trial corresponds to theoutput_values
of anOUTPUT
Mechanism for that trial.- Type
list[list[list]]
- simulation_results¶
a list of the
results
for simulations of the Composition when it is executed using itsevaluate
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 itsrun
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 usingclassPreferences
defined in __init__.py (see Preferences for details).- Type
PreferenceSet or specification dict
- class _CompilationData(owner, parent=None)¶
- assign_ShowGraph(show_graph_attributes)¶
Helper function to allow override of the ShowGraph class in subclasses (e.g., AutodiffComposition)
- 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 theGraph
.By default, if _analyze_graph determines that a Node is
ORIGIN
, it is also given the roleINPUT
. Similarly, if _analyze_graph determines that a Node isTERMINAL
, it is also given the roleOUTPUT
.However, if the required_roles argument of
add_node
is used to set any Node in the Composition toINPUT
, then theORIGIN
nodes are not set toINPUT
by default. If the required_roles argument ofadd_node
is used to set any Node in the Composition toOUTPUT
, then theTERMINAL
nodes are not set toOUTPUT
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.
- import_composition(composition, nodes='all', get_input_from=None, send_output_to=None, transfer_required_roles=True, transfer_excluded_roles=True, context=None)¶
Import a Composition into the current Composition.
- Parameters
composition (Composition) – the Composition to be imported into the current Composition.
nodes (list : default ALL) – the nodes to be imported from
composition
. Each item of the list must be a Mechanism. If ALL (the default), all nodes incomposition
will be imported.get_input_from (dict : default None) – mapping from Nodes (keys) in the current Composition to Nodes (values) in the Composition to be imported that will receive their input; this argument must be specified.
send_output_to (dict : default None) – mapping from Nodes (keys) in the Composition to be imported to Nodes (values) in the current Composition that will receive their output; this argument must be specified.
transfer_required_roles (bool : default True) – if True, the
required_roles
of the nodes in the imported Composition will be transferred to the corresponding nodes in the current Composition.transfer_excluded_roles (bool : default True) – if True, the
excluded_roles
of the nodes in the imported Composition will be transferred to the corresponding nodes in the current Composition.
- _add_required_node_role(node, role, context=None)¶
Assign the
NodeRole
specified by role to node. Remove exclusion of thatNodeRole
if it had previously been specified inexclude_node_roles
.
- 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 inexclude_node_roles
.
- 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.
- get_required_roles_by_node(node)¶
Return a list of
NodeRoles
that have been user-assigned to a specified 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_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
- Returns
- Return type
list[Mechanisms and/or Compositions]
- get_nested_nodes_by_roles_at_any_level(comp, include_roles, exclude_roles=None)¶
Return all Nodes from comp or any nested within it that have include_roles but not exclude_roles. Returns Nodes that have or don’t have the specified roles in the Composition specified by comp or any Composition nested within it, irrespective of their status at other levels of nesting. To get nodes that are either INPUT or OUTPUT Nodes at all levels of nesting, use either
get_nested_input_nodes_at_all_levels() or get_nested_output_nodes_at_all_levels()
- Note: do this recursively, checking roles on the “way down,” as 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).
- Note: exclude_roles takes precedence, so that if a NodeRole is listed in both,
nodes with that role will be excluded.
- Return type
list
- get_nested_input_nodes_at_all_levels()¶
Return all Nodes from nested Compositions that receive input directly from input to outermost Composition.
- Return type
list
- get_nested_output_nodes_at_all_levels()¶
Return all Nodes from nested Compositions that send output directly to outermost Composition.
- Return type
list
- _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’sinput_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
- Exclude input_port(s) of Node(s) in a nested Composition if their input comes from a Node in the enclosing
Composition rather than its input_CIM (as those will be accounted for by the input_CIM of the outer Comp)
- _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
- _get_terminal_nodes(graph, toposorted_graph=None)¶
Returns a list of nodes in this composition that are NodeRole.TERMINAL with respect to an acyclic graph. The result can change depending on whether the scheduler or composition graph is used. The graph of the scheduler graph is the scheduler’s consideration_queue.
Includes all nodes that have no receivers in graph. The ObjectiveMechanism of a Composition’s controller cannot be NodeRole.TERMINAL, so if the ObjectiveMechanism is the only node with no receivers in graph, then that node’s senders are assigned NodeRole.TERMINAL instead.
- Return type
set
[Component
]
- _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]).
Note
this takes account of any Projections designated as feedback by graph_processing (i.e., self.graph.comp_to_vertex[efferent].feedback == EdgeType.FEEDBACK)
these will all be assigined afferent Projections from Composition.input_CIM
- INPUT:
all Nodes that have no incoming edges in this composition, or that are in a cycle with no external incoming edges, 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
- BIAS:
all Nodes that have one or more InputPorts for which default_input == DEFAULT_VARIABLE
- INTERNAL:
A Node that is neither
INPUT
norOUTPUT
. Note that it can also beORIGIN
,TERMINAL
orSINGLETON
, if it has noafferent
orefferent
Projections or neither, respectively. This role cannot be modified programmatically.- CYCLE:
all Nodes that identified as being in a cycle by self.graph_processing (i.e., in a cycle 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 Nodes that have no outgoing edges in this compositions 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
Note
this insures that for cases in which there are nested CYCLES (e.g., LearningMechanisms for a
learning Pathway
), only the Node in the outermost CYCLE that is specified as a FEEDBACK_SENDER is assigned as a TERMINAL Node (i.e., the LearningMechanism responsible for the first learned Projection; in thelearning Pathway
)an ObjectiveMechanism assigned CONTROLLER_OBJECTIVE is prohibited since it and the Composition’s
controller
are executed outside of (either before or after) all of the other Components of the Composition, as managed directly by the scheduler;Execution of a `Composition always ends with a
TERMINAL
Node, although someTERMINAL
Nodes may execute earlier (i.e., if they belong to a Pathway that is shorter than the longest one in the Composition).
- _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.Note
The InputPort on the input_CIM is named using the following convention: INPUT_CIM_NAME + “_” + node.name + “_” + node.input_port.name
Note
If the input_CIM is for a nested Composition, any of its input_ports that receive Projection(s) from Nodes in the enclosing (outer) Composition (rather than its input_CIM) are marked as internal_only, since they do not receive input directly from the external environment of the enclosing Composition
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.Note
The OutputPort on the output_CIM is named using the following convention: OUTPUT_CIM_NAME + “_” + node.name + “_” + node.output_port.name
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:
input_CIM_ports = { INPUT Node InputPort: (InputCIM InputPort, InputCIM OutputPort) }
output_CIM_ports = { OUTPUT Node OutputPort: (OutputCIM InputPort, OutputCIM OutputPort) }
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, context=None)¶
Calls
add_projection
for each Projection in the projections list. Each Projection must have itssender
andreceiver
already specified. If an item in the list is a list of projections,add_projections
is called recursively on that list. Seeadd_projection
for additional details of how duplicates are determined and handled.- 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, is_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
andreceiver
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 (it can be between any pair of the sender’s OutputPort
and receiver’s InputPort)
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/orreceiver
attributes are not specified, then sender and/or receiver are used.if
sender
and/orreceiver
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 itssender
andreceiver
, 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 the sender and/or the receiver is specified as a Mechanism, a Projection from any of a specified sender’s OutputPorts to any of a specified receiver’s InputPorts will be considered a match. However, if both sender and receiver are specified as Ports, then only a Projection from the sender to the receiver will be considered a match, allowing other Projections to remain between that pair of Nodes. .. 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
- _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 between the same pair of Nodes
Finding more than one Projection in the current Composition raises an error (should never be the case). Finding one in the current Composition and any number outside of it is allowed, and handled as follows:
if in_composition is ONLY, return the Projection if one is found in the current Composition,
and none are found outside of it.
if in_composition is True, return the Projection found in the current Composition,
irrespective of whether there are also any outside of the Composition.
if in_composition is False, return only Projections that are found outside the current Composition
and only if there are none found within the current Composition.
if in_composition is ANY, return all existing Projections in or out of the current Composition.
If the condition specified above is satisfied, then return the Projection(s) found. Otherwise, return False.
- IMPLEMENTATION NOTE:
If the sender and/or the receiver is specified as a Mechanism, then any Projection between that Mechanism the other specification will be considered a match, irrespective of whether they use the same InputPorts (if it is a receiver) and/or OutputPorts (if it is a sender); if both are Mechanisms, then any Projection between them will count as a match, irrespective of the InputPorts and/or OutputPorts used. However, if both sender and receiver are specified as Ports, then only a Projection from the sender to the receiver will be considered a match, allowing other Projections to remain between pair of Nodes
Return Projection or list of Projections that satisfies the conditions, else False
- Return type
Union
[bool
,list
]
- _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 supersede 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 withadd_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 itsname
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 Projection Specifications; see Specifying the Matrix Parameter for details of specification)name (str) – species the name used for Pathway; supersedes
name
of Pathway object if it is has one.
- Returns
Pathway added to Composition.
- Return type
- add_linear_learning_pathway(pathway, learning_function=None, loss_spec=Loss.MSE, learning_rate=None, error_function=<class 'psyneulink.core.components.functions.nonstateful.transformfunctions.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 thelearned_projection
attribute of theLearningMechanisms
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 totarget
OBJECTIVE_MECHANISM: ComparatorMechanism (assigned tolearning_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_spec (Loss : default Loss.MSE) – specifies the loss function used if
BackPropagation
is specified as the learning_function (seeadd_backpropagation_learning_pathway
).learning_rate (float : default 0.05) – specifies the
learning_rate
used for the learning_function of the LearningMechanism in the pathway (see Learning Rate for additional details).error_function (function : default LinearCombination) –
specifies the function assigned to Mechanism used to compute the error from the target and the output (
value
) of theTARGET
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 fuctionPredictionErrorDeltaFunction
.learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the
matrix
parameter of thelearned_projection
is updated in eachTRIAL
when the Composition executes; it is assigned as the default value for thelearning_enabled
attribute of the LearningMechanism in the pathway, and its LearningProjection (seelearning_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 Projection Specifications; see Specifying the Matrix Parameter for details of specification)name (str :) – species the name used for Pathway; supersedes
name
of Pathway object if it is has one.
- Returns
learning Pathway
<Composition_Learning_Pathway>` added to the Composition.- Return type
- add_reinforcement_learning_pathway(pathway, learning_rate=None, 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 Projection Specifications; see Specifying the Matrix Parameter for details of specification)learning_rate (float : default 0.05) – specifies the
learning_rate
used for theReinforcementLearning
function of the LearningMechanism in the pathway (see Learning Rate for additional details).error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (
value
) of theTARGET
Mechanism in the pathway).learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the
matrix
parameter of thelearned_projection
is updated in eachTRIAL
when the Composition executes; it is assigned as the default value for thelearning_enabled
attribute of the LearningMechanism in the pathway, and its LearningProjection (seelearning_enabled
for meaning of values).name (str :) – species the name used for Pathway; supersedes
name
of Pathway object if it is has one.
- Returns
Reinforcement
learning Pathway
<Composition_Learning_Pathway>` added to the Composition.- Return type
- add_td_learning_pathway(pathway, learning_rate=None, 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 theTDLearning
function of the LearningMechanism in the pathway (see Learning Rate for details).error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (
value
) of theTARGET
Mechanism in the pathway).learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the
matrix
parameter of thelearned_projection
is updated in eachTRIAL
when the Composition executes; it is assigned as the default value for thelearning_enabled
attribute of the LearningMechanism in the pathway, and its LearningProjection (seelearning_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 Projection Specifications; see Specifying the Matrix Parameter for details of specification)name (str :) – species the name used for Pathway; supersedes
name
of Pathway object if it is has one.
- Returns
TD Reinforcement
learning Pathway
<Composition_Learning_Pathway>` added to the Composition.- Return type
- add_backpropagation_learning_pathway(pathway, learning_rate=None, error_function=None, loss_spec=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 aslearned_projections
.learning_rate (float : default 0.05) – specifies the
learning_rate
used for theBackpropagation
function of the LearningMechanisms in the pathway (see Learning Rate for additional details).error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (
value
) of theTARGET
(last) Mechanism in the pathway).loss_spec (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 thelearned_projections
are updated in eachTRIAL
when the Composition executes; it is assigned as the default value for thelearning_enabled
attribute of the LearningMechanisms in the pathway, and their LearningProjections (seelearning_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 Projection Specifications; see Specifying the Matrix Parameter for details of specification)name (str :) – species the name used for Pathway; supersedes
name
of Pathway object if it is has one.
- Returns
BackPropagation
learning Pathway
<Composition_Learning_Pathway>` added to the Composition.- Return type
Creates TARGET_MECHANISM, ComparatorMechanism and LearningMechanism for RL and TD learning
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
- Return type
- _create_terminal_backprop_learning_components(output_source, error_function, loss_spec, learned_projection, learning_rate, learning_update, context)¶
Create ComparatorMechanism, LearningMechanism and LearningProjection for Component in learning Pathway
- _get_back_prop_error_sources(efferents, learning_mech=None, context=None)¶
Add any LearningMechanisms associated with efferent projection from output_source
- 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, thecontroller
attempts to use the entire input set provided to therun
method of the Composition as input for the call torun
. If it is not, thecontroller
uses the inputs slated for its next or previous execution, depending on whether thecontroller_mode
of the Composition is set tobefore
orafter
, 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 ofevaluate
.The
net_outcome
for each run is calculated using thecontroller
’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 theagent_rep
. If return_results is True, an array with the results of each run is also returned.
- _is_preparing(context)¶
Returns true if the composition is currently preparing to execute (run or learn)
- _infer_target_nodes(targets, execution_mode)¶
Maps targets onto target mechanisms (as needed by learning)
- Returns
Dict mapping TargetMechanisms -> target values
- Return type
dict
- _parse_learning_spec(inputs, targets, execution_mode, context)¶
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 inputsint
– 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 inputsint
– 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 dictint
– 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 dictint
– 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 inputsint
– 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
ornp.ndarray
orlist
- _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 dictint
– 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 Nodes 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_and_expand_for_all_trials(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, context)¶
Extracts inputs for a single trial and parses it in accordance with its type Note: this method is intended to run BEFORE a call to Composition.execute
- 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>, **kwargs)¶
- 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 eachTRIAL
executed during the run (see Composition Inputs for additional information about format, andget_input_format
method for generating an example of the input format for the Composition). If inputs is not specified, the default_variable for eachINPUT
Node is used as its input onTRIAL
.- 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, useComposition.termination_processing
(orScheduler.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 andReportDevices
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 theshow_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 theshow_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 asTrue
, defaults are used for all arguments ofshow_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 eachexecution_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 or os.PathLike (default=PsyNeuLink root dir or current dir) – specifies the directory to be used for the movie file; by default a subdirectory of <MOVIE_DIR>/pnl-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’.
- inputs: Dict{
- _
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 primarynode
andprojection
in the Composition, if it is not already set.Note
As when setting the
log_condition
directly, a value ofTrue
will correspond to theEXECUTION
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_unit
pint.Quantity
1ms
if not otherwise determined by any absolute conditions, specifies the absolute duration of a
TIME_STEP
. SeeScheduler.default_absolute_time_unit
- context
execution_id
defaultdefault_execution_id
context in which the Composition will be executed; set to self.default_execution_id ifunspecified.
- 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
- 2d list of values of OUTPUT Nodes at end of last triallist[list]
each item in the list is the
output_values
for anOUTPUT
Node of the Composition, listed in the order listed inget_nodes_by_role
(NodeRole.OUTPUT
).Note
The
results
attribute of the Composition contains a list of the outputs for all trials.
- Return type
list
- learn(inputs, targets=None, num_trials=None, epochs=1, learning_rate=None, minibatch_size=None, optimizations_per_minibatch=None, patience=None, min_delta=0, execution_mode=ExecutionMode.Python, randomize_minibatches=False, call_before_minibatch=None, call_after_minibatch=None, context=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:
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).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. Thetargets
andepochs
keys should contain values of the same shape astargets
andepochs
.
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 (see `Composition_Learning_Rate
for additional details).minibatch_size (int (default=1)) – specifies the number of inputs used to calculate the
error_signal
for one step (gradient update) of learning, after which LearningMechanisms with learning mode TRIAL will update thematrix
parameter of the MappingProjection for which they are responsible; this overrides the Composition’s default value.optimizations_per_minibatch (int (default=1)) –
specifies the number of executions and weight updates of learnable pathways that are carried out for each set of stimuli in a
minibatch
; this overrides the Composition’s default value.Hint
This can be used to implement the backprop-to-activation proceedure in which the
backpropagation learning algorithm
is used, with a high learning rate, to quickly search for a pattern of activation in response to a given input (or set of inputs) that is useful for some downstream purpose.randomize_minibatch (bool (default=False)) – specifies whether the order of the input trials should be randomized in each epoch
patience (int or None (default=None)) – used for early stopping of training; If a model has more than
patience
bad consecutive epochs, thenlearn
will prematurely return. A bad epoch is determined by themin_delta
valuemin_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.
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 andReportDevices
for options.context (
Optional
[Context
]) – context will be set to self.default_execution_id if unspecified
- Return type
list
- Returns
the results of the last trial of training (list)
.. note:: – the results of the final epoch of training are stored in the Composition’s
learning_results
attribute.
- 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, **kwargs)¶
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
: defaultdefault_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] : 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 andReportDevices
for options.
- Return type
ndarray
- Returns
output_values (np.ndarray)
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’srun
method; TEXT returns a user-readable text description of the format (optionally with inputs required forINPUT
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 theINPUT
Mechanisms in the Composition (including any nested ones) have aninput_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 anINPUT
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 therun
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 allOUTPUT
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 forMechanisms Mechanism
that have anoutput_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]
- _update_results(results, trial_output, execution_mode, synch_with_pnl_options, context)¶
Update results by appending most recent trial_output This is included as a helper so it can be overriden by subclasses (such as AutodiffComposition) that may need to do this less frequently for scallable exeuction
- 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. Ifinclude_unspecified_nodes
is True and a value is not provided, the node will be initialized to its default value. Ifinclude_unspecified_nodes
is False, then all nodes must have corresponding initialization values. TheDEFAULT
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
- property is_nested¶
Determine whether Composition is nested in another Used in run() to decide whether to:
initialize from context
assign values to CIM from input dict (if not nested) or simply execute CIM (if nested)
- property _sender_ports¶
Returns: ContentAddressableList: list containing Ports on this object that can send Projections
- property _receiver_ports¶
Returns: ContentAddressableList: list containing Ports on this object that can receive Projections
- show_graph(show_all=False, show_node_structure=False, show_nested='nested', show_nested_args='all', show_cim=False, show_controller=True, show_learning=False, show_headers=True, show_types=False, show_dimensions=False, show_projection_labels=False, show_projections_not_in_composition=False, active_items=None, output_fmt='pdf', context=None)¶
Patch to ShowGraph method IMPLEMENTATION NOTE: arguments are listed explicitly so they show up in IDEs that support argument completion
- class psyneulink.core.compositions.composition.NodeRole(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)¶
Roles assigned to Nodes of a Composition.
- ORIGIN¶
A Node that has no scheduling dependencies on any other Nodes within its own Composition. Typically, an
ORIGIN
Node also do 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 anORIGIN
Node. A Composition may have manyORIGIN
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, theORIGIN
Nodes of a Composition are also itsINPUT
Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have manyINPUT
Nodes. Note that any Node that shadows anINPUT
Node is itself also assigned the role ofINPUT
Node.
- SINGLETON¶
A Node that is both an
ORIGIN
and aTERMINAL
. This role cannot be modified programmatically.
- BIAS¶
A Node for which one or more of its InputPorts is assigned DEFAULT_VARIABLE as its
default_input
(which provides it a prespecified input that is constant across executions). Such a node can also be assigned as anINPUT
and/orORIGIN
, if it receives input from outside the Composition and/or does not receive any Projections from other Nodes within the Composition, respectively. This role cannot be modified programmatically.
- INTERNAL¶
A Node that is neither
INPUT
norOUTPUT
. Note that it can also beORIGIN
,TERMINAL
orSINGLETON
, if it has noafferent
orefferent
Projections or neither, respectively. 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
orLEARNING_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’soutput_CIM
, but – unlike anOUTPUT
Node – theoutput_values
of which are not included in the Composition’sresults
attribute (seeallow_probes
for an example.
- OUTPUT¶
A Node the
output_values
of which are included in the Composition’sresults
attribute. By default, theTERMINAL
Nodes of a Composition are also itsOUTPUT
Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have manyOUTPUT
Nodes.
- TERMINAL¶
A Node on which no other Nodes have scheduling dependencies within its own Composition, excluding ObjectiveMechanism. Typically, a
TERMINAL
Node 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 manyTERMINAL
Nodes. The ObjectiveMechanism associated with the Composition’scontroller
(assigned the roleCONTROLLER_OBJECTIVE
) cannot be aTERMINAL
Node of a Composition. Execution of a Composition itself always ends with aTERMINAL
Node, although thecontroller
and its associated ObjectiveMechanism may execute after that; someTERMINAL
Nodes may also execute earlier (i.e., if they belong to a Pathway that is shorter than the longest one in the Composition). Nodes in a flattened cycle will be either all TERMINAL or all not TERMINAL. 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 aProjection
.- 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 aNode
, this is one or more Projections; for a Projection, it is a single Node.
- 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 arepotentially 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