def __init__(self, params: FlockPartialSwitchNodeGroupParams, name: str = "FlockPartialSwitchNodeGroup"): super().__init__(name, inputs=FlockPartialSwitchInputs(self), outputs=FlockPartialSwitchOutputs(self)) dim = 0 n_fork_1 = ForkNode( dim, [params.split_idx, params.flock_size - params.split_idx]) n_fork_2 = ForkNode( dim, [params.split_idx, params.flock_size - params.split_idx]) n_switch = SwitchNode(n_inputs=2) n_join = JoinNode(dim, n_inputs=2) self.add_node(n_fork_1) self.add_node(n_fork_2) self.add_node(n_switch) self.add_node(n_join) Connector.connect(self.inputs.input_1.output, n_fork_1.inputs.input) Connector.connect(self.inputs.input_2.output, n_fork_2.inputs.input) Connector.connect(n_fork_1.outputs[0], n_switch.inputs[0]) Connector.connect(n_fork_2.outputs[0], n_switch.inputs[1]) Connector.connect(n_switch.outputs.output, n_join.inputs[0]) Connector.connect(n_fork_2.outputs[1], n_join.inputs[1]) Connector.connect(n_join.outputs.output, self.outputs.output.input) self._n_switch = n_switch
def __init__(self): super().__init__("cuda") actions_descriptor = GridWorldActionDescriptor() node_action_monitor = ActionMonitorNode(actions_descriptor) grid_world_params = GridWorldParams('MapE') grid_world_params.tile_size = 3 node_grid_world = GridWorldNode(grid_world_params) random_action_generator = RandomNumberNode(upper_bound=len(actions_descriptor.action_names())) join_node = JoinNode(flatten=True) # GridWorld sizes width = grid_world_params.egocentric_width * grid_world_params.tile_size height = grid_world_params.egocentric_height * grid_world_params.tile_size fork_node = ForkNode(dim=0, split_sizes=[width * height, 4]) self.add_node(node_grid_world) self.add_node(node_action_monitor) self.add_node(random_action_generator) self.add_node(join_node) self.add_node(fork_node) Connector.connect(node_grid_world.outputs.egocentric_image, join_node.inputs[0]) Connector.connect(node_grid_world.outputs.output_action, join_node.inputs[1]) self._create_and_connect_agent(join_node, fork_node) Connector.connect(random_action_generator.outputs.one_hot_output, node_action_monitor.inputs.action_in) Connector.connect(node_action_monitor.outputs.action_out, node_grid_world.inputs.agent_action)
def _connect_expert_output(self): self.fork_node = ForkNode(1, [ self._almost_top_level_expert_output_size(self._params_list), self.se_io.get_num_labels() ]) self.add_node(self.fork_node) # top-level-expert -> fork Connector.connect( self._top_level_flock_node.outputs.sp.current_reconstructed_input, self.fork_node.inputs.input) # fork -> dataset/se Connector.connect(self.fork_node.outputs[1], self.se_io.inputs.agent_to_task_label, is_backward=True)
def __init__(self, input_data_size: int, labels_size: int, sp_params: Optional[ExpertParams] = None, name: str = "", seed: Optional[int] = None): super().__init__("SpReconstructionLayer", inputs=ClassificationInputs(self), outputs=ClassificationOutputs(self)) join_node = JoinNode(n_inputs=2, flatten=True, name=name + " Join") self.add_node(join_node) self.join_node = join_node Connector.connect(self.inputs.data.output, join_node.inputs[0]) Connector.connect(self.inputs.label.output, join_node.inputs[1]) unsqueeze_node = UnsqueezeNode(0) self.add_node(unsqueeze_node) Connector.connect(join_node.outputs.output, unsqueeze_node.inputs.input) if sp_params is None: sp_params = ExpertParams() sp_node = SpatialPoolerFlockNode(sp_params, name=name + " SP Expert", seed=seed) self.add_node(sp_node) self.sp_node = sp_node Connector.connect(unsqueeze_node.outputs.output, sp_node.inputs.sp.data_input) fork_node = ForkNode(1, [input_data_size, labels_size], name=name + " Fork") self.add_node(fork_node) self.fork_node = fork_node Connector.connect(sp_node.outputs.sp.current_reconstructed_input, fork_node.inputs.input) Connector.connect(fork_node.outputs[1], self.outputs.label.input)
def __init__(self, curriculum: tuple = (1, -1)): super().__init__() se_config = SpaceEngineersConnectorConfig() se_config.render_width = 16 se_config.render_height = 16 se_config.curriculum = list(curriculum) base_expert_params = ExpertParams() base_expert_params.flock_size = 1 base_expert_params.n_cluster_centers = 100 base_expert_params.compute_reconstruction = False base_expert_params.spatial.cluster_boost_threshold = 1000 base_expert_params.spatial.learning_rate = 0.2 base_expert_params.spatial.batch_size = 1000 base_expert_params.spatial.buffer_size = 1010 base_expert_params.spatial.learning_period = 100 base_expert_params.temporal.batch_size = 1000 base_expert_params.temporal.buffer_size = 1010 base_expert_params.temporal.learning_period = 200 base_expert_params.temporal.forgetting_limit = 20000 # parent_expert_params = ExpertParams() # parent_expert_params.flock_size = 1 # parent_expert_params.n_cluster_centers = 20 # parent_expert_params.compute_reconstruction = True # parent_expert_params.temporal.exploration_probability = 0.9 # parent_expert_params.spatial.cluster_boost_threshold = 1000 # parent_expert_params.spatial.learning_rate = 0.2 # parent_expert_params.spatial.batch_size = 1000 # parent_expert_params.spatial.buffer_size = 1010 # parent_expert_params.spatial.learning_period = 100 # parent_expert_params.temporal.context_without_rewards_size = se_config.LOCATION_SIZE_ONE_HOT # SE nodes actions_descriptor = SpaceEngineersActionsDescriptor() node_se_connector = SpaceEngineersConnectorNode( actions_descriptor, se_config) node_action_monitor = ActionMonitorNode(actions_descriptor) # flock-related nodes flock_node = ExpertFlockNode(base_expert_params) blank_task_control = ConstantNode((se_config.TASK_CONTROL_SIZE, )) blank_task_labels = ConstantNode((20, )) # parent_flock_node = ExpertFlockNode(parent_expert_params) join_node = JoinNode(flatten=True) actions = ['FORWARD', 'BACKWARD', 'LEFT', 'RIGHT'] action_count = len(actions) pass_actions_node = PassNode(output_shape=(action_count, ), name="pass actions") fork_node = ForkNode( 0, [base_expert_params.n_cluster_centers, action_count]) def squeeze(inputs, outputs): outputs[0].copy_(inputs[0].squeeze()) squeeze_node = LambdaNode( squeeze, 1, [(base_expert_params.n_cluster_centers + action_count, )], name="squeeze lambda node") def stack_and_unsqueeze(inputs, outputs): outputs[0].copy_(torch.stack([inputs[0], inputs[1]]).unsqueeze(0)) stack_unsqueeze_node = LambdaNode( stack_and_unsqueeze, 2, [(1, 2, se_config.LOCATION_SIZE_ONE_HOT)], name="stack and unsqueeze node") to_one_hot_node = ToOneHotNode() action_parser_node = AgentActionsParserNode(actions_descriptor, actions) random_node = RandomNumberNode(0, action_count, name="random action generator", generate_new_every_n=5, randomize_intervals=True) switch_node = SwitchNode(2) # add nodes to the graph self.add_node(flock_node) # self.add_node(parent_flock_node) self.add_node(node_se_connector) self.add_node(node_action_monitor) self.add_node(blank_task_control) self.add_node(blank_task_labels) # self.add_node(join_node) # self.add_node(fork_node) # self.add_node(pass_actions_node) # self.add_node(squeeze_node) # self.add_node(to_one_hot_node) # self.add_node(stack_unsqueeze_node) self.add_node(action_parser_node) self.add_node(random_node) # self.add_node(switch_node) # first layer Connector.connect(node_se_connector.outputs.image_output, flock_node.inputs.sp.data_input) # Connector.connect( # flock_node.outputs.tp.projection_outputs, # join_node.inputs[0] # ) # Connector.connect( # pass_actions_node.outputs.output, # join_node.inputs[1] # ) # # second layer # Connector.connect( # join_node.outputs.output, # parent_flock_node.inputs.sp.data_input # ) # Connector.connect( # node_se_connector.outputs.task_to_agent_location_one_hot, # stack_unsqueeze_node.inputs[0] # ) # Connector.connect( # node_se_connector.outputs.task_to_agent_location_target_one_hot, # stack_unsqueeze_node.inputs[1] # ) # Connector.connect( # stack_unsqueeze_node.outputs[0], # parent_flock_node.inputs.tp.context_input # ) # # # actions # Connector.connect( # parent_flock_node.outputs.sp.predicted_reconstructed_input, # squeeze_node.inputs[0] # ) # Connector.connect( # squeeze_node.outputs[0], # fork_node.inputs.input # ) # Connector.connect( # fork_node.outputs[1], # to_one_hot_node.inputs.input # ) # Connector.connect( # random_node.outputs.one_hot_output, # switch_node.inputs[0] # ) # Connector.connect( # to_one_hot_node.outputs.output, # switch_node.inputs[1] # ) # Connector.connect( # switch_node.outputs.output, # action_parser_node.inputs.input # ) # directly use random exploration Connector.connect(random_node.outputs.one_hot_output, action_parser_node.inputs.input) Connector.connect(action_parser_node.outputs.output, node_action_monitor.inputs.action_in) # Connector.connect( # switch_node.outputs.output, # pass_actions_node.inputs.input, # is_low_priority=True # ) Connector.connect( node_action_monitor.outputs.action_out, node_se_connector.inputs.agent_action, # is_low_priority=True is_backward=False) # blank connection Connector.connect(blank_task_control.outputs.output, node_se_connector.inputs.task_control) Connector.connect(blank_task_labels.outputs.output, node_se_connector.inputs.agent_to_task_label) # Save the SE connector so we can check testing/training phase. # When the se_io interface has been added, this can be removed. self._node_se_connector = node_se_connector
def create_topology(self): """ +----------------+ +-------------+ | dataset_switch | | | +--+-----+-------+ | v | | | +----------+------------+ | | | | context_feedback_pass | | | | +--------------------+--+ | | | | | | | v v | | +-------+------+--+ | | | gate_input_join | | | +-------+---------+ | | | | | v | | +--------+---------+ | | | gate_input_noise | | | +--------+---------+ | | | | | v | | +---+--+ | | | gate | | | +---+--+ | | | | | v | | +-------+--------+ +--------+ | | format_context | | | | +-------+--------+ | | | | v | | | +------+-----+ | | ---->-+ specialist | | | +--+--------++ | | | | | +--------------------------------+ v v ++--------++ | accuracy | +----------+ """ n_gate = SpatialPoolerFlockNode( ExpertParams(flock_size=self._params.flock_size, n_cluster_centers=self._params.seq_count, spatial=SpatialPoolerParams( # input_size=3, enable_learning=True, buffer_size=self._params.gate_buffer_size, batch_size=100, learning_rate=0.2, learning_period=10, cluster_boost_threshold=100, max_boost_time=200 ), ), name="Gate" ) self.add_node(n_gate) # Specialist n_specialist = SpecialistNodeGroup(SpecialistNodeGroupParams( flock_size=self._params.flock_size, n_symbols=len(self._params.symbols), gate_input_context_multiplier=self._params.gate_input_context_multiplier, gate_input_context_avg_window_size=self._params.gate_input_context_avg_window_size, seq_count=self._params.seq_count, convert_context_to_one_hot=self._params.convert_context_to_one_hot )) self.add_node(n_specialist) self._n_specialist = n_specialist n_context_feedback_pass = PassNode((self._params.flock_size, self._params.seq_count)) n_gate_input_join = JoinNode(dim=1, n_inputs=2) n_gate_input_noise = RandomNoiseNode(RandomNoiseParams(amplitude=0.0001)) n_format_context = SPFormatContextNodeGroup(self._params.seq_count, self._params.flock_size) self.add_node(n_context_feedback_pass) self.add_node(n_gate_input_join) self.add_node(n_gate_input_noise) self.add_node(n_format_context) # Dataset n_dataset_switch = DatasetSwitchNodeGroup(DatasetSwitchNodeGroupParams( dataset_params=DatasetAlphabetNodeGroupParams( flock_size=self._params.flock_size, symbols=self._params.symbols, seq_length=self._params.seq_length, seq_count=self._params.seq_count, seq_repeat=self._params.seq_repeat ), flock_split=self._params.flock_split )) self._n_dataset_switch = n_dataset_switch self.add_node(n_dataset_switch) # dataset to specialist Connector.connect(n_dataset_switch.outputs.output, n_specialist.inputs.input) # specialist to gate Connector.connect(n_specialist.outputs.context_feedback, n_context_feedback_pass.inputs.input, is_backward=True) Connector.connect(n_context_feedback_pass.outputs.output, n_gate_input_join.inputs[0]) # dataset to gate Connector.connect(n_dataset_switch.outputs.sequence_id_one_hot, n_gate_input_join.inputs[1]) Connector.connect(n_gate_input_join.outputs.output, n_gate_input_noise.inputs.input) Connector.connect(n_gate_input_noise.outputs.output, n_gate.inputs.sp.data_input) # gate to specialist Connector.connect(n_gate.outputs.sp.forward_clusters, n_format_context.inputs.input) Connector.connect(n_format_context.outputs.output, n_specialist.inputs.context_input) # Measuring accuracy # Fork n_fork_dataset = ForkNode(0, [self._params.flock_split, self._params.flock_size - self._params.flock_split]) n_fork_prediction = ForkNode(0, [self._params.flock_split, self._params.flock_size - self._params.flock_split]) self.add_node(n_fork_dataset) self.add_node(n_fork_prediction) Connector.connect(n_dataset_switch.outputs.output, n_fork_dataset.inputs.input) Connector.connect(n_specialist.outputs.output, n_fork_prediction.inputs.input) self._n_accuracy_single_1 = AccuracyNode(1, name='Accuracy single 1') self.add_node(self._n_accuracy_single_1) Connector.connect(n_fork_dataset.outputs[0], self._n_accuracy_single_1.inputs.input_a) Connector.connect(n_fork_prediction.outputs[0], self._n_accuracy_single_1.inputs.input_b) self._n_accuracy_single_2 = AccuracyNode(1, name='Accuracy single 2') self.add_node(self._n_accuracy_single_2) Connector.connect(n_fork_dataset.outputs[1], self._n_accuracy_single_2.inputs.input_a) Connector.connect(n_fork_prediction.outputs[1], self._n_accuracy_single_2.inputs.input_b) self._n_accuracy_1 = AccuracyNode(self._params.accuracy_average_steps, name='Accuracy 1') self.add_node(self._n_accuracy_1) Connector.connect(n_fork_dataset.outputs[0], self._n_accuracy_1.inputs.input_a) Connector.connect(n_fork_prediction.outputs[0], self._n_accuracy_1.inputs.input_b) self._n_accuracy_2 = AccuracyNode(self._params.accuracy_average_steps, name='Accuracy 2') self.add_node(self._n_accuracy_2) Connector.connect(n_fork_dataset.outputs[1], self._n_accuracy_2.inputs.input_a) Connector.connect(n_fork_prediction.outputs[1], self._n_accuracy_2.inputs.input_b)
def __init__(self, action_count=4, location_vector_size=100, use_grayscale: bool = False): super().__init__("Task 1 - Basic expert", inputs=Task1BasicExpertGroupInputs(self), outputs=Task1BasicExpertGroupOutputs(self)) base_expert_params = ExpertParams() base_expert_params.flock_size = 1 base_expert_params.n_cluster_centers = 100 base_expert_params.compute_reconstruction = False base_expert_params.spatial.cluster_boost_threshold = 1000 base_expert_params.spatial.learning_rate = 0.2 base_expert_params.spatial.batch_size = 1000 base_expert_params.spatial.buffer_size = 1010 base_expert_params.spatial.learning_period = 100 parent_expert_params = ExpertParams() parent_expert_params.flock_size = 1 parent_expert_params.n_cluster_centers = 20 parent_expert_params.compute_reconstruction = True parent_expert_params.temporal.exploration_probability = 0.9 parent_expert_params.spatial.cluster_boost_threshold = 1000 parent_expert_params.spatial.learning_rate = 0.2 parent_expert_params.spatial.batch_size = 1000 parent_expert_params.spatial.buffer_size = 1010 parent_expert_params.spatial.learning_period = 100 parent_expert_params.temporal.context_without_rewards_size = location_vector_size # flock-related nodes flock_node = ExpertFlockNode(base_expert_params) parent_flock_node = ExpertFlockNode(parent_expert_params) join_node = JoinNode(flatten=True) unsqueeze_node_to_base_expert = UnsqueezeNode(0) unsqueeze_node_to_parent_expert = UnsqueezeNode(0) fork_node = ForkNode( 0, [base_expert_params.n_cluster_centers, action_count]) def squeeze(inputs, outputs): outputs[0].copy_(inputs[0].squeeze()) squeeze_node = LambdaNode( squeeze, 1, [(base_expert_params.n_cluster_centers + action_count, )], name="squeeze lambda node") def stack_and_unsqueeze(inputs, outputs): outputs[0].copy_(torch.stack([inputs[0], inputs[1]]).unsqueeze(0)) stack_unsqueeze_node = LambdaNode(stack_and_unsqueeze, 2, [(1, 2, location_vector_size)], name="stack and unsqueeze node") # add nodes to the graph self.add_node(flock_node) self.add_node(unsqueeze_node_to_base_expert) self.add_node(parent_flock_node) self.add_node(unsqueeze_node_to_parent_expert) self.add_node(join_node) self.add_node(fork_node) self.add_node(squeeze_node) self.add_node(stack_unsqueeze_node) Connector.connect(self.inputs.actions.output, join_node.inputs[1]) if use_grayscale: grayscale_node = GrayscaleNode(squeeze_channel=True) self.add_node(grayscale_node) Connector.connect(self.inputs.image.output, grayscale_node.inputs.input) Connector.connect(grayscale_node.outputs.output, unsqueeze_node_to_base_expert.inputs.input) else: Connector.connect(self.inputs.image.output, unsqueeze_node_to_base_expert.inputs.input) Connector.connect(unsqueeze_node_to_base_expert.outputs.output, flock_node.inputs.sp.data_input) Connector.connect(self.inputs.current_location.output, stack_unsqueeze_node.inputs[0]) Connector.connect(self.inputs.target_location.output, stack_unsqueeze_node.inputs[1]) Connector.connect(fork_node.outputs[1], self.outputs.actions.input) # first layer Connector.connect(flock_node.outputs.tp.projection_outputs, join_node.inputs[0]) # second layer Connector.connect(join_node.outputs.output, unsqueeze_node_to_parent_expert.inputs.input) # second layer Connector.connect(unsqueeze_node_to_parent_expert.outputs.output, parent_flock_node.inputs.sp.data_input) Connector.connect(stack_unsqueeze_node.outputs[0], parent_flock_node.inputs.tp.context_input) # actions Connector.connect( parent_flock_node.outputs.sp.predicted_reconstructed_input, squeeze_node.inputs[0]) Connector.connect(squeeze_node.outputs[0], fork_node.inputs.input)