ModulatorySignal¶
Contents¶
Overview¶
A ModulatorySignal is a subclas of OutputPort that belongs to a ModulatoryMechanism, and is
used to modulate the value of one or more Ports by way of
one or more ModulatoryProjctions. A ModulatorySignal modulates the value of a Port by modifying
a parameter of that Port’s function. There are three types of ModulatorySignals, each of which
is associated with a particular type of ModulatoryMechanism and ModulatoryProjection, and modifies the value of different types of Ports, as summarized below:
- ControlSignal
takes the
allocationassigned to it by thefunctionof the ControlMechanism to which it belongs, and uses it to modulate the parameter of a Mechanism or itsfunction(and thereby thevalueof that Mechanism), or a parameter of thefunctionone of the Mechanism’s InputPorts or OutputPorts (and thereby thevalueof the corresponding Port).
- GatingSignal takes the
allocationassigned to it by the functionof the Gating Mechanism to which it belongs, and uses it to modulate the parameter of thefunctionof an InputPort or OutputPort (and hence that Port’svalue). A GatingMechanism and GatingSignal can be thought of as implementing a form of control specialized for gating the input to and/or output of a Mechanism.
- GatingSignal takes the
- LearningSignal
takes the learning_signal calculated by the
functionof the LearningMechanism to which it belongs, and uses it to modulate thematrixparameter of a MappingProjection.
These are shown in a figure below, and are descdribed in greater detail in in the sections under Structure.
See ModulatoryMechanism for conventions used for the names of Modulatory components.
Creating a ModulatorySignal¶
ModulatorySignal is a base class, and cannot be instantiated directly. However, the three types of ModulatorySignals
listed above can be created directly, by calling the constructor for the desired type. More commonly, however,
ModulatorySignals are created automatically by the ModulatoryMechanism to which they belong, or
by specifying them in the constructor for a ModulatoryMechanism (the details of which are
described in the documentation for each type of ModulatorySignal). If a ModulatorySignal is constructed explicitly,
the type of modulation it uses is specifed in the modulation argument of its constructor, using a 2-item tuple
that contains the Port to be modulated as the first item, and either the name of the parameter of the Port’s function to be modulated, or a keyword specifying the type of modulation, as the second item (see
Types of Modulation for additional details).
Structure¶
A ModulatorySignal is always assigned to a ModulatoryMechanism, and must be assigned to an
ModulatoryMechanism of the appropriate type (see Types of ModulatoryMechanism). The
ModulatorySignal receives an allocation from the ModulatoryMechanism to which it is
assigned, that it uses as the variable for its function, the
result of which is the modulatory value of the ModulatorySignal. A ModulatorySignal is
associated with one or more ModulatoryProjections of the corresponding type, that receive
the ModulatorySignal’s value, and use this to modulate the Port(s) to which they project.
All of the ModulatoryProjections from a given ModulatorySignal are assigned the same modulatory value (see ModulatoryProjections below) and use the same type of modulation specified by the the ModulatorySignal’s modulation attribute.
The ModulatoryProjections received by a Port are listed in the Port’s mod_afferents
attribute.
The section on Modulation below provides a comparison of ModulatorySignal subclasses and their uses (summarized in an accompanying table and figure), as well as a description of the different types of modulation and a more detailed description of how modulation is implemented.
ModulatoryProjections¶
A ModulatorySignal can be assigned one or more ModulatoryProjections,
using either the projections argument of its constructor, or in an entry of a dictionary assigned to the
params argument with the key PROJECTIONS. These are assigned to its efferents
attribute. See Port Projections for additional details concerning the specification of
Projections when creating a Port.
Although a ModulatorySignal can be assigned more than one ModulatoryProjection,
all of those Projections receive and convey the same modulatory value from the
ModulatorySignal, and use the same form of modulation. This is a common use for some
ModulatorySignals (e.g., the use of a single GatingSignal to gate multiple InputPort(s) or
OutputPort(s)), but requires more specialized circumstances for others (e.g., the use of a single
LearningSignal for more than one MappingProjection, or a single ControlSignal for the parameters of more than
one Mechanism or function).
Modulation¶
A ModulatorySignal modulates the value of a Port either by modifying a parameter of the Port’s function (which determines the Port’s value), or by assigning a value to the Port
directly. The type of modulation is determined by the ModulatorySignal’s
modulation attribute, which can be specified in the modulation argument of its
ModulatorySignal’s constructor, or in a MODULATION entry of a Port specification dictionary used to create the ModulatorySignal (see Type of Modualtion and
figure below for details). If the type of modulation
is not specified when a ModulatorySignal is created, it is assigned the value of the modulation attribute for the ModulatoryMechanism to which it
belongs.
Uses of Modulation¶
There are three broad types of modulation that serve different purposes, and differ according to the ModulatorySignals used and the type of Port modulated; these are modulation of a:
- Mechanism's
functiona ControlSignal must be used; this modulates the
valueof ParameterPort for a parameter of the Mechanism’sfunctionwhich, in turn, determines how it computes the Mechanism’svalue;
- Mechanism's input or output
a GatingSignal is specialized for this purpose, though a ControlSignal can also be used. These modulate either the value <InputPort.value>` an InputPort of the Mechanism, that determines the Mechanism’s
variableused as the input to itsfunction; or thevalueof an OutputPort of the Mechanism, that determines how thevalueof the Mechanism (i.e., the result of itsfunction) is used to generate the output from that Mechanism.
- MappingProjection
a LearningSignal must be used; this modulates the ParameterPort for the
matrixparameter of a MappingProjection’sfunctionwhich, in turn, determines how it computes the MappingProjection’svalue.
The following table summarizes the three uses of modulation, the ModulatorySignals for each, and the Ports they modulate. The mechanics of modulation are described in greater detail in Implementation of Modulation, and shown in the figure below.
ModulatorySignals and Ports they Modulate (colors listed are those used in the figure below)
Purpose |
ModulatorySignal |
Default type of |
Recipient Port |
Default Function (mod param) for Recipient Port |
|---|---|---|---|---|
Modulate the parameter of a
Mechanism’s |
ControlSignal (blue) |
MULTIPLICATIVE |
Mechanism ParameterPort (by default) but can also be an InputPort or OutputPort |
|
Modulate the input or output of
a Mechanism’s |
GatingSignal (brown) |
MULTIPLICATIVE |
Mechanism InputPort/OutputPort |
|
Modulate a MappingProjection’s
|
LearningSignal (green) |
ADDITIVE |
MappingProjection ParameterPort |
It is important to emphasize that, although the purpose of a ModulatorySignal is to modify the functioning of a
Mechanism or a MappingProjection, it does this indirectly by modifying a Port that determines the input
or output of a Mechanism, or the parameters of a Mechanism or Projection’s function, rather than directly modifying
the function of the Mechanism or Projection itself. This is shown in the following figure, and described in greater
detail under Implementation of Modulation.
Anatomy of Modulation
Three types of Modulatory Components and the Ports they modulate. The default type of modulation for each type of ModulatorySignal, and the default Function and modulated parameter of
its recipient Port are listed in the table above. Note that the ControlMechanism
and ControlSignal are shown in the figure modulating the ParameterPort of a Mechanism;
however, like Gating components, they can also be used to modulate InputPorts and OutputPorts. The figure below shows a detailed view of how ModulatorySignals
modulate the parameters of a Port’s function.¶
Types of Modulation¶
The modulation attribute of a ModulatorySignal determines the way in which it
modulates the value of a Port, by specifying which parameter of the Port’s function that it modifies (see figure below). This is specified
in a tuple containing the Port and the name of the parameter to be modified (see example). Alternatively, a keyword can be used in place of the parameter’s name.
For some Functions, keywords can be used to specify function-specific forms of modulation (e.g., see
TransferWithCosts Function for an example). In addition, there are
four keywords that can be used to specify generic forms of modulation supported by most Functions:
MULTPLICATIVE_PARAM - assign the
valueof the ModulatorySignal to the parameter of the Port’sfunctionspecified as its multiplicative_param. For example, if the Port’sfunctionisLinear(the default for most Ports), then the ModulatorySignal’svalueis assigned to the function’sslopeparameter (it’s multiplicative_param), thus multiplying the Port’svariableby that amount each time the Port is executed, and assigning the result as the Port’svalue.ADDITIVE_PARAM - assign the
valueof the ModulatorySignal to the parameter of the Port’sfunctionspecified as its additive_param. For example, if the Port’sfunctionisLinear(the default for most Ports), then the ModulatorySignal’svalueis assigned to the function’sinterceptparameter (it’s additive_param), thus adding that value to the Port’svariableeach time the Port is executed, and assigning the result as the Port’svalue.OVERRIDE - assign the
valueof the ModulatorySignal directly to the Port’svalue; in effect, this bypasses the Port’sfunction. Note that this can be specified for only one ModulatorySignal that modulates a given Port (see below for additional details).DISABLE - suppresses the modulatory effect of the ModulatorySignal; the Port’s
functionwill operate as if it did not receive a ModulatoryProjection from that ModulatorySignal.Note
the MULTPLICATIVE_PARAM and ADDITIVE_PARAM keywords can be used only with Functions that specify a multiplicative_param and/or additive_param, respectively.
The default type of modulation for ControlSignals and GatingSignals is
MULTIPLICATIVE. The default for LearningSignals is ADDITIVE (which additively modifies the
value of the LearningSignal (i.e., the weight changes computed by the LearningMechanism)
to the Port’s variable (i.e., the current weight matrix for
the MappingProjection being learned).
Implementation of Modulation¶
Although the purpose of a ModulatorySignal is to modify the operation of a Mechanism or MappingProjection, it does not do this directly; rather, it does it by way of a Port that
modulates the input, function parameter, or output of the Mechanism or MappingProjeciton to be regulated. More
specifically, a ModulatorySignal modulates the function of a Port responsible for
generating those values, by modifying a parameter of that Port’s function. This is shown
in the figure below:
Detailed View of Modulation
A ModulatorySignal modulates the value of a Port either by modifying a parameter of the
Port’s function, or assigining the value of the Port directly.
This is determined by the ModulatorySignal’s modulation attribute. That can be
assigned either the name of a parameter of the Port’s function, or a keyword that
specifies a standard form of modulation. The keywords MULTIPLICATIVE and ADDITIVE specify that the value of the ModulatorySignal be assigned to the multiplicative_param or `additive_param of the Port’s function, respectively; OVERRIDE specifies that the
ModulatorySignal’s value be assigned directly as the Port’s value, in effect bypassing the Port’s function (see
Types of Modulation for additional details).¶
Though this implementaton of modulation is indirect, it provides a standard for all forms of modulation, as well as considerable flexibility in the modulatory regulation of Components within a Composition (see Types of Modulation below).
The types of Ports modulated by each type of ModulatorySignal are summarized in Uses of Modulation, and the accompanying table and figure.
Any modulable parameter of a Port’s function can be modulated,
and different parameters of the same function of a Port can be modulated by different
ModulatorySignals. The same parameter can also be modulated by more than on ModulatorySignal. If more than one
ModulatorySignal modulates the same parameter of a Port’s function, then that parameter’s
modulation_combine_function attribute determines how the values of the different ModulatorySignals are combined. By default, the product of their
vaues is used. However, if OVERRIDE is specfied as the type of modulation for one
of them, then that ModulatorySignal’s value is assigned directly as the Port’s value, and the others are all ignored. Only one ModulatorySignal specified as OVERRIDE can modulate
a given parameter; if there is more than, then an error is generated.
Execution¶
ModulatorySignals cannot be executed directly. This done when the ModulatoryMechanism to
which they belong is executed. When a ModulatorySignal is executed, it calculates its value,
which is then assigned as the variable of the ModulatoryProjections listed in its efferents attribute.
When those Projections execute, they convey the ModulatorySignal’s value to the function of the Port to which they project. The Port’s function
then uses that value in determining value of the parameter designated by the modulation
attribute of the ModulatorySignal when the Port’s value is updated.
# FIX 5/8/20 – REWORK TO BE ALIGNED WITH ModulatoryMechanism
Note
The change in the value of a Port in response to a ModulatorySignal does not occur until the Mechanism to which the port belongs is next executed; see Lazy Evaluation for an explanation of “lazy” updating).
Class Reference¶
- class psyneulink.core.components.ports.modulatorysignals.modulatorysignal.ModulatorySignal(owner=None, input_shapes=None, reference_value=None, default_allocation=1.0, function=None, modulates=None, modulation=None, index=None, assign=None, params=None, name=None, prefs=None, **kwargs)¶
Subclass of OutputPort used by a ModulatoryMechanism to modulate the value of one more Ports. See OutputPort and subclasses for additional arguments and attributes.
Note
ModulatorySignal is an abstract class and should never be instantiated by a call to its constructor. It should be instantiated using the constructor for a subclass.
- Parameters:
default_allocation (scalar : defaultModulatoryAllocation) – specifies the default template and value used for
variable.modulation (str : default MULTIPLICATIVE) – specifies the type of modulation the ModulatorySignal uses to determine the value of the Port(s) it modulates; must be either a keyword defined by the Function of the parameter to be modulated, or one of the following generic keywords – MULTIPLICATIVE, ADDITIVE, OVERRIDE or DISABLE (see Types of Modulation for additional details).
- variable¶
same as
allocation.- Type:
scalar, list or np.ndarray
- allocation¶
value assigned by the ModulatorySignal’s
owner, and used as thevariableof itsfunctionto determine the ModulatorySignal’sModulatorySignal.value.- Type:
float
- function¶
used to transform the ModulatorySignal’s
allocationinto itsvalue; default is theIdentityFunction that simply assignsallocationtovalue.- Type:
- value¶
result of
function, used to determine thevalueof the Port(s) being modulated.- Type:
number, list or np.ndarray
- modulation¶
determines how the
valueof the ModulatorySignal is used to modulate the value of the port(s) being modulated (see Types of Modulation for additional details).- Type:
str
- efferents¶
a list of the ModulatoryProjections assigned to the ModulatorySignal.
- Type:
[List[GatingProjection]]
- name¶
the name of the ModulatorySignal. If the ModulatorySignal’s initialization has been deferred, it is assigned a temporary name (indicating its deferred initialization status) until initialization is completed, at which time it is assigned its designated name. If that is the name of an existing ModulatorySignal, it is appended with an indexed suffix, incremented for each Port with the same base name (see Naming). If the name is not specified in the name argument of its constructor, a default name is assigned as follows; if the ModulatorySignal has:
no projections (which are used to name it) – the name of its class is used, with an index that is incremented for each ModulatorySignal with a default named assigned to its
owner;one
ModulatoryProjection– the following template is used: “<target Mechanism name> <target Port name> <ModulatorySignal type name>” (for example,'Decision[drift_rate] ControlSignal', or'Input Layer[InputPort-0] GatingSignal');multiple ModulatoryProjections, all to Ports of the same Mechanism – the following template is used: “<target Mechanism name> (<target Port name>,…) <ModulatorySignal type name>” (for example,
Decision (drift_rate, threshold) ControlSignal, or'Input Layer[InputPort-0, InputPort-1] GatingSignal');multiple ModulatoryProjections to Ports of different Mechanisms – the following template is used: “<owner Mechanism’s name> divergent <ModulatorySignal type name>” (for example,
'ControlMechanism divergent ControlSignal'or'GatingMechanism divergent GatingSignal').
Note
Unlike other PsyNeuLink components, Port names are “scoped” within a Mechanism, meaning that Ports with the same name are permitted in different Mechanisms. However, they are not permitted in the same Mechanism: Ports within a Mechanism with the same base name are appended an index in the order of their creation.
- Type:
str
- _instantiate_projections(projections, context=None)¶
Instantiate Projections specified in PROJECTIONS entry of params arg of Port’s constructor
Specification should be an existing ModulatoryProjection, or a receiver Mechanism or Port Disallow any other specifications (including PathwayProjections) Call _instantiate_projection_from_port to assign ModulatoryProjections to .efferents
- exception psyneulink.core.components.ports.modulatorysignals.modulatorysignal.ModulatorySignalError(message, component=None)¶