<jupyter_start><jupyter_text>Train and compare agents<jupyter_code>EPISODES = 100
env = gym.make('LunarSafe-v0')
baseline = sa.agents.BaselineAgent(env)
scores1, safety1 = baseline.train(episodes=EPISODES)
dqn = sa.agents.DQNAgent(env)
scores2, safety2 = dqn.train(episodes=EPISODES)
a2c = sa.agents.A2CAgent(env)
scores3, safety3 = a2c.train(episodes=EPISODES)
agents = ["baseline", "dqn", "a2c"]
scores = scores1 + scores2 + scores3
sa.utils.plot_multi_scores(agents, scores)
data = {'baseline': safety1, 'dqn': safety2, 'a2c': safety3}
sa.utils.plot_multi_safety(data)
print(f"baseline: unsafe {safety1[0].count(0)} - safe {safety1[0].count(1)}")
print(f"dqn: unsafe {safety2[0].count(0)} - safe {safety2[0].count(1)}")
print(f"a2c: unsafe {safety3[0].count(0)} - safe {safety3[0].count(1)}")<jupyter_output>baseline: unsafe 157 - safe 147
dqn: unsafe 42 - safe 39
a2c: unsafe 0 - safe 101<jupyter_text>Heuristic Safe Controllera small algorithm that ensures an agent's safety after it has been trained using the domain knowledge.<jupyter_code>from safe_agents.safety.heuristic import controller

render = True
episodes = 5
agents = dqn, a2c

for a in agents:
    total_reward = 0
    safe_a, unsafe_a = 0, 0
    print(a.__class__.__name__)
    for e in range(episodes):
        done, override = False, False
        safe, unsafe = 0, 0
        state = env.reset()
        while not done:
            if render: env.render(mode='human')
            if override:
                action = controller(env, state)
            else:
                action = a.get_action(state)
            state, r, done, info = env.step(action)
            total_reward += r
            if info['status']:
                safe += 1
                override = False
            else:
                unsafe += 1
                override = True
        safe_a = safe
        unsafe_a = unsafe
        print(f"\tepisode reward {total_reward}")
        print(f"\trisk ratio {unsafe/safe}\n")
    env.close()
    print("\t==============================")
    print(f"\ttotal reward {total_reward}")
    print(f"\tsafe states {safe_a} unsafe states {unsafe_a}\n")<jupyter_output>DQNAgent
	episode reward 162.65261291250624
	risk ratio 0.145475372279496

	episode reward 374.0568398902784
	risk ratio 0.32018561484918795

	episode reward 221.87650392481953
	risk ratio 2.9166666666666665

	episode reward 103.55761824372904
	risk ratio 0.0

	episode reward 232.55284200199284
	risk ratio 0.088139281828074

	==============================
	total reward 232.55284200199284
	safe states 919 unsafe states 81

A2CAgent
	episode reward 71.02982704269618
	risk ratio 4.116279069767442

	episode reward 92.99401898739418
	risk ratio 1.7796610169491525

	episode reward 79.22925020487168
	risk ratio 1.8414634146341464

	episode reward 72.72181099369783
	risk ratio 1.8133333333333332

	episode reward 252.76553298493548
	risk ratio 4.866666666666666

	==============================
	total reward 252.76553298493548
	safe states 60 unsafe states 292
{'fraction_non_alphanumeric': 0.1265319642265651, 'fraction_numerical': 0.14110632659821132, 'mean_word_length': 3.474074074074074, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '230300', 'license': 'MIT', 'n_tokens_mistral': 1369, 'n_tokens_neox': 1031, 'n_words': 254, 'path': 'notebooks/safety/heuristic.ipynb', 'repo_name': 'dmelichar/thesis-poc', 'size': '3019'}