def switch_to_processing_trial(mechanisms): # Turn on accumulation switch_integrator_mode(mechanisms, True) # Turn on noise switch_noise(mechanisms, pnl.NormalDist(mean=0, standard_dev=unit_noise).function) # Execute until one of the accumulators crosses the threshold my_Stroop.termination_processing = { pnl.TimeScale.TRIAL: pnl.While(pass_threshold, respond_red_accumulator, respond_green_accumulator, accumulator_threshold) }
def test_function(self): fun = pnl.NormalDist(mean=5.0).function spec = SampleSpec(function=fun) sample_iterator = SampleIterator(specification=spec) expected = [ 5.978737984105739, 7.240893199201458, 6.867557990149967, 4.022722120123589, 5.950088417525589 ] for i in range(5): assert np.allclose(next(sample_iterator), expected[i])
words_input_layer = pnl.TransferMechanism(size=2, function=pnl.Linear, name='WORDS_INPUT') # Hidden layer units, colors: ('red','green') words: ('RED','GREEN') # Logistic activation function, Gain = 1.0, Bias = -4.0 #should be randomly distributed noise to the net input of each unit (except input unit) #should have tau = smoothing_factor = 0.1 colors_hidden_layer = pnl.TransferMechanism( size=2, function=pnl.Logistic(gain=1.0, bias=4.0), # function=pnl.Logistic(gain=1.0, offset=-4.0), integrator_mode=False, noise=pnl.NormalDist(mean=0.0, standard_dev=.01).function, smoothing_factor=0.1, name='COLORS HIDDEN') #should be randomly distributed noise to the net input of each unit (except input unit) #should have tau words_hidden_layer = pnl.TransferMechanism( size=2, function=pnl.Logistic(gain=1.0, bias=4.0), # function=pnl.Logistic(gain=1.0, offset=-4.0), integrator_mode=False, noise=pnl.NormalDist(mean=0.0, standard_dev=.01).function, smoothing_factor=0.1, name='WORDS HIDDEN') #log hidden layer activation colors_hidden_layer.set_log_conditions('value')
input_layer = pnl.TransferMechanism(size=2, initial_value=np.array([[0.0, 0.0]]), name='INPUT LAYER') # Create Decision Layer --- [ Target, Distractor ] decision_layer = pnl.LCA( size=2, time_step_size=dt, leak=-1.0, self_excitation=w_XiXi, competition=w_XiXj, # Recurrent matrix: [ w_XiXi -w_XiXj ] # [ -w_XiXj w_XiXi ] function=pnl.Logistic(bias=b_decision), noise=pnl.NormalDist(standard_dev=SD).function, integrator_mode=True, name='DECISION LAYER') # Create Response Layer --- [ Target ] response_layer = pnl.LCA( size=1, time_step_size=dt, leak=-1.0, self_excitation=w_X3X3, # Recurrent matrix: [w_X3X3] # Competition param does not apply because there is only one unit function=pnl.Logistic(bias=b_response), noise=pnl.NormalDist(standard_dev=SD).function, integrator_mode=True,
input_layer = pnl.TransferMechanism(size=2, initial_value=np.array([[0.0, 0.0]]), name='INPUT LAYER') # Create Decision Layer --- [ Target, Distractor ] decision_layer = pnl.LCAMechanism( size=2, time_step_size=dt, leak=1.0, self_excitation=w_XiXi, competition=w_XiXj, # Recurrent matrix: [ w_XiXi -w_XiXj ] # [ -w_XiXj w_XiXi ] function=pnl.Logistic(x_0=b_decision), noise=pnl.NormalDist(standard_deviation=SD), integrator_mode=True, name='DECISION LAYER') # Create Response Layer --- [ Target ] response_layer = pnl.LCAMechanism( size=1, time_step_size=dt, leak=1.0, self_excitation=w_X3X3, # Recurrent matrix: [w_X3X3] # Competition param does not apply because there is only one unit function=pnl.Logistic(x_0=b_response), noise=pnl.NormalDist(standard_deviation=SD), integrator_mode=True,
def get_stroop_model(unit_noise_std=.01, dec_noise_std=.1): # model params # TODO bad practice, to be moved hidden_func = pnl.Logistic(gain=1.0, x_0=4.0) integration_rate = .2 leak = 0 competition = 1 # input layer, color and word inp_clr = pnl.TransferMechanism(size=N_UNITS, function=pnl.Linear, name='COLOR INPUT') inp_wrd = pnl.TransferMechanism(size=N_UNITS, function=pnl.Linear, name='WORD INPUT') # task layer, represent the task instruction; color naming / word reading inp_task = pnl.TransferMechanism(size=N_UNITS, function=pnl.Linear, name='TASK') # hidden layer for color and word hid_clr = pnl.TransferMechanism( size=N_UNITS, function=hidden_func, integrator_mode=True, integration_rate=integration_rate, noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, name='COLORS HIDDEN') hid_wrd = pnl.TransferMechanism( size=N_UNITS, function=hidden_func, integrator_mode=True, integration_rate=integration_rate, noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, name='WORDS HIDDEN') # output layer output = pnl.TransferMechanism( size=N_UNITS, function=pnl.Logistic, integrator_mode=True, integration_rate=integration_rate, noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, name='OUTPUT') # decision layer, some accumulator decision = pnl.LCAMechanism( size=N_UNITS, leak=leak, competition=competition, # MAX_VS_NEXT=lca_mvn, noise=pnl.UniformToNormalDist( standard_deviation=dec_noise_std).function, name='DECISION') # PROJECTIONS, weights copied from cohen et al (1990) wts_clr_ih = pnl.MappingProjection(matrix=[[2.2, -2.2], [-2.2, 2.2]], name='COLOR INPUT TO HIDDEN') wts_wrd_ih = pnl.MappingProjection(matrix=[[2.6, -2.6], [-2.6, 2.6]], name='WORD INPUT TO HIDDEN') wts_clr_ho = pnl.MappingProjection(matrix=[[1.3, -1.3], [-1.3, 1.3]], name='COLOR HIDDEN TO OUTPUT') wts_wrd_ho = pnl.MappingProjection(matrix=[[2.5, -2.5], [-2.5, 2.5]], name='WORD HIDDEN TO OUTPUT') wts_tc = pnl.MappingProjection(matrix=[[4.0, 4.0], [0, 0]], name='COLOR NAMING') wts_tw = pnl.MappingProjection(matrix=[[0, 0], [4.0, 4.0]], name='WORD READING') # build the model model = pnl.Composition(name='STROOP model') model.add_node(inp_clr) model.add_node(inp_wrd) model.add_node(hid_clr) model.add_node(hid_wrd) model.add_node(inp_task) model.add_node(output) model.add_node(decision) model.add_linear_processing_pathway([inp_clr, wts_clr_ih, hid_clr]) model.add_linear_processing_pathway([inp_wrd, wts_wrd_ih, hid_wrd]) model.add_linear_processing_pathway([hid_clr, wts_clr_ho, output]) model.add_linear_processing_pathway([hid_wrd, wts_wrd_ho, output]) model.add_linear_processing_pathway([inp_task, wts_tc, hid_clr]) model.add_linear_processing_pathway([inp_task, wts_tw, hid_wrd]) model.add_linear_processing_pathway( [output, pnl.IDENTITY_MATRIX, decision]) # # LOGGING # hid_clr.set_log_conditions('value') # hid_wrd.set_log_conditions('value') # output.set_log_conditions('value') # collect the node handles nodes = [inp_clr, inp_wrd, inp_task, hid_clr, hid_wrd, output, decision] metadata = [integration_rate, dec_noise_std, unit_noise_std] return model, nodes, metadata
def test_bustamante_Stroop_model(self): # INPUT UNITS # colors: ('red', 'green'), words: ('RED','GREEN') colors_input_layer = pnl.TransferMechanism( size=2, function=psyneulink.core.components.functions.transferfunctions. Linear, name='COLORS_INPUT') words_input_layer = pnl.TransferMechanism( size=2, function=psyneulink.core.components.functions.transferfunctions. Linear, name='WORDS_INPUT') # Task layer, tasks: ('name the color', 'read the word') task_layer = pnl.TransferMechanism(size=2, function=psyneulink.core.components. functions.transferfunctions.Linear, name='TASK') # HIDDEN LAYER UNITS # colors_hidden: ('red','green') # Logistic activation function, Gain = 1.0, Bias = -4.0 (in PNL bias is subtracted so enter +4.0 to get negative bias) # randomly distributed noise to the net input # time averaging = integration_rate = 0.1 unit_noise = 0.005 colors_hidden_layer = pnl.TransferMechanism( size=2, function=psyneulink.core.components.functions.transferfunctions. Logistic(gain=1.0, x_0=4.0), # should be able to get same result with offset = -4.0 integrator_mode=True, noise=psyneulink.core.components.functions.distributionfunctions. NormalDist(mean=0, standard_deviation=unit_noise).function, integration_rate=0.1, name='COLORS HIDDEN') # words_hidden: ('RED','GREEN') words_hidden_layer = pnl.TransferMechanism( size=2, function=pnl.Logistic(gain=1.0, x_0=4.0), integrator_mode=True, noise=pnl.NormalDist(mean=0, standard_deviation=unit_noise).function, integration_rate=0.1, name='WORDS HIDDEN') # OUTPUT UNITS # Response layer, provide input to accumulator, responses: ('red', 'green') # time averaging = tau = 0.1 # randomly distributed noise to the net input response_layer = pnl.TransferMechanism( size=2, function=psyneulink.core.components.functions.transferfunctions. Logistic, name='RESPONSE', integrator_mode=True, noise=psyneulink.core.components.functions.distributionfunctions. NormalDist(mean=0, standard_deviation=unit_noise).function, integration_rate=0.1) # Respond red accumulator # alpha = rate of evidence accumlation = 0.1 # sigma = noise = 0.1 # noise will be: squareroot(time_step_size * noise) * a random sample from a normal distribution accumulator_noise = 0.1 respond_red_accumulator = pnl.IntegratorMechanism( function=pnl.SimpleIntegrator(noise=pnl.NormalDist( mean=0, standard_deviation=accumulator_noise).function, rate=0.1), name='respond_red_accumulator') # Respond green accumulator respond_green_accumulator = pnl.IntegratorMechanism( function=pnl.SimpleIntegrator(noise=pnl.NormalDist( mean=0, standard_deviation=accumulator_noise).function, rate=0.1), name='respond_green_accumulator') # LOGGING colors_hidden_layer.set_log_conditions('value') words_hidden_layer.set_log_conditions('value') response_layer.set_log_conditions('value') respond_red_accumulator.set_log_conditions('value') respond_green_accumulator.set_log_conditions('value') # SET UP CONNECTIONS # rows correspond to sender # columns correspond to: weighting of the contribution that a given sender makes to the receiver # INPUT TO HIDDEN # row 0: input_'red' to hidden_'red', hidden_'green' # row 1: input_'green' to hidden_'red', hidden_'green' color_weights = pnl.MappingProjection(matrix=np.atleast_2d( [[2.2, -2.2], [-2.2, 2.2]]), name='COLOR_WEIGHTS') # row 0: input_'RED' to hidden_'RED', hidden_'GREEN' # row 1: input_'GREEN' to hidden_'RED', hidden_'GREEN' word_weights = pnl.MappingProjection(matrix=np.atleast_2d([[2.6, -2.6], [-2.6, 2.6]]), name='WORD_WEIGHTS') # HIDDEN TO RESPONSE # row 0: hidden_'red' to response_'red', response_'green' # row 1: hidden_'green' to response_'red', response_'green' color_response_weights = pnl.MappingProjection( matrix=np.atleast_2d([[1.3, -1.3], [-1.3, 1.3]]), name='COLOR_RESPONSE_WEIGHTS') # row 0: hidden_'RED' to response_'red', response_'green' # row 1: hidden_'GREEN' to response_'red', response_'green' word_response_weights = pnl.MappingProjection( matrix=np.atleast_2d([[2.5, -2.5], [-2.5, 2.5]]), name='WORD_RESPONSE_WEIGHTS') # TASK TO HIDDEN LAYER # row 0: task_CN to hidden_'red', hidden_'green' # row 1: task_WR to hidden_'red', hidden_'green' task_CN_weights = pnl.MappingProjection(matrix=np.atleast_2d( [[4.0, 4.0], [0, 0]]), name='TASK_CN_WEIGHTS') # row 0: task_CN to hidden_'RED', hidden_'GREEN' # row 1: task_WR to hidden_'RED', hidden_'GREEN' task_WR_weights = pnl.MappingProjection(matrix=np.atleast_2d( [[0, 0], [4.0, 4.0]]), name='TASK_WR_WEIGHTS') # RESPONSE UNITS TO ACCUMULATORS # row 0: response_'red' to respond_red_accumulator # row 1: response_'green' to respond_red_accumulator respond_red_differencing_weights = pnl.MappingProjection( matrix=np.atleast_2d([[1.0], [-1.0]]), name='RESPOND_RED_WEIGHTS') # row 0: response_'red' to respond_green_accumulator # row 1: response_'green' to respond_green_accumulator respond_green_differencing_weights = pnl.MappingProjection( matrix=np.atleast_2d([[-1.0], [1.0]]), name='RESPOND_GREEN_WEIGHTS') # CREATE COMPOSITION FROM PATHWAYS my_Stroop = pnl.Composition(pathways=[ { 'WORD_PATHWAY': [ words_input_layer, word_weights, words_hidden_layer, word_response_weights, response_layer ] }, { 'COLO_PATHWAY': [ colors_input_layer, color_weights, colors_hidden_layer, color_response_weights, response_layer ] }, { 'TASK_CN_PATHWAY': [task_layer, task_CN_weights, colors_hidden_layer] }, { 'TASK_WR_PATHWAY': [task_layer, task_WR_weights, words_hidden_layer] }, { 'RESPOND_RED_PATHWAY': [ response_layer, respond_red_differencing_weights, respond_red_accumulator ] }, { 'RESPOND_GREEN_PATHWAY': [ response_layer, respond_green_differencing_weights, respond_green_accumulator ] }, ]) # my_Stroop.show() # my_Stroop.show_graph(show_dimensions=pnl.ALL) # Function to create test trials # a RED word input is [1,0] to words_input_layer and GREEN word is [0,1] # a red color input is [1,0] to colors_input_layer and green color is [0,1] # a color-naming trial is [1,0] to task_layer and a word-reading trial is [0,1] def trial_dict(red_color, green_color, red_word, green_word, CN, WR): trialdict = { colors_input_layer: [red_color, green_color], words_input_layer: [red_word, green_word], task_layer: [CN, WR] } return trialdict # CREATE THRESHOLD FUNCTION # first value of DDM's value is DECISION_VARIABLE # context is always passed to Condition functions and is the context # in which the function gets called - below, during system execution def pass_threshold(mech1, mech2, thresh, context=None): results1 = mech1.output_ports[0].parameters.value.get(context) results2 = mech2.output_ports[0].parameters.value.get(context) for val in results1: if val >= thresh: return True for val in results2: if val >= thresh: return True return False accumulator_threshold = 1.0 mechanisms_to_update = [ colors_hidden_layer, words_hidden_layer, response_layer ] def switch_integrator_mode(mechanisms, mode): for mechanism in mechanisms: mechanism.integrator_mode = mode def switch_noise(mechanisms, noise): for mechanism in mechanisms: mechanism.noise.base = noise def switch_to_initialization_trial(mechanisms): # Turn off accumulation switch_integrator_mode(mechanisms, False) # Turn off noise switch_noise(mechanisms, 0) # Execute once per trial my_Stroop.termination_processing = { pnl.TimeScale.TRIAL: pnl.AllHaveRun() } def switch_to_processing_trial(mechanisms): # Turn on accumulation switch_integrator_mode(mechanisms, True) # Turn on noise switch_noise( mechanisms, psyneulink.core.components.functions.distributionfunctions. NormalDist(mean=0, standard_deviation=unit_noise).function) # Execute until one of the accumulators crosses the threshold my_Stroop.termination_processing = { pnl.TimeScale.TRIAL: pnl.While(pass_threshold, respond_red_accumulator, respond_green_accumulator, accumulator_threshold) } def switch_trial_type(): # Next trial will be a processing trial if isinstance( my_Stroop.termination_processing[pnl.TimeScale.TRIAL], pnl.AllHaveRun): switch_to_processing_trial(mechanisms_to_update) # Next trial will be an initialization trial else: switch_to_initialization_trial(mechanisms_to_update) CN_trial_initialize_input = trial_dict(0, 0, 0, 0, 1, 0) WR_trial_initialize_input = trial_dict(0, 0, 0, 0, 0, 1) # Start with an initialization trial switch_to_initialization_trial(mechanisms_to_update) my_Stroop.run( inputs=trial_dict(0, 1, 1, 0, 1, 0), # termination_processing=change_termination_processing, num_trials=4, call_after_trial=switch_trial_type)
def get_stroop_model(unit_noise_std=.01, dec_noise_std=.1): # model params integration_rate = 1 hidden_func = pnl.Logistic(gain=1.0, x_0=4.0) # input layer, color and word reward = pnl.TransferMechanism(name='reward') punish = pnl.TransferMechanism(name='punish') inp_clr = pnl.TransferMechanism( size=N_UNITS, function=pnl.Linear, name='COLOR INPUT' ) inp_wrd = pnl.TransferMechanism( size=N_UNITS, function=pnl.Linear, name='WORD INPUT' ) # task layer, represent the task instruction; color naming / word reading inp_task = pnl.TransferMechanism( size=N_UNITS, function=pnl.Linear, name='TASK' ) # hidden layer for color and word hid_clr = pnl.TransferMechanism( size=N_UNITS, function=hidden_func, integrator_mode=True, integration_rate=integration_rate, # noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, noise=pnl.NormalDist(standard_deviation=unit_noise_std), name='COLORS HIDDEN' ) hid_wrd = pnl.TransferMechanism( size=N_UNITS, function=hidden_func, integrator_mode=True, integration_rate=integration_rate, # noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, noise=pnl.NormalDist(standard_deviation=unit_noise_std), name='WORDS HIDDEN' ) # output layer output = pnl.TransferMechanism( size=N_UNITS, function=pnl.Logistic, integrator_mode=True, integration_rate=integration_rate, # noise=pnl.NormalDist(standard_deviation=unit_noise_std).function, noise=pnl.NormalDist(standard_deviation=unit_noise_std), name='OUTPUT' ) # decision layer, some accumulator signalSearchRange = pnl.SampleSpec(start=0.05, stop=5, step=0.05) decision = pnl.DDM(name='Decision', input_format=pnl.ARRAY, function=pnl.DriftDiffusionAnalytical(drift_rate=1, threshold =1, noise=1, starting_point=0, t0=0.35), output_ports=[pnl.RESPONSE_TIME, pnl.PROBABILITY_UPPER_THRESHOLD, pnl.PROBABILITY_LOWER_THRESHOLD] ) driftrate_control_signal = pnl.ControlSignal(projections=[(pnl.SLOPE, inp_clr)], variable=1.0, intensity_cost_function=pnl.Exponential(rate=1),#pnl.Exponential(rate=0.8),#pnl.Exponential(rate=1), allocation_samples=signalSearchRange) threshold_control_signal = pnl.ControlSignal(projections=[(pnl.THRESHOLD, decision)], variable=1.0, intensity_cost_function=pnl.Linear(slope=0), allocation_samples=signalSearchRange) reward_rate = pnl.ObjectiveMechanism(function=pnl.LinearCombination(operation=pnl.PRODUCT, exponents=[[1],[1],[-1]]), monitor=[reward, decision.output_ports[pnl.PROBABILITY_UPPER_THRESHOLD], decision.output_ports[pnl.RESPONSE_TIME]]) punish_rate = pnl.ObjectiveMechanism(function=pnl.LinearCombination(operation=pnl.PRODUCT, exponents=[[1],[1],[-1]]), monitor=[punish, decision.output_ports[pnl.PROBABILITY_LOWER_THRESHOLD], decision.output_ports[pnl.RESPONSE_TIME]]) objective_mech = pnl.ObjectiveMechanism(function=pnl.LinearCombination(operation=pnl.SUM, weights=[[1],[-1]]), monitor=[reward_rate, punish_rate]) # objective_mech = pnl.ObjectiveMechanism(function=object_function, # monitor=[reward, # punish, # decision.output_ports[pnl.PROBABILITY_UPPER_THRESHOLD], # decision.output_ports[pnl.PROBABILITY_LOWER_THRESHOLD], # (decision.output_ports[pnl.RESPONSE_TIME])]) # PROJECTIONS, weights copied from cohen et al (1990) wts_clr_ih = pnl.MappingProjection( matrix=[[2.2, -2.2], [-2.2, 2.2]], name='COLOR INPUT TO HIDDEN') wts_wrd_ih = pnl.MappingProjection( matrix=[[2.6, -2.6], [-2.6, 2.6]], name='WORD INPUT TO HIDDEN') wts_clr_ho = pnl.MappingProjection( matrix=[[1.3, -1.3], [-1.3, 1.3]], name='COLOR HIDDEN TO OUTPUT') wts_wrd_ho = pnl.MappingProjection( matrix=[[2.5, -2.5], [-2.5, 2.5]], name='WORD HIDDEN TO OUTPUT') wts_tc = pnl.MappingProjection( matrix=[[4.0, 4.0], [0, 0]], name='COLOR NAMING') wts_tw = pnl.MappingProjection( matrix=[[0, 0], [4.0, 4.0]], name='WORD READING') # build the model model = pnl.Composition(name='STROOP model') model.add_node(decision, required_roles=pnl.NodeRole.OUTPUT) model.add_node(reward, required_roles=pnl.NodeRole.OUTPUT) model.add_node(punish, required_roles=pnl.NodeRole.OUTPUT) model.add_linear_processing_pathway([inp_clr, wts_clr_ih, hid_clr]) model.add_linear_processing_pathway([inp_wrd, wts_wrd_ih, hid_wrd]) model.add_linear_processing_pathway([hid_clr, wts_clr_ho, output]) model.add_linear_processing_pathway([hid_wrd, wts_wrd_ho, output]) model.add_linear_processing_pathway([inp_task, wts_tc, hid_clr]) model.add_linear_processing_pathway([inp_task, wts_tw, hid_wrd]) model.add_linear_processing_pathway([output, pnl.IDENTITY_MATRIX, decision]) # 3/15/20 # model.add_linear_processing_pathway([output, [[1,-1]], (decision, pnl.NodeRole.OUTPUT)]) # 3/15/20 # model.add_linear_processing_pathway([output, [[1],[-1]], decision]) # 3/15/20 model.add_nodes([reward_rate, punish_rate]) controller = pnl.OptimizationControlMechanism(agent_rep=model, features=[inp_clr.input_port, inp_wrd.input_port, inp_task.input_port, reward.input_port, punish.input_port], feature_function=pnl.AdaptiveIntegrator(rate=0.1), objective_mechanism=objective_mech, function=pnl.GridSearch(), control_signals=[driftrate_control_signal, threshold_control_signal]) model.add_controller(controller=controller) # collect the node handles nodes = [inp_clr, inp_wrd, inp_task, hid_clr, hid_wrd, output, decision, reward, punish,controller] metadata = [integration_rate, dec_noise_std, unit_noise_std] return model, nodes, metadata
def _generate_layers(self): """ Generate the layers for this model. The hidden layers use an integrator mode, rate, and noise function. TODO: does the indirect pathway accumulate exactly the same as the hidden and output layers? :return: None, saves the layers into a whole bunch of members """ # Inputs self.color_input_layer = pnl.TransferMechanism(size=self.num_features, name='color_input') self.shape_input_layer = pnl.TransferMechanism(size=self.num_features, name='shape_input') # Task units self.color_task_layer = pnl.TransferMechanism(size=1, name='color_task') self.shape_task_layer = pnl.TransferMechanism(size=1, name='shape_task') # Hidden layers self.color_hidden_layer = pnl.TransferMechanism(size=self.hidden_layer_size, name='color_hidden', function=pnl.Logistic(gain=self.hidden_gain, bias=self.hidden_bias), integrator_mode=self.integrator_mode, integration_rate=self.integration_rate, noise=self._generate_noise_function()) self.shape_hidden_layer = pnl.TransferMechanism(size=self.hidden_layer_size, name='shape_hidden', function=pnl.Logistic(gain=self.hidden_gain, bias=self.hidden_bias), integrator_mode=self.integrator_mode, integration_rate=self.integration_rate, noise=self._generate_noise_function()) # self.color_dummy = pnl.TransferMechanism(size=self.hidden_layer_size, name='dummy') if self.indirect_path: self._generate_indirect_layer() # Output layers self.output_layer = pnl.TransferMechanism(size=self.num_features, name='output', function=pnl.Logistic, integrator_mode=self.integrator_mode, integration_rate=self.integration_rate, noise=self._generate_noise_function()) self.first_accumulator = pnl.IntegratorMechanism( function=pnl.SimpleIntegrator(noise=pnl.NormalDist(standard_dev=self.accumulator_noise_std).function, rate=self.accumulator_rate), name='first_response_accumulator') self.second_accumulator = pnl.IntegratorMechanism( function=pnl.SimpleIntegrator(noise=pnl.NormalDist(standard_dev=self.accumulator_noise_std).function, rate=self.accumulator_rate), name='second_response_accumulator') if self.log_values: self.log_layers = [self.color_hidden_layer, self.shape_hidden_layer, self.output_layer, self.first_accumulator, self.second_accumulator] if self.indirect_path: # Inserting there for it to appear in the correct order in output dataframe self.log_layers.insert(2, self.indirect_shape_layer) for layer in self.log_layers: layer.set_log_conditions('value')
def _generate_noise_function(self): """ Generate the noise function with the supplied `noise_std`, split to a member since this tends to recurr. :return: A PsyNeuLink noise function with a normal noise distribution """ return pnl.NormalDist(standard_dev=self.noise_std).function