Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brains as Scriptable Objects #1250

Merged
merged 52 commits into from
Oct 5, 2018
Merged

Conversation

vincentpierre
Copy link
Contributor

@vincentpierre vincentpierre commented Sep 21, 2018

Abstract

Make the Brain class inherit from ScriptableObject rather than MonoBehaviour. Make development of Brains easier for the developer.

Background

The current way to create, maintain and reuse Brains is laborious. A lot of this friction comes from the fact that they inherit from MonoBehaviour and must therefore be attached to a GameObject in the scene to be used. Scriptable objects are assets meaning that they exist outside of the scene. This means that they could be shared across scenes, be linked to Agent’s prefabs.

Goals

  • Remove the need to have a Brain GameObject in the Environment Scene
  • Maintain all current functionalities through simple UI
  • Design a clear API for Agents and Academy to interact with Brains

Non-Goals

  • Create new functionalities
  • Create complex UI

Plan

  • Modify the Brain classes so that each brain inherits from the base brain class
  • Create the Training Hub to allow the academy to know which brains to keep track of
  • Modify protobuf definitions and C# code to deleted BrainType refences (BrainType is replaced by the actual class of the brain)
  • Renamed Internal and External Brain Learning Brain
  • Create custom Editor for each brain class
  • Delete all CoreBrains
  • Documentation PR here
  • Modify all the scene to reflect this change Balance Ball
  • Fix UnityTests
  • Create UI to create Brains from the Editor
  • Fix the Pytests
  • Resolve Conflicts with develop

[CustomPropertyDrawer(typeof(BrainParameters))]
public class BrainParametersDrawer : PropertyDrawer
{
// private BrainParameters _bp;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove dead line

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{

// CheckInitialize(property, label);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these dead lines as well.


public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra spaces.

@awjuliani
Copy link
Contributor

Just finished a look through the code. Only suggestions are minor cosmetic. Also tested the functionality by creating two brains for 3DBall, and using one to train. Biggest feedback is around usability. As mentioned offline, having a way to distinguish the type of a brain from the editor would be nice. Perhaps we can even use custom icons for different brain types? The other usability issue is that we have to re-input the brain parameters for each brain we create for a given agent. I know we want to eventually do this automatically by creating the brain from the agent, but I wonder if there is some intermediate solution, such as creating a new brain based on an existing brain?

/// </summary>
/// <param name="source">The BrainParameters that will be copied</param>
/// <param name="target">The BrainParameters that will be overwritten</param>
private static void DeepCopyBrainParametersFrom(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove From

/// <param name="source">The BrainParameters that will be copied</param>
/// <param name="target">The BrainParameters that will be overwritten</param>
private static void DeepCopyBrainParametersFrom(
BrainParameters source, ref BrainParameters target)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

source and destination

}

public override void OnInspectorGUI()
{
var brain = (Brain) target;
CopyBrainParametersFrom(brain);
var brainToCopy = EditorGUILayout.ObjectField("Copy Brain Parameters from : ", null,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var brainToCopy = EditorGUILayout.ObjectField(
  "Copy Brain Parameters from : ", null, typeof(Brain), false) as Brain;

var serializedBrain = serializedObject;
serializedBrain.Update();
EditorGUILayout.PropertyField(serializedBrain.FindProperty("brainParameters"), true);
serializedBrain.ApplyModifiedProperties();

// Draws an horizontal thick line
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an --> a

{
return;
}
if (GUI.Button(removeRect, new GUIContent("Remove Last",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation

}

// This is the Remove button
if (_dict.Count == 0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment - if there are no parameter, hide the remove button

/// </summary>
/// <param name="property">The SerializedProperty of the ResetParameters
/// to make the custom GUI for.</param>
/// <param name="label">The label of this property.</param>
private void CheckInitialize(SerializedProperty property, GUIContent label)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitializeParameter


/// <summary>
/// Removes the last ResetParameter from the ResetParameters
/// </summary>
private void RemoveLastItem()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REmoveLastParameter

}
}

/// <summary>
/// Adds a new ResetParameter to the ResetParameters with a default name.
/// </summary>
private void AddNewItem()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddParameter

* Modified first docs

* modified the markdown, not the images

* Missing doc

* Replaced Internal with Learned Brain

* updated the images

* Addressed some comments

* Renamed Training Hub to Broadcast Hub

* Forgot one file

* Added new images

* addressing comment

* Fixed some typos
Copy link

@mmattar mmattar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I find the term Learning Brain odd for Inference mode. Are there another options?
  • Some comments from earlier review are still pending.

vectorObservationSize = src.vectorObservationSize,
numStackedVectorObservations = src.numStackedVectorObservations,
vectorActionSize = (int[]) src.vectorActionSize.Clone(),
cameraResolutions = (resolution[])src.cameraResolutions.Clone(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space before src.cameraResolutions.Clone(),

numStackedVectorObservations = src.numStackedVectorObservations,
vectorActionSize = (int[]) src.vectorActionSize.Clone(),
cameraResolutions = (resolution[])src.cameraResolutions.Clone(),
vectorActionDescriptions = (string[])src.vectorActionDescriptions.Clone(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space before src.vectorActionDescriptions.Clone(),

private BroadcastHub _hub;
// The height of a line in the Unity Inspectors
private const float LineHeight = 17f;
private const float ExtraSpaceBellow = 10f;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor due to typo: ExtraSpaceBellow --> ExtraSpaceBelow

private BroadcastHub _hub;
// The height of a line in the Unity Inspectors
private const float LineHeight = 17f;
private const float ExtraSpaceBellow = 10f;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this field?

must provide dictionaries from Brain names to arrays for `action`, `memory`
and `value`. For example: If you have two external Brains named `brain1` and
and `value`. For example: If you have two training Brains named `brain1` and
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

training Brain?

@@ -92,7 +109,7 @@ in order to ensure a smooth transition.
with ML-Agents. For more information on using `learn.py`, see
[here](Training-ML-Agents.md#training-with-mlagents-learn).
* Hyperparameters for training Brains are now stored in the
`trainer_config.yaml` file. For more information on using this file, see
`Controler_config.yaml` file. For more information on using this file, see
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: Controler_config

ML-Agents`
* Edit their `Brain Paramters` to be the same as the parameters used
in the `Brain` GameObjects
* Set the `Brain` property of the agents to the appropriate `Brain`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sentence somewhat confusing ...

[Brains](Learning-Environment-Design-Brains.md) for details on using the
different types of Brains. You can extend the CoreBrain class to create
different Brain types if the four built-in types don't do what you need.
different types of Brains. You can create new kinds of brains if the three
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other brains can we build?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know, you could imagine a brain that would record all the actions perform and store them to disk for example.

There are 3 kinds of brains you can use:

* [Learning](Learning-Environment-Learning-Brains.md) – Use a
**LearningBrain** to make use of a trained model or train a new model.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double-space after LearningBrain

Copy link

@mmattar mmattar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more things

public class PlayerBrainEditor : BrainEditor
{

public override void OnInspectorGUI()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vincentpierre - this method is still huge, please break-up.

brain.gameObject.name,
(CommunicatorObjects.BrainTypeProto)
brain.brainType));
bp.ToProto(brain.name, broadcastHub.IsControlled(brain))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is off on this line and next.


namespace MLAgents
{

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line

{

[System.Serializable]
public class BroadcastHub
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class comments

[SerializeField]
private List<Brain> _brainsToControl = new List<Brain>();

public int Count
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method comment

get { return broadcastingBrains.Count; }
}

public bool IsControlled(Brain b)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • method comment
  • change b to brain

return _brainsToControl.Contains(b);
}

public void SetTraining(Brain b, bool train)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • method comment
  • change b to brain

}
}

public void Clear()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method comment

decision.brainParameters = brainParameters;
}
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line

agentInfos[agent].reward,
agentInfos[agent].done,
agentInfos[agent].memories));

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line

@vincentpierre
Copy link
Contributor Author

@mmattar Comments addressed

Copy link

@mmattar mmattar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of minor comments, otherwise, 🚢

/// </summary>
/// <param name="serializedBrain"> The SerializedObject corresponding to the brain. </param>
/// <param name="brain"> The Brain of which properties are displayed. </param>
private static void DrawContinuousKeyMapping(SerializedObject serializedBrain,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either:

private static void DrawContinuousKeyMapping(SerializedObject serializedBrain, PlayerBrain brain)

OR

private static void DrawContinuousKeyMapping(
    SerializedObject serializedBrain, PlayerBrain brain)

/// If the input is [a, b, c], the result will be [0, a, a+b, a+b+c]
/// </summary>
/// <returns> The cumulative sum of the input array.</returns>
public static int[] CumSum(int [] array)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit test!

@vincentpierre vincentpierre merged commit 253b3bb into develop Oct 5, 2018
@vincentpierre vincentpierre deleted the develop-scriptable-brains branch October 5, 2018 21:40
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants