-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Integrate BrainParameters with ActionSpec, update BrainParametersDrawer #4718
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
Conversation
This change can go into hybrid staging or directly into master if staging is too huge |
/// The size of the action space. | ||
/// The specification of the Action space for the BrainParameters. | ||
/// </summary> | ||
public ActionSpec VectorActionSpec = new ActionSpec(0, 0, new int[] { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just call this "ActionSpec"? https://unity.slack.com/archives/C01G1362C23/p1607471246002900
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept this simply because public ActionSpec ActionSpec = new ActionSpec();
looks a bit confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it okay to add new public fields to BrainParameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you can always add new public fields and methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do it in a few other places like this:
public abstract ActionSpec ActionSpec { get; } |
and
public ActionSpec ActionSpec { get; } |
I think it's better to have a slightly confusing declaration and simplify how people use it.
|
||
/// <summary> | ||
/// Get the total number of Discrete Actions that can be taken by calculating the Sum | ||
/// of all of the Discrete Action branch sizes. | ||
/// </summary> | ||
public int SumOfDiscreteBranchSizes { get; } | ||
public int SumOfDiscreteBranchSizes { get { return m_SumOfDiscreteBranchSizes; } set { m_SumOfDiscreteBranchSizes = value; } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably out of scope, but why is this public and not internal? I feel like ActionSpec should be only nContinuous and DiscreteBranchSizes...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed m_SumOfDiscreteBranchSizes and m_NumDiscreteActions, and derive them from branch sizes.
/// <param name="numDiscreteActions">Number of Discrete Actions</param> | ||
/// <param name="branchSizes">The array of branch sizes for the discrete action space. Each index | ||
/// contains the number of actions available for that branch.</param> | ||
public void SetDiscrete(int numDiscreteActions, int[] branchSizes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can SetDiscrete only take a single branchSizes argument ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure I understand this question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think he means public void SetDiscrete(int[] branchSizes)
.
This makes sense to me; only m_NumContinuousActions
and m_DiscreteBranchSizes
is necessary in ActionSpec for all information.
/// The size of the action space. | ||
/// The specification of the Action space for the BrainParameters. | ||
/// </summary> | ||
public ActionSpec VectorActionSpec = new ActionSpec(0, 0, new int[] { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it okay to add new public fields to BrainParameters?
@@ -72,16 +72,17 @@ static string BuildIntArrayLabel(SerializedProperty actionSizeProperty) | |||
/// </summary> | |||
void MakeActionsProperty(SerializedProperty property) | |||
{ | |||
var actSizeProperty = property.FindPropertyRelative("VectorActionSize"); | |||
var actSpaceTypeProp = property.FindPropertyRelative("VectorActionSpaceType"); | |||
var actSpecProperty = property.FindPropertyRelative("VectorActionSpec"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we move all of our strings to constants? Feels ripe for typo bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved them all to const strings
please run some yamato tests on this branch before merging. |
/// Set action size fields related to continuous actions. | ||
/// </summary> | ||
/// <param name="numContinuousActions">Number of Continuous Actions</param> | ||
public void SetContinuous(int numContinuousActions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal?
If you keep this public, I think it should m_BranchSizes to null. As long it's only used in the one or two places that it currently is, it's probably OK as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it internal.
Add: Originally this is for safely setting discrete fields since there're multiple fields related to discrete spec. Now that there's only one (branch sizes) it's not necessary anymore. I might just remove it.
/// <param name="numDiscreteActions">Number of Discrete Actions</param> | ||
/// <param name="branchSizes">The array of branch sizes for the discrete action space. Each index | ||
/// contains the number of actions available for that branch.</param> | ||
public void SetDiscrete(int[] branchSizes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comments as SetContinuous
@@ -61,7 +68,8 @@ public class BrainParameters | |||
/// For the discrete action space: the number of branches in the action space. | |||
/// </value> | |||
[FormerlySerializedAs("vectorActionSize")] | |||
public int[] VectorActionSize = new[] { 1 }; | |||
[FormerlySerializedAs("VectorActionSize")] | |||
public int[] VectorActionSizeDeprecated = new[] { 1 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are public fields on a public class, so we can't rename them.
I think (@surfnerd correct me if I'm wrong) we can do something like
[FormerlySerializedAs("vectorActionSize")]
[FormerlySerializedAs("VectorActionSize")]
private int[] m_VectorActionSizeDeprecated; // or maybe internal
int[] VectorActionSize {
get { /* do something with ActionSpec */ }
set { /* do something with ActionSpec */ }
}
(and similar for VectorActionSpaceType
). The make sure to use the m_* fields (not the properties) in the OnBeforeSerialize methods.
/// </summary> | ||
public int NumActions | ||
public int NumActionsDeprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't rename. We can mark as [Obsolete]
to discourage access though.
/// <summary> | ||
/// Called by Unity immediately before serializing this object. | ||
/// </summary> | ||
/// <remarks> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agent has a lot of boilerplate here since it's the main class and users will inherit from it. That shouldn't be the case for BrainParameters, so I think we can trim this down here.
/// </example> | ||
public void OnAfterDeserialize() | ||
{ | ||
if (!hasUpgradedBrainParametersWithActionSpec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment on the docstring.
Can we move the logic here and in OnBeforeSerialize to a private UpdateToActionSpec()
method?
@@ -32,24 +32,24 @@ public void WriteDiscreteActionMask(IDiscreteActionMask actionMask) | |||
public void TestConstruct() | |||
{ | |||
var ar = new TestActionReceiver(); | |||
var va = new VectorActuator(ar, new[] { 1, 2, 3 }, SpaceType.Discrete, "name"); | |||
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(new int[] { 1, 2, 3 }), "name"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(new int[] { 1, 2, 3 }), "name"); | |
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name"); |
MakeDiscrete uses [params](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params)
so you can skip the new int[]
and just pass them like multiple args. Not a requirement, just some syntactic sugar.
@@ -423,7 +426,7 @@ def sac_entropy_loss( | |||
) | |||
# We update all the _cont_ent_coef as one block | |||
entropy_loss += -1 * ModelUtils.masked_mean( | |||
_cont_ent_coef * target_current_diff, loss_masks | |||
torch.mean(_cont_ent_coef) * target_current_diff, loss_masks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad merge? Looks like this is undoing #4725
"Unknown enum value."); | ||
} | ||
ActionSpec = actionSpec; | ||
string suffix = $"-Continuous-{actionSpec.NumContinuousActions}-Discrete-{actionSpec.NumDiscreteActions}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically a behavior change. Not sure if there's any observable difference, though - maybe in how the actuators are sorted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed it back and only use that with hybrid action
/// </summary> | ||
public ActionSpec ActionSpec | ||
{ | ||
get { return new ActionSpec(m_NumContinuousActions, m_DiscreteBranchSizes); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this means that someone could do something like
myBrainParams.ActionSpec.NumContinuousActions = 4;
which would compile are run, but it would set NumContinuousActions on the new ActionSpec that gets returned here, but it wouldn't propagate to m_NumContinuousActions.
@surfnerd is there a better pattern for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActionSpec is a value type, so 'new' is redundant here I believe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without 'new' there will be compile error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the deprecated fields can be synced with corresponding new field, it's actually easier to just bring back ActionSpec and sync with ActionSpec fields to solve this problem.
{ | ||
m_ActionSpec.NumContinuousActions = value.NumContinuousActions; | ||
m_ActionSpec.BranchSizes = value.BranchSizes; | ||
if (m_ActionSpec.NumContinuousActions == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can this block be replaced with SyncDeprecatedActionFields()
?
com.unity.ml-agents/CHANGELOG.md
Outdated
@@ -10,11 +10,10 @@ and this project adheres to | |||
## [Unreleased] | |||
### Major Changes | |||
#### com.unity.ml-agents (C#) | |||
- Agent with both continuous and discrete actions is now supported. You can specify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is still a minor change from semantic versioning point of view. We'll list it as "major" for the release notes though.
Also, please keep the old PR# (#4702) and add this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was following the python changelog. Is the python changes also minor?
Proposed change(s)
Useful links (Github issues, JIRA tickets, ML-Agents forum threads etc.)
JIRA: MLA-1320
Types of change(s)
Checklist
Other comments