def test_source_wet_is_delayed_by_one_k(): env = CrossAdaptiveEnv() action = env.action_space.sample() N = 2 for _ in range(N): env.step(action) assert env.source_dry.player.k == N assert env.target.player.k == N assert env.source_wet.player.k == N - 1
def run_offline_inference(agent: Trainer, env: CrossAdaptiveEnv): # NOTE: something is wrong here. For some reason, all the action values are too close to the bound done = False obs = env.reset() while not done: action = agent.compute_action(obs) # TODO: standardize action # it might be difficult to standardize the action in live mode, but offline inference essentially work obs, _, done, _ = env.step(action)
def test_lower_skew_factors_yield_lower_value(): action = 0.5 min_value = 0.0 max_value = 1.0 skew_factors = [0.5, 0.3] assert CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factors[0]) > CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factors[1])
def test_env_inits_and_makes_first_step_correctly(): env = CrossAdaptiveEnv() empty_features = np.zeros(shape=len(env.analyser.analysis_features)) initial_state = env.get_state() assert np.array_equal(initial_state, np.concatenate((empty_features, empty_features))) action = env.action_space.sample() state, reward, done, _ = env.step(action) assert done is True assert reward == 0.0 assert not np.array_equal(state, initial_state) assert np.abs(state.mean()) > 0.0
def test_non_debug_mode_does_not_define_debug_channels(): config = { **CROSS_ADAPTIVE_DEFAULT_CONFIG, "debug": False, } env = CrossAdaptiveEnv(config) debug_channels = list( map(lambda param: f"{param.name}{DEBUG_SUFFIX}", env.effect.parameters)) action = env.action_space.sample() env.step(action) source = env.render() for ch in debug_channels: assert f'chn_k "{ch}"' not in source.csd
def test_debug_mode_renders_channels_to_debug_wave_file(): config = { **CROSS_ADAPTIVE_DEFAULT_CONFIG, "debug": True, } env = CrossAdaptiveEnv(config) debug_channels = list( map(lambda param: f"{param.name}{DEBUG_SUFFIX}", env.effect.parameters)) action = env.action_space.sample() env.step(action) source = env.render() assert "fout" in source.csd for ch in debug_channels: assert f"upsamp(k_{ch})" in source.csd
def test_debug_mode_sets_debug_channels(): config = { **CROSS_ADAPTIVE_DEFAULT_CONFIG, "debug": True, } env = CrossAdaptiveEnv(config) debug_channels = list( map(lambda param: f"{param.name}{DEBUG_SUFFIX}", env.effect.parameters)) action = env.action_space.sample() env.step(action) source = env.render() debug_values = source.player.get_channels(debug_channels) for v in debug_values: assert env.action_space.low[0] < v < env.action_space.high[1]
def test_non_linear_mapping_still_obtains_the_max_value(): action = 1.0 min_value = 0.0 max_value = 1.0 skew_factor = 0.1 assert (CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factor) == 1.0)
def test_non_linear_mapping(): action = 0.5 min_value = 0.0 max_value = 1.0 skew_factor = 0.5 assert (CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factor) == 0.5625)
def test_source_wet_wraps_correctly_at_the_end_of_the_sound(): config = { **CROSS_ADAPTIVE_DEFAULT_CONFIG, "eval_interval": None, # episode is done at the end of the source } env = CrossAdaptiveEnv(config) action = env.action_space.sample() assert env.should_delay_source_wet_one_frame is True done = False while not done: _, _, done, _ = env.step(action) assert env.source_dry.player.k == 0 assert env.source_wet.player.k > 0 assert env.should_delay_source_wet_one_frame is False _, _, done, _ = env.step(action) assert env.source_wet.player.k == 0 assert env.source_dry.player.k == 1
def test_multiple_targets_are_allowed(): targets = ["amen_5s.wav", "drums_5s.wav"] config = { **CROSS_ADAPTIVE_DEFAULT_CONFIG.copy(), "targets": targets, "eval_interval": None, } env = CrossAdaptiveEnv(config) assert Path(env.target.input).name == targets[0] done = False while not done: action = env.action_space.sample() _, _, done, _ = env.step(action) assert Path(env.target.input).name == targets[1] done = False while not done: action = env.action_space.sample() _, _, done, _ = env.step(action) assert Path(env.target.input).name == targets[0]
def test_linear_mapping(): action = 0.5 min_value = 0.0 max_value = 1.0 skew_factor = 1.0 assert (CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factor) == 0.75) action = 0.0 min_value = 50 max_value = 20000 skew_factor = 1.0 assert (CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factor) == 10025) action = 1.0 min_value = 0.0 max_value = 1.0 skew_factor = 1.0 assert (CrossAdaptiveEnv.map_action_to_effect_parameter( action, min_value, max_value, skew_factor) == 1.0)
def test_source_wet_is_equal_to_previous_source_dry_when_effect_is_thru(): config = {**CROSS_ADAPTIVE_DEFAULT_CONFIG, "effect": "thru"} env = CrossAdaptiveEnv(config) env.step(env.action_space.sample()) source_dry_features_after_first_step = env.source_dry_features.copy() source_wet_features_after_first_step = env.source_wet_features.copy() assert np.array_equal( source_wet_features_after_first_step, np.zeros(shape=len(env.analyser.analysis_features)), ) env.step(env.action_space.sample()) source_dry_features_after_second_step = env.source_dry_features.copy() source_wet_features_after_second_step = env.source_wet_features.copy() assert np.array_equal(source_wet_features_after_second_step, source_dry_features_after_first_step) assert not np.array_equal(source_dry_features_after_second_step, source_dry_features_after_first_step)
def run_live_inference( agent: Trainer, env: CrossAdaptiveEnv, ): mediator = Mediator() episode_index = 0 while episode_index < 1500: source_features, target_features = mediator.get_features() if source_features is None or target_features is None: continue else: # trim off timestamp source_features = source_features[1:] target_features = target_features[1:] standardized_source = np.array([ env.standardizer.get_standardized_value( env.analyser.analysis_features[i], feature_value) for i, feature_value in enumerate(source_features) ]) standardized_target = np.array([ env.standardizer.get_standardized_value( env.analyser.analysis_features[i], feature_value) for i, feature_value in enumerate(target_features) ]) obs = np.concatenate((standardized_source, standardized_target)) print(np.round(obs, decimals=2)) action = agent.compute_action(obs) # action = env.action_space.sample() mapping = env.action_to_mapping(action) # print(mapping) mediator.send_effect_mapping(mapping) episode_index += 1 mediator.terminate() print("\n\n\tDONE\n\n")
def inference( config_path: str, checkpoint_path: str, source_sound: str = None, target_sound: str = None, render_to_dac=False, live_mode=True, ): """ Runs inference on a pretrained agent Args: config: config dict checkpoint_path: path to checkpoint from which to load the pretrained agent source_sound: an input sound source target_sound: a target sound source to evaluate the model against """ # NOTE: går an å teste om man egentlig trenger å sette config, siden jeg allerede gjør agent.restore() ray.init(local_mode=config["ray"]["local_mode"]) env_config = { "effect": config["env"]["effect"], "metric": config["env"]["metric"], "feature_extractors": config["env"]["feature_extractors"], "source": source_sound if source_sound else config["env"]["source"], "targets": [target_sound] if target_sound else config["env"]["targets"], "eval_interval": None, "render_to_dac": render_to_dac, "standardize_rewards": False, # NOTE: experimental feature "debug": config["env"]["debug"], } learning_rate = (config["agent"]["learning_rate"] if "learning_rate" in config["agent"].keys() else 3e-3) hidden_layers = config["agent"]["hidden_layers"] tanh = "tanh" common_config = { "env": CrossAdaptiveEnv, "env_config": env_config, "framework": "torch", "num_cpus_per_worker": config["ray"]["num_cpus_per_worker"], "log_level": config["ray"]["log_level"], # "observation_filter": "MeanStdFilter", # NB! some (old) runs didn't not include this, so that might cause crashes "num_workers": 0, "train_batch_size": 256, "explore": False, } def sac_trainer(): agent_name = "SAC" sac_config = { **sac.DEFAULT_CONFIG.copy(), **common_config.copy(), "learning_starts": 10000 if not checkpoint_path else 0, "target_entropy": -24, # set empirically after trials with dist_lpf "optimization": { "actor_learning_rate": learning_rate, "critic_learning_rate": learning_rate, "entropy_learning_rate": learning_rate, }, # Model options for the Q network(s). "Q_model": { "fcnet_activation": tanh, "fcnet_hiddens": hidden_layers, }, # Model options for the policy function. "policy_model": { "fcnet_activation": tanh, "fcnet_hiddens": hidden_layers, }, } return sac.SACTrainer, sac_config, agent_name def ppo_trainer(): agent_name = "PPO" ppo_config = { **ppo.DEFAULT_CONFIG.copy(), **common_config.copy(), "lr": learning_rate, "model": { "fcnet_hiddens": hidden_layers, "fcnet_activation": tanh, }, "sgd_minibatch_size": 64, # Coefficient of the entropy regularizer. Unused if a schedule if set "entropy_coeff": 0.0, # Decay schedule for the entropy regularizer. "entropy_coeff_schedule": None, } return ppo.PPOTrainer, ppo_config, agent_name agent = config["agent"]["agent"] available_trainers = ["sac", "ppo"] no_agent_error = ValueError(f"{agent} not available") if agent not in available_trainers: raise no_agent_error elif agent == "sac": trainer, agent_config, agent_name = sac_trainer() elif agent == "ppo": trainer, agent_config, agent_name = ppo_trainer() env = CrossAdaptiveEnv(env_config) agent = trainer(config=agent_config) agent.restore(checkpoint_path) if live_mode: run_live_inference(agent, env) else: run_offline_inference(agent, env)
def test_target_and_source_dry_has_no_effects(): env = CrossAdaptiveEnv() assert "aOut = aIn" in env.source_dry.csd assert "aOut = aIn" in env.target.csd assert "aOut = aIn" not in env.source_wet.csd