浏览代码

[MLA-1879] culture-invariant sorting for sensors and actuators (#5194)

/check-for-ModelOverriders
GitHub 4 年前
当前提交
5415b004
共有 8 个文件被更改,包括 113 次插入10 次删除
  1. 3
      com.unity.ml-agents/CHANGELOG.md
  2. 10
      com.unity.ml-agents/Runtime/Actuators/ActuatorManager.cs
  3. 2
      com.unity.ml-agents/Runtime/Agent.cs
  4. 7
      com.unity.ml-agents/Runtime/Inference/BarracudaModelExtensions.cs
  5. 13
      com.unity.ml-agents/Runtime/Sensors/ISensor.cs
  6. 28
      com.unity.ml-agents/Tests/Editor/Actuators/ActuatorManagerTests.cs
  7. 57
      com.unity.ml-agents/Tests/Runtime/Sensor/SensorUtilTests.cs
  8. 3
      com.unity.ml-agents/Tests/Runtime/Sensor/SensorUtilTests.cs.meta

3
com.unity.ml-agents/CHANGELOG.md


### Bug Fixes
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)
- Fixed a bug where sensors and actuators could get sorted inconsistently on different systems to different Culture
settings. Unfortunately, this may require retraining models if it changes the resulting order of the sensors
or actuators on your system. (#5194)
#### ml-agents / ml-agents-envs / gym-unity (Python)

10
com.unity.ml-agents/Runtime/Actuators/ActuatorManager.cs


internal class ActuatorManager : IList<IActuator>
{
// IActuators managed by this object.
IList<IActuator> m_Actuators;
List<IActuator> m_Actuators;
// An implementation of IDiscreteActionMask that allows for writing to it based on an offset.
ActuatorDiscreteActionMask m_DiscreteActionMask;

#endif
// Sort the Actuators by name to ensure determinism
SortActuators();
SortActuators(m_Actuators);
var continuousActions = numContinuousActions == 0 ? ActionSegment<float>.Empty :
new ActionSegment<float>(new float[numContinuousActions]);
var discreteActions = numDiscreteBranches == 0 ? ActionSegment<int>.Empty : new ActionSegment<int>(new int[numDiscreteBranches]);

/// <summary>
/// Sorts the <see cref="IActuator"/>s according to their <see cref="IActuator.Name"/> value.
/// </summary>
void SortActuators()
internal static void SortActuators(List<IActuator> actuators)
((List<IActuator>)m_Actuators).Sort((x,
y) => x.Name
.CompareTo(y.Name));
actuators.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.InvariantCulture));
}
/// <summary>

2
com.unity.ml-agents/Runtime/Agent.cs


}
// Sort the Sensors by name to ensure determinism
sensors.Sort((x, y) => x.GetName().CompareTo(y.GetName()));
SensorUtils.SortSensors(sensors);
#if DEBUG
// Make sure the names are actually unique

7
com.unity.ml-agents/Runtime/Inference/BarracudaModelExtensions.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.Barracuda;

names.Add(mem.input);
}
names.Sort();
names.Sort(StringComparer.InvariantCulture);
return names.ToArray();
}

});
}
tensors.Sort((el1, el2) => el1.name.CompareTo(el2.name));
tensors.Sort((el1, el2) => string.Compare(el1.name, el2.name, StringComparison.InvariantCulture));
return tensors;
}

}
}
names.Sort();
names.Sort(StringComparer.InvariantCulture);
return names.ToArray();
}

13
com.unity.ml-agents/Runtime/Sensors/ISensor.cs


using System;
using System.Collections.Generic;
using System.Linq;
namespace Unity.MLAgents.Sensors
{
/// <summary>

}
return count;
}
}
internal static class SensorUtils
{
internal static void SortSensors(List<ISensor> sensors)
{
// Use InvariantCulture to ensure consistent sorting between different culture settings.
sensors.Sort((x, y) => string.Compare(x.GetName(), y.GetName(), StringComparison.InvariantCulture));
}
}
}

28
com.unity.ml-agents/Tests/Editor/Actuators/ActuatorManagerTests.cs


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using NUnit.Framework;
using Unity.MLAgents.Actuators;

Assert.AreEqual(va1.m_DiscreteBufferSize, 3);
Assert.IsTrue(va2.m_HeuristicCalled);
Assert.AreEqual(va2.m_DiscreteBufferSize, 4);
}
/// <summary>
/// Test that sensors sort by name consistently across culture settings.
/// Example strings and cultures taken from
/// https://docs.microsoft.com/en-us/globalization/locale/sorting-and-string-comparison
/// </summary>
/// <param name="culture"></param>
[TestCase("da-DK")]
[TestCase("en-US")]
public void TestSortActuators(string culture)
{
List<IActuator> actuators = new List<IActuator>();
var actuator0 = new TestActuator(ActionSpec.MakeContinuous(2), "Apple");
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(2), "Æble");
actuators.Add(actuator0);
actuators.Add(actuator1);
var originalCulture = CultureInfo.CurrentCulture;
CultureInfo.CurrentCulture = new CultureInfo(culture);
ActuatorManager.SortActuators(actuators);
CultureInfo.CurrentCulture = originalCulture;
Assert.AreEqual(actuator1, actuators[0]);
Assert.AreEqual(actuator0, actuators[1]);
}
}
}

57
com.unity.ml-agents/Tests/Runtime/Sensor/SensorUtilTests.cs


using System;
using System.Collections.Generic;
using System.Globalization;
using NUnit.Framework;
using UnityEngine;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Utils.Tests;
namespace Unity.MLAgents.Tests
{
[TestFixture]
public class SensorUtilTests
{
internal class TempCulture : IDisposable
{
private CultureInfo m_OriginalCulture;
internal TempCulture(CultureInfo newCulture)
{
m_OriginalCulture = CultureInfo.CurrentCulture;
CultureInfo.CurrentCulture = newCulture;
}
public void Dispose()
{
CultureInfo.CurrentCulture = m_OriginalCulture;
}
}
/// <summary>
/// Test that sensors sort by name consistently across culture settings.
/// Example strings and cultures taken from
/// https://docs.microsoft.com/en-us/globalization/locale/sorting-and-string-comparison
/// </summary>
/// <param name="culture"></param>
[TestCase("da-DK")]
[TestCase("en-US")]
public void TestSortCulture(string culture)
{
List<ISensor> sensors = new List<ISensor>();
var sensor0 = new TestSensor("Apple");
var sensor1 = new TestSensor("Æble");
sensors.Add(sensor0);
sensors.Add(sensor1);
var originalCulture = CultureInfo.CurrentCulture;
CultureInfo.CurrentCulture = new CultureInfo(culture);
SensorUtils.SortSensors(sensors);
CultureInfo.CurrentCulture = originalCulture;
Assert.AreEqual(sensor1, sensors[0]);
Assert.AreEqual(sensor0, sensors[1]);
}
}
}

3
com.unity.ml-agents/Tests/Runtime/Sensor/SensorUtilTests.cs.meta


fileFormatVersion: 2
guid: 929b34a718bc42c8aa75a3e1c8c11103
timeCreated: 1617049947
正在加载...
取消
保存