Skip to content

Commit

Permalink
Fix/component/default naming (#558)
Browse files Browse the repository at this point in the history
• System
  - show_graph():
         fixed bug producing empty image for graphs with just one Mechanism
         added auto-recurrent projections

• Component
  - deferred_init:  
          fixed bug in which "Deferred Init" was remaining in name of initialized Component
  - added call to _assign_default_name()

• PathwayProjection, Projection
  - added _assign_default_name to trap call from Component
  • Loading branch information
jdcpni authored Dec 1, 2017
1 parent 848f08b commit e6e5ac6
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 33 deletions.
10 changes: 10 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions Scripts/Examples/Multilayer-Learning.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@
Middle_Weights_matrix = (np.arange(5 * 4).reshape((5, 4)) + 1) / (5 * 4)
Output_Weights_matrix = (np.arange(4 * 3).reshape((4, 3)) + 1) / (4 * 3)

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

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

# Commented lines in this projection illustrate variety of ways in which matrix and learning signals can be specified
# Treated same as Middle_Weights Projection
Output_Weights = pnl.MappingProjection(
name='Output Weights',
sender=Hidden_Layer_2,
Expand All @@ -59,13 +59,13 @@
Input_Weights,
Hidden_Layer_1,
# Middle_Weights,
# No projection specification is needed here since the sender arg for Middle_Weights
# No Projection specification is needed here since the sender arg for Middle_Weights
# is Hidden_Layer_1 and its receiver arg is Hidden_Layer_2
Hidden_Layer_2,
# Output_Weights,
# Output_Weights does not need to be listed for the same reason as Middle_Weights
# If Middle_Weights and/or Output_Weights is not declared above, then the process
# will assign a default for missing projection
# If Middle_Weights and/or Output_Weights is not declared above, then the Process
# will assign a default for rhe missing Projection
Output_Layer
],
clamp_input=pnl.SOFT_CLAMP,
Expand Down Expand Up @@ -104,8 +104,10 @@ def show_target(system):
)

mySystem.reportOutputPref = True
mySystem.show_graph(show_learning=pnl.ALL, show_dimensions=pnl.ALL)
# mySystem.show_graph()
# Shows graph will full information:
# mySystem.show_graph(show_learning=pnl.ALL, show_dimensions=pnl.ALL)
# Shows minimal graph:
mySystem.show_graph()

stim_list = {Input_Layer: [[-1, 30]]}
target_list = {Output_Layer: [[0, 0, 1]]}
Expand Down
16 changes: 10 additions & 6 deletions psyneulink/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1095,15 +1095,16 @@ def _deferred_init(self, context=None):
except KeyError:
pass

# If name is None, mark as deferred so that name can be customized
# using info that has become available at time of deferred init
self.init_args[NAME] = self.name or (self.init_args[NAME] or
(DEFERRED_INITIALIZATION + ' ' + self.className) or
DEFERRED_DEFAULT_NAME)

# Complete initialization
super(self.__class__,self).__init__(**self.init_args)

# If name was assigned, "[DEFERRED INITIALIZATION]" was appended to it, so remove it
if DEFERRED_INITIALIZATION in self.name:
self.name = self.name.replace("["+DEFERRED_INITIALIZATION+"]","")
# Otherwise, allow class to replace std default name with class-specific one if it has a method for doing so
else:
self._assign_default_name()

self.init_status = InitStatus.INITIALIZED

def _assign_deferred_init_name(self, name, context):
Expand All @@ -1118,6 +1119,9 @@ def _assign_deferred_init_name(self, name, context):
registry=DeferredInitRegistry,
context=context)

def _assign_default_name(self, **kwargs):
return

def _assign_args_to_param_dicts(self, **kwargs):
"""Assign args passed in __init__() to params
Expand Down
5 changes: 0 additions & 5 deletions psyneulink/components/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,14 +1548,9 @@ def _parse_and_instantiate_projection_entries(self, pathway, context=None):
elif (isinstance(item, (np.matrix, str, tuple)) or
(isinstance(item, np.ndarray) and item.ndim == 2)):
# If a LearningProjection is explicitly specified for this Projection, use it
# MODIFIED 8/14/17 OLD [WAS ALREADY COMMENTED OUT]:
# if params:
# matrix_spec = (item, params)
# MODIFIED 8/14/17 NEW:
if isinstance(item, tuple):
matrix_spec = item
learning_projection_specified = True
# MODIFIED 8/14/17 END
# If a LearningProjection is not specified for this Projection but self.learning is, use that
elif self.learning:
matrix_spec = (item, self.learning)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def __init__(self,
prefs=prefs,
context=context)

def _assign_default_projection_name(self, state, sender_name=None, receiver_name=None):
def _assign_default_projection_name(self, state=None, sender_name=None, receiver_name=None):

template = "{} for {}[{}]"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,14 +461,6 @@ def __init__(self,
prefs:is_pref_set=None,
context=None):

# if matrix is DEFAULT_MATRIX:
# initializer = get_matrix(matrix)
# initial_rate = initializer * 0.0
# matrix={VALUE:DEFAULT_MATRIX,
# FUNCTION:ConstantIntegrator(owner=self._parameter_states[MATRIX],
# initializer=get_matrix(DEFAULT_MATRIX),
# rate=initial_rate)}

# Assign args to params and functionParams dicts (kwConstants must == arg names)
# Assign matrix to function_params for use as matrix param of MappingProjection.function
# (7/12/17 CW) this is a PATCH to allow the user to set matrix as an np.matrix... I still don't know why
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ def __init__(self,
prefs=prefs,
context=context)

def _assign_default_projection_name(self, state, sender_name=None, receiver_name=None):
def _assign_default_projection_name(self, state=None, sender_name=None, receiver_name=None):

from psyneulink.components.mechanisms.mechanism import Mechanism


name_template = "{}[{}]"
projection_name_template = "{} from {} to {}"

Expand All @@ -114,9 +115,9 @@ def _assign_default_projection_name(self, state, sender_name=None, receiver_name

elif self.init_status is InitStatus.INITIALIZED:
if self.sender.owner:
sender_name = name_template.format(self.sender.owner.name, sender_name)
sender_name = name_template.format(self.sender.owner.name, self.sender.name)
if self.receiver.owner:
receiver_name = name_template.format(self.receiver.owner.name, receiver_name)
receiver_name = name_template.format(self.receiver.owner.name, self.receiver.name)
self.name = projection_name_template.format(self.className, sender_name, receiver_name)

else:
Expand Down
7 changes: 6 additions & 1 deletion psyneulink/components/projections/projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@ def __init__(self,
prefs=prefs,
context=context.__class__.__name__)

self._assign_default_projection_name()

def _validate_params(self, request_set, target_set=None, context=None):
"""Validate PROJECTION_SENDER and/or sender arg (current self.sender), and assign one of them as self.sender
Expand Down Expand Up @@ -948,7 +950,10 @@ def socket_assignments(self):
return {SENDER:sender,
RECEIVER:receiver}

def _assign_default_projection_name(self, state, sender_name=None, receiver_name=None):
def _assign_default_name(self, **kwargs):
self._assign_default_projection_name(**kwargs)

def _assign_default_projection_name(self, state=None, sender_name=None, receiver_name=None):
raise ProjectionError("PROGRAM ERROR: {} must implement _assign_default_projection_name().".
format(self.__class__.__name__))

Expand Down
2 changes: 2 additions & 0 deletions psyneulink/components/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -3319,10 +3319,12 @@ def _get_label(item):
# For Projection, show dimensions of matrix
elif isinstance(item, Projection):
if show_dimensions in {ALL, PROJECTIONS}:
# MappingProjections use matrix
if isinstance(item, MappingProjection):
value = np.array(item.matrix)
dim_string = "({})".format("x".join([str(i) for i in value.shape]))
return "{}\n{}".format(item.name, dim_string)
# ModulatoryProjections use value
else:
value = np.array(item.value)
dim_string = "({})".format(len(value))
Expand Down

0 comments on commit e6e5ac6

Please sign in to comment.