def test_sync_functionality(self): # Two Components, one with Synchronizable dropped in: # A: Can only push out values. # B: To be synced by A's values. sync_from = MyCompWithVars(scope="sync-from") sync_to = MyCompWithVars(initializer1=8.0, initializer2=7.0, scope="sync-to", synchronizable=True) # Create a dummy test component that contains our two Synchronizables. container = Component(name="container") container.add_components(sync_from, sync_to) @rlgraph_api(component=container) def execute_sync(self): values_ = sync_from.variables() return sync_to.sync(values_) test = ComponentTest(component=container) # Test syncing the variable from->to and check them before and after the sync. # Before the sync. test.variable_test(sync_to.get_variables(VARIABLE_NAMES), { "sync-to/"+VARIABLE_NAMES[0]: np.full(shape=sync_from.space.shape, fill_value=8.0), "sync-to/"+VARIABLE_NAMES[1]: np.full(shape=sync_from.space.shape, fill_value=7.0) }) # Now sync and re-check. test.test("execute_sync", expected_outputs=None) # After the sync. test.variable_test(sync_to.get_variables(VARIABLE_NAMES), { "sync-to/"+VARIABLE_NAMES[0]: np.zeros(shape=sync_from.space.shape), "sync-to/"+VARIABLE_NAMES[1]: np.ones(shape=sync_from.space.shape) })
def test_exploration_with_continuous_action_space(self): # TODO not portable, redo with more general mean/stddev checks over a sample of distributed outputs. return # 2x2 action-pick, each composite action with 5 categories. action_space = FloatBox(shape=(2,2), add_batch_rank=True) distribution = Normal() action_adapter = ActionAdapter(action_space=action_space) # Our distribution to go into the Exploration object. nn_output_space = FloatBox(shape=(13,), add_batch_rank=True) # 13: Any flat nn-output should be ok. exploration = Exploration.from_spec(dict(noise_spec=dict(type="gaussian_noise", mean=10.0, stddev=2.0))) # The Component to test. exploration_pipeline = Component(scope="continuous-plus-noise") exploration_pipeline.add_components(action_adapter, distribution, exploration, scope="exploration-pipeline") @rlgraph_api(component=exploration_pipeline) def get_action(self_, nn_output): _, parameters, _ = action_adapter.get_logits_probabilities_log_probs(nn_output) sample_stochastic = distribution.sample_stochastic(parameters) sample_deterministic = distribution.sample_deterministic(parameters) action = exploration.get_action(sample_stochastic, sample_deterministic) return action @rlgraph_api(component=exploration_pipeline) def get_noise(self_): return exploration.noise_component.get_noise() test = ComponentTest(component=exploration_pipeline, input_spaces=dict(nn_output=nn_output_space), action_space=action_space) # Collect outputs in `collected` list to compare moments. collected = list() for _ in range_(1000): test.test("get_noise", fn_test=lambda component_test, outs: collected.append(outs)) self.assertAlmostEqual(10.0, np.mean(collected), places=1) self.assertAlmostEqual(2.0, np.std(collected), places=1) np.random.seed(10) input_ = nn_output_space.sample(size=3) expected = np.array([[[13.163095, 8.46925], [10.375976, 5.4675055]], [[13.239931, 7.990649], [10.03761, 10.465796]], [[10.280741, 7.2384844], [10.040194, 8.248206]]], dtype=np.float32) test.test(("get_action", input_), expected_outputs=expected, decimals=3)
def test_call_in_comprehension(self): container = Component(scope="container") sub_comps = [Dummy1To1(scope="dummy-{}".format(i)) for i in range(3)] container.add_components(*sub_comps) # Define container's API: @rlgraph_api(name="test", component=container) def container_test(self_, input_): # results = [] # for i in range(len(sub_comps)): # results.append(sub_comps[i].run(input_)) results = [x.run(input_) for x in sub_comps] return self_._graph_fn_sum(*results) @graph_fn(component=container) def _graph_fn_sum(self_, *inputs): return sum(inputs) test = ComponentTest(component=container, input_spaces=dict(input_=float)) test.test(("test", 1.23), expected_outputs=len(sub_comps) * (1.23 + 1), decimals=2)