Giter Site home page Giter Site logo

dstl / yawning-titan Goto Github PK

View Code? Open in Web Editor NEW
54.0 8.0 15.0 22.13 MB

YAWNING TITAN is an abstract, graph based cyber-security simulation environment that supports the training of intelligent agents for autonomous cyber operations.

License: MIT License

Python 71.84% Jupyter Notebook 3.43% TypeScript 15.49% JavaScript 2.91% SCSS 0.48% HTML 3.77% Batchfile 0.03% Shell 0.03% CSS 2.03%
autonomous-agents cybersecurity openai-gym openai-gym-environment reinforcement-learning rl-environment

yawning-titan's Introduction

Python GitHub GitHub Workflow Status GitHub Workflow Status GitHub release (latest SemVer) GitHub commits since latest release (by SemVer) ![GitHub issue custom search](https://img.shields.io/github/issues-search?label=active%20bug%20issues& ![GitHub issue custom search](https://img.shields.io/github/issues-search?label=active%20feature%20requests& GitHub Discussions

YAWNING-TITAN

About The Project

YAWNING-TITAN (YT) is an abstract, graph based cyber-security simulation environment that supports the training of intelligent agents for autonomous cyber operations. YAWNING-TITAN currently only supports defensive autonomous agents who face off against probabilistic red agents.

YT has been designed with the following things in mind:

  • Simplicity over complexity
  • Minimal Hardware Requirements
  • Operating System agnostic
  • Support for a wide range of algorithms
  • Enhanced agent/policy evaluation support
  • Flexible environment and game rule configuration
  • Generation of evaluation episode visualisations (gifs)

YT was publicly released on 20th July 2022 under MIT licence. It will continue to be developed through the Autonomous Resilient Cyber Defence (ARCD) project, overseen by Dstl.

Contributing to YAWNING-TITAN

Found a bug, have an idea/feature you'd like to suggest, or just want to get involved with the YT community, please read our How to contribute to YAWNING-TITAN? guidelines.

What's YAWNING-TITAN built with

Getting Started with YAWNING-TITAN

Pre-Requisites

In order to get YT installed, you will need to have the following installed:

  • python3.8+
  • python3-pip
  • virtualenv

YT is designed to be OS-agnostic, and thus should work on most variations/distros of Linux, Windows, and MacOS.

Installation from source

1. Navigate to the YAWNING-TITAN folder and create a new python virtual environment (venv)

python3 -m venv <name_of_venv>

2. Activate the venv

Unix
source <name_of_venv>/bin/activate
Windows
.\<name_of_venv>\Scripts\activate

3. Install yawning-titan into the venv along with all of it's dependencies

python3 -m pip install -e .

This will install all the dependencies including algorithm libraries. These libraries all use torch. If you'd like to install tensorflow for use with Rllib, you can do this manually or install tensorflow as an optional dependency by postfixing the command in step 3 above with the [tensorflow] extra. Example:

python3 -m pip install -e .[tensorflow]

Development Installation

To install the development dependencies, postfix the command in step 3 above with the [dev] extra. Example:

python3 -m pip install -e .[dev]

Application Directories

Upon install, YT creates a set of application directories, both hidden for YT use, and visible for user use. The created directory trees for Linux, Windows, and MacOS operating systems are detailed below:

Linux
~/
├─ .cache/
│  ├─ yawning_titan/
│  │  ├─ log/
├─ .config/
│  ├─ yawning_titan/
├─ .local/
│  ├─ share/
│  │  ├─ yawning_titan/
│  │  │  ├─ app_images/
│  │  │  ├─ db/
│  │  │  ├─ docs/
├─ yawning_titan/
│  ├─ agents/
│  ├─ game_modes/
│  ├─ images/
│  ├─ notebooks/
Windows
~/
├─ AppData/
│  ├─ yawning_titan/
│  │  ├─ app_images/
│  │  ├─ config/
│  │  ├─ db/
│  │  ├─ docs/
│  │  ├─ logs/
├─ yawning_titan/
│  ├─ agents/
│  ├─ game_modes/
│  ├─ images/
│  ├─ notebooks/
MacOS
~/
├─ Library/
│  ├─ Application Support/
│  │  ├─ Logs/
│  │  │  ├─ yawning_titan/
│  │  │  │  ├─ log/
│  │  ├─ Preferences/
│  │  │  ├─ yawning_titan/
│  │  ├─ yawning_titan/
│  │  │  ├─ app_images/
│  │  │  ├─ db/
│  │  │  ├─ docs/
├─ yawning_titan/
│  ├─ agents/
│  ├─ game_modes/
│  ├─ images/
│  ├─ notebooks/

Documentation

YT comes with a full set of documentation created using the Sphinx documentation library and are hosted on GitHub pages at https://dstl.github.io/YAWNING-TITAN.

These docs can also be built manually from the cloned repo by using the following commands:

This will require the development dependencies to be installed, see Development Installation

Unix
cd docs
make html
Windows
cd docs
.\make.bat html

This will build the documentation as a collection of HTML files which uses the Read The Docs sphinx theme. Other build options are available but may require additional dependencies such as LaTeX and PDF. Please refer to the Sphinx documentation for your specific output requirements.

Example Notebooks

A collection of example notebooks have been provided. The original versions of these notebooks stored in yawning_titan/notebooks/_package_data and are copied over to the newly created users notebooks application directory (~/yawning_titan/notebooks) at install. These are the best place to start if you want to get a feel for YT before builidng the docs and exploring further. If the notebooks become corrupted in the users notebooks application directory, they can be reset running the following commands from an interactive Python session on your venv:

from yawning_titan.notebooks.jupyter import reset_default_jupyter_notebooks
reset_default_jupyter_notebooks(overwrite_existing=True)

Cite This Work

If you would like to include a citation for YT in your work, please cite the paper published at the ICML 2022 ML4Cyber Workshop.

@inproceedings{inproceedings,
 author = {Andrew, Alex and Spillard, Sam and Collyer, Joshua and Dhir, Neil},
 year = {2022},
 month = {07},
 title = {Developing Optimal Causal Cyber-Defence Agents via Cyber Security Simulation},
 maintitle = {International Confernece on Machine Learning (ICML)},
 booktitle = {Workshop on Machine Learning for Cybersecurity (ML4Cyber)}
}

License

YAWNING-TITAN is released under MIT license. Please see LICENSE for details.

Related Environments

You may also wish to explore the PrimAITE environment, an effective simulation capability for the purposes of training and evaluating AI in a cyber-defensive role: https://github.com/Autonomous-Resilient-Cyber-Defence/PrimAITE

yawning-titan's People

Contributors

br0kej avatar chrismccarthydev avatar ctyler-dstl avatar czar-ec-envitia avatar dependabot[bot] avatar jamesshort1 avatar jcollyer-dstl avatar rumbelows avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yawning-titan's Issues

Signature of NetworkInterface causing issues in a few files

Describe the bug
The __init__ method in NetworkInterface changed and no longer allows for settings_path. This causes rl_baseline.py to fail.

To Reproduce
Steps to reproduce the behaviour:

  1. run rl_baseline.py
  2. TypeError

Expected behaviour
I expect the file to run to completion.

Environment (please complete the following information):

  • OS: Ubuntu 18.04
  • Python: 3.8.15
  • YT Version: 1.0.0
  • Software: Google Colab/Notebook

Additional context
This seems like more of a simple oversight than a bug. It looks like there's a new way to do the same thing.

Non reproducibility

There are two issues in the RedActionSet class which prevent reproducible experiments.

possible_to_attack is turned from a set of strings to a list of strings, this produces non-reproducible results. As seen by running the code below twice.

random.seed(0)
possible_to_attack = set()

for i in range(100):
    possible_to_attack.add(str(i))

possible_to_attack = list(possible_to_attack)
print(random.choices(possible_to_attack,k=1))

This can be fixed by sorting the list. The problem might also occur with the connected list (although it doesn't appear so).

    possible_to_attack = list(possible_to_attack)
    # FIXED
    possible_to_attack.sort()

A better fix would likely be for nodes to be integers instead of strings.

set_of_spreading_nodes is iterated through in a for loop which also leads to non-reproducible results since it generates random numbers.

        for node in set_of_spreading_nodes:
            if (
                random.randint(0, 100)
                < self.network_interface.red_chance_to_spread_to_connected_node
                * 100
            ):

A simple (ugly) fix is below

    # FIXED
    set_of_spreading_nodes = list(set_of_spreading_nodes)
    set_of_spreading_nodes.sort()
    
    if self.network_interface.red_chance_to_spread_to_connected_node > 0:
        for node in set_of_spreading_nodes:

Suggestion: adding the isolated state to observation

Including isolation_status to OBSERVATION_SPACE in the configuration file, and then adding the if statement in get_current_observation, as the agent will struggle in training with isolate/connect without it (since it currently needs to understand more complex relationships with the adjacency matrix). A simple fix in the meantime is below.

    # Gets the adj matrix for the current graph
    node_connections = []

    # ADDED
    isolated_state = []

    if self.obs_node_connections:
        node_connections = self.adj_matrix
        # pads the array to account for any missing deceptive nodes that may not have been placed yet
        node_connections = np.pad(node_connections, (0, open_spaces), "constant")

        # ADDED
        isolated_state = np.asarray(
            list(self.get_attributes_from_key("isolated").values())
        ).astype(int)
        # does it make sense to isolate a deceptive node?
        isolated_state = np.pad(isolated_state, (0, open_spaces), "constant")

then including the variable in the obs, and making the required changes in get_observation_size. With this change it might also make sense for the node_connections to remain static despite nodes being isolated. This intuitively makes sense since the decision of reconnecting a node will depend on the true adjacency matrix.

Suggestion: check if a node is connected to an indirect specific node (e.g., high_value_target)

Hello,

In complex networks, it would be useful to know if a node is connected to another one in an indirect way.

The getter functions from network_interface, get_base_connected_nodes and get_current_connected_nodes, returns only (as far as I have understood) the nodes directly (edge =1) connected to an input node.

Instead the networkx function node_connectivity(input_graph, node_to_check, specific_node) returns all the possible paths that connects the node_to_check to a target_node (0 if there are none, 1/2/N depending on how many paths are present).
In this way it can be possible to check and count how many nodes are affected in case of the isolation of a gateway node to preserve a high_value_target or similar decisions.

Hope this helps,
Cheers,

high_value_target not working with lose_when_high_value_target_lost setting (i.e self.gr_loss_hvt is True)

self.possible_high_value_targets = []

quick fix:

    self.possible_high_value_targets = [] if high_value_target is None else [high_value_target]

As a sidenote, it will only select a random new hvt if new random entry nodes are also set, i.e in the RESET part of the config file

  choose_new_high_value_target_on_reset: False
  choose_new_entry_nodes_on_reset: False

but not an issue in my opinion as I can't think of a case where the hvt changes but the entry nodes need to remain the same on resets.

Isolation cost/reward

Blue agents can simply isolate entry nodes and incur the one step cost with no further penalties throughout the episode (or isolate other nodes such as the hvt). The isolation cost should be incurred at each step until the node is reconnected. An example implementation in standard_rewards is shown below.

# cost for actions
action_cost = {
    "reduce_vulnerability": 0.5,
    "restore_node": 1,
    "make_node_safe": 0.5,
    "scan": 0,
    "isolate": 10, # should be less or equal to restore_node cost for a step, so between 0.5 and 1 instead of 10
    "connect": 0,
    "do_nothing": -0.5,
    "add_deceptive_node": 8,
}

# don't count isolation cost twice
reward = -action_cost[blue_action] if blue_action != "isolate" else 0
# while nodes are still isolated include the "isolate" cost
reward += -action_cost["isolate"] * sum(end_isolation.values())

[BUG] Action indices randomised on environment initialisation

There is a problem in Yawning Titan with how actions are assigned to indexes, affecting the performance of trained RL agents:

-In YT 1.0.1 (and it appears 2.0.0), action indices are randomly set on environment initialisation as the nodes are ordered by sorting a dictionary.
-This means the same action index will correspond to a different node across different instances of the environment (shown to the right).
-Therefore, unless the environment instance is saved, an RL agent cannot be deployed after training.
-However, this will always cause problems when training using parallel vector environments.

Environment Action Indexes:
Idx: 0 Node: None Tech: scan
Idx: 1 Node: None Tech: do_nothing
Idx: 2 Node: 6 Tech: reduce_vulnerability
Idx: 3 Node: 6 Tech: restore_node
Idx: 4 Node: 6 Tech: make_node_safe
Idx: 5 Node: 6 Tech: isolate
Idx: 6 Node: 6 Tech: connect
Idx: 7 Node: 11 Tech: reduce_vulnerability
Idx: 8 Node: 11 Tech: restore_node
Idx: 9 Node: 11 Tech: make_node_safe

Re-Initialise Environment:
Idx: 0 Node: None Tech: scan
Idx: 1 Node: None Tech: do_nothing
Idx: 2 Node: 19 Tech: reduce_vulnerability
Idx: 3 Node: 19 Tech: restore_node
Idx: 4 Node: 19 Tech: make_node_safe
Idx: 5 Node: 19 Tech: isolate
Idx: 6 Node: 19 Tech: connect
Idx: 7 Node: 22 Tech: reduce_vulnerability
Idx: 8 Node: 22 Tech: restore_node
Idx: 9 Node: 22 Tech: make_node_safe

[BUG] Saved GIFs seem to be zoomed-in on only part of the network

Describe the bug
When rendering the network, the animation displays fine on the screen (although there are two figures). When saving the GIF it saves zoomed-in on only part of the network.

To Reproduce
Steps to reproduce the behaviour:

from stable_baselines3.common.env_checker import check_env
from stable_baselines3.common.evaluation import evaluate_policy
from stable_baselines3 import PPO
from stable_baselines3.ppo import MlpPolicy as PPOMlp

from yawning_titan.envs.generic.core.blue_interface import BlueInterface
from yawning_titan.envs.generic.core.red_interface import RedInterface
from yawning_titan.envs.generic.generic_env import GenericNetworkEnv
from yawning_titan.envs.generic.core.network_interface import NetworkInterface
from yawning_titan.networks.network_db import default_18_node_network
# from yawning_titan.game_modes.game_mode_db import default_game_mode
from yawning_titan.game_modes.game_mode import GameMode
from yawning_titan.envs.generic.core.action_loops import ActionLoop

# game_mode = default_game_mode()
game_mode = GameMode.create_from_yaml(
    'C:/Work/yawning-titan/YAWNING-TITAN/tests/_package_data/legacy_default_game_mode.yaml')

network = default_18_node_network()
network_interface = NetworkInterface(game_mode=game_mode, network=network)

red = RedInterface(network_interface)
blue = BlueInterface(network_interface)

env = GenericNetworkEnv(red, blue, network_interface)

check_env(env, warn=True)

# reset anything changed during the check
_ = env.reset()

agent = PPO(PPOMlp, env, verbose=1)

agent.learn(total_timesteps=1000)

evaluate_policy(agent, env, n_eval_episodes=10)

loop = ActionLoop(env, agent, episode_count=1)
loop.gif_action_loop(save_gif=True, render_network=True)

Expected behaviour
I'd expect the saved GIF to look like Figure 2.

Screenshots/Outputs

Live animation:

live

Saved GIF:

saved

Environment (please complete the following information):

  • OS: Windows 10
  • Python: 3.10.9
  • YT Version: 1.1.1
  • Software: PyCharm

Additional context
FAO @ChrisMcCarthyDev.

Incorrect reward for blue agent reaching max_steps

if self.network_interface.reward_end_multiplier:

It should be the following.

            if self.network_interface.reward_end_multiplier:
                # FIXED
                reward = self.network_interface.reward_success * (
                    len(self.network_interface.get_nodes(filter_true_safe=True))
                    / self.network_interface.get_number_of_nodes()
                )
                # incorrect below
                # reward = self.network_interface.reward_end_multiplier * (
                #     len(self.network_interface.get_nodes(filter_true_safe=True))
                #     / self.network_interface.get_number_of_nodes()
                # )

since in the NetworkInterface class the variables are defined as following (although their names should likely be swapped).

    self.reward_success = self.reward_settings["rewards_for_reaching_max_steps"]
    self.reward_end_multiplier = self.reward_settings[
        "end_rewards_are_multiplied_by_end_state"
    ]

Add support for the new OpenAI Gym `step` API interface

The upstream team developing gym have implemented a new step API interface to support more granular termination criteria for environments. The details of the changes can be found here - openai/gym#2752.

This doesn't seem to be impacting the current build but as gym matures, it's likely that this interface will become the default.

Typo in the Citation section

In the Readme file in the front page there is a very small typo in the Andrew et al. paper citation: Conference is written Confernece
Below it is highlighted in the citation
@inproceedings{...
...
title = {Developing Optimal Causal Cyber-Defence Agents via Cyber Security Simulation},
maintitle = {International Confernece on Machine Learning (ICML)},
booktitle = {Workshop on Machine Learning for Cybersecurity (ML4Cyber)}
}

input never an integer in custom_network function - network_creator

Hi,

I think there is a piece missing in the function custom_network(), from network_creator code (helper functions).

The input number of nodes is checked if it is an integer, however every input from user is read as string (or at least in a Windows environment). So it is not possible to create a custom network.

An easy fix could be:
Actual code

def custom_network() -> Union[Tuple[np.array, dict], None]:
    size = input("How many nodes in the network? ")
    if type(size) != int:
        print("Error in input - NOT INT")
        return None
    else:
        #do something

FIX

def custom_network() -> Union[Tuple[np.array, dict], None]:
    size = input("How many nodes in the network? ")
    if type(int(size)) != int:
        print("Error in input - NOT INT")
        return None
    else:
        #do something

I think in this way if the input is a float or a text char it will not work, however it will go smoothly for integers.
I hope this helps,
Alberto

Scanning action not useful as blue agent sees the true compromised state

list(self.get_attributes_from_key("true_compromised_status").values())

The blue agent's observation includes the true compromised state instead of its observation of the compromised state.

    # Gets the current safe/compromised status of all of the nodes
    compromised_state = []
    if self.obs_compromised_status:
        # FIXED
        compromised_state = np.asarray(
            list(self.get_attributes_from_key("blue_view_compromised_status").values())
        )
        # previously was
        # compromised_state = np.asarray(
        #     list(self.get_attributes_from_key("true_compromised_status").values())
        # )

[BUG] internal reporting for node.isolated may be incorrect

Describe the bug
Calling len(list(networkx.isolates(G)) and sum(get_all_isolation()) return different values. This is because when a node is isolated by the blue agent, there is no check for previously connected nodes, and if any nodes that are not the target node have been made isolated.

An extreme example is that isolating the centre node in a star network of N nodes, on the one hand should report all nodes as isolated (as the len(list(networkx.isolates(G)) does), however only one node is reported as isolated internally (the sum of the return for get_all_isolation() method)

To Reproduce
Steps to reproduce the behaviour:
2. Instantiate env = GenericNetworkEnv
3. Print env.network_interface.get_all_isolation() and len(list(networkx.isolates(env.network_interface.current_graph)))
5. See error

Expected behaviour
We would expect that isolating a node, might have the effect of isolating other nodes that are not the target node. However, this is not recorded internally, which might effect proper rewards calculation (e.g. for rewards that are proportional to the number of isolated nodes, or the change in the number of isolated nodes).

Screenshots/Outputs
image
image

The below code should additionally check and set isolated nodes that are not the target node

image

Environment (please complete the following information):
Checked with:

  • [Python 3.9.13]
  • YT Version: [e.g. v1.0.1]
    It might also be a problem in the latest, after scanning the code.

[BUG] Rendering and GIF saving is broken

Describe the bug
When rendering, a small blank window is displayed and then later the final frame flashes up before the window closes.

When trying to save a GIF, the same happens, except there are two small blank windows, and th following error is produced after the final frame flashes up:

Traceback (most recent call last):
  File "C:\Work\YT\YAWNING-TITAN\main.py", line 36, in <module>
    loop.gif_action_loop(save_gif=True, render_network=True)
  File "C:\Work\YT\YAWNING-TITAN\src\yawning_titan\envs\generic\core\action_loops.py", line 117, in gif_action_loop
    webm_path = os.path.join(
  File "C:\Users\t_dudman\AppData\Local\Programs\Python\Python310\lib\ntpath.py", line 104, in join
    path = os.fspath(path)
TypeError: expected str, bytes or os.PathLike object, not NoneType

To Reproduce
Run the following script:

from stable_baselines3.common.env_checker import check_env
from stable_baselines3.common.evaluation import evaluate_policy
from stable_baselines3 import PPO
from stable_baselines3.ppo import MlpPolicy as PPOMlp

from yawning_titan.envs.generic.core.blue_interface import BlueInterface
from yawning_titan.envs.generic.core.red_interface import RedInterface
from yawning_titan.envs.generic.generic_env import GenericNetworkEnv
from yawning_titan.envs.generic.core.network_interface import NetworkInterface
from yawning_titan.networks.network_db import default_18_node_network
from yawning_titan.game_modes.game_mode_db import default_game_mode
from yawning_titan.envs.generic.core.action_loops import ActionLoop

game_mode = default_game_mode()

network = default_18_node_network()
network_interface = NetworkInterface(game_mode=game_mode, network=network)

red = RedInterface(network_interface)
blue = BlueInterface(network_interface)

env = GenericNetworkEnv(red, blue, network_interface)

check_env(env, warn=True)

# reset anything changed during the check
_ = env.reset()

agent = PPO(PPOMlp, env, verbose=1)

agent.learn(total_timesteps=1000)

evaluate_policy(agent, env, n_eval_episodes=10)

loop = ActionLoop(env, agent, episode_count=1)
loop.gif_action_loop(save_gif=True, render_network=True)

Change save_gif=True to save_gif=False to see the other problem.

Expected behaviour
Rendering and GIF saving should work.

Environment:

  • OS: Windoiws 10
  • Python: 3.10
  • YT Version: v2.0.0
  • Software: PyCharm

Additional context
As discussed with CM.

yawning_titan.agents.nsa_red doesnt seem to be working (TypeError: 'NSARed' object is not callable)

When I try to create a NSARed agent it goes without errors but when I try to use it in yawning_titan.yawning_titan_run.YawningTitanRun it returns this error : TypeError: 'NSARed' object is not callable

Is there any other way to use NSARed?

# Provides the red agent behaviour within the `18-node-def` environment.
from yawning_titan.agents.nsa_red import NSARed

from stable_baselines3.common.env_checker import check_env
from stable_baselines3.common.evaluation import evaluate_policy


from yawning_titan.envs.generic.core.blue_interface import BlueInterface
from yawning_titan.envs.generic.core.red_interface import RedInterface
from yawning_titan.envs.generic.generic_env import GenericNetworkEnv
from yawning_titan.envs.generic.core.action_loops import ActionLoop
from yawning_titan.envs.generic.core.network_interface import NetworkInterface
from yawning_titan.networks.network_db import default_18_node_network
from yawning_titan.game_modes.game_mode_db import default_game_mode


# Build the Network
network = default_18_node_network()
# Build the GameModeConfig
game_mode = default_game_mode()
# Build the NetworkInterface
network_interface = NetworkInterface(game_mode=game_mode, network=network)

# Create the red and blue agents
red = RedInterface(network_interface)
blue = BlueInterface(network_interface)

# Set the red agent to the NSARed premade
red=NSARed(skill=0.5,
       action_set=red.action_set,
       action_probabilities=red.action_probabilities,
       node_set=red.node_set,
       zd_start_amount=0,
       zd_gain=0,
       zd_required=10)

# Create the environment
env = GenericNetworkEnv(red, blue, network_interface)
# check it s gym compliant;its not 
check_env(env, warn=True)
# reset any change during the check 
# _ = env.reset()

from yawning_titan.yawning_titan_run import YawningTitanRun
YawningTitanRun(network=default_18_node_network(),
                game_mode=default_game_mode(),
                red_agent_class=red,
                blue_agent_class=blue,
                print_metrics=False,
                show_metrics_every=1,
                collect_additional_per_ts_data=False,
                eval_freq=10000,
                total_timesteps=200000,
                training_runs=1,
                n_eval_episodes=1,
                deterministic=False,
                warn=True,
                render=False,
                verbose=1,
                logger=None,
                output_dir=None,
                auto=True)

high_value_target is always "None" if "gr_loss_hvt" = False, network_interface

Hi,

I am working on some custom networks along with longer game scenarios (e.g., we don't care, at the moment, if the high_value_target is taken or not). I have a specific node which I identify as high_value_target and I feed it into the class network_interface.

However, it seems that if I set from the setup YAML file gr_loss_hvt = False, the class automatically forgets the input_value_target and sets it to 'None' (see line 408 in network_interface.py file).

So the getter function, get_high_value_target, return "None", which is set in the init function of the class (lines 403 to 408).

I fixed it by changing the output (from "None" to "high_value_target") in case I have "gr_loss_hvt = False" in the YAML file.

However, it seems that the function is missing a description for cases like "gr_loss_hvt = False".

Hope this helps,
Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.