浏览代码

Refactoring Curriculum tests and code.

- Curriculum tests are now separate from other trainers.
- Property setter is now used in Curriculum.
/develop-generalizationTraining-TrainerController
Deric Pang 7 年前
当前提交
de128fa1
共有 6 个文件被更改,包括 113 次插入60 次删除
  1. 53
      python/tests/test_unitytrainers.py
  2. 13
      python/unitytrainers/curriculum.py
  3. 2
      python/unitytrainers/trainer_controller.py
  4. 11
      unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs
  5. 11
      python/curricula/push_curriculum.json
  6. 83
      python/tests/test_curriculum.py

53
python/tests/test_unitytrainers.py


memory_size: 8
''')
dummy_curriculum = json.loads('''{
"measure" : "reward",
"thresholds" : [10, 20, 50],
"min_lesson_length" : 3,
"signal_smoothing" : true,
"parameters" :
{
"param1" : [0.7, 0.5, 0.3, 0.1],
"param2" : [100, 50, 20, 15],
"param3" : [0.2, 0.3, 0.7, 0.9]
}
}''')
bad_curriculum = json.loads('''{
"measure" : "reward",
"thresholds" : [10, 20, 50],
"min_lesson_length" : 3,
"signal_smoothing" : false,
"parameters" :
{
"param1" : [0.7, 0.5, 0.3, 0.1],
"param2" : [100, 50, 20],
"param3" : [0.2, 0.3, 0.7, 0.9]
}
}''')
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')

batch_size=None, training_length=2)
assert len(b.update_buffer['action']) == 10
assert np.array(b.update_buffer['action']).shape == (10, 2, 2)
def test_curriculum():
open_name = '%s.open' % __name__
with mock.patch('json.load') as mock_load:
with mock.patch(open_name, create=True) as mock_open:
mock_open.return_value = 0
mock_load.return_value = bad_curriculum
with pytest.raises(CurriculumError):
Curriculum('tests/test_unityagents.py', {"param1": 1, "param2": 1, "param3": 1})
mock_load.return_value = dummy_curriculum
with pytest.raises(CurriculumError):
Curriculum('tests/test_unityagents.py', {"param1": 1, "param2": 1})
curriculum = Curriculum('tests/test_unityagents.py', {"param1": 1, "param2": 1, "param3": 1})
assert curriculum.get_lesson_number == 0
curriculum.set_lesson_number(1)
assert curriculum.get_lesson_number == 1
curriculum.increment_lesson(10)
assert curriculum.get_lesson_number == 1
curriculum.increment_lesson(30)
curriculum.increment_lesson(30)
assert curriculum.get_lesson_number == 1
assert curriculum.lesson_length == 3
curriculum.increment_lesson(30)
assert curriculum.get_config() == {'param1': 0.3, 'param2': 20, 'param3': 0.7}
assert curriculum.get_config(0) == {"param1": 0.7, "param2": 100, "param3": 0.2}
assert curriculum.lesson_length == 0
assert curriculum.get_lesson_number == 2
if __name__ == '__main__':

13
python/unitytrainers/curriculum.py


"""
self.lesson_length = 0
self.max_lesson_number = 0
self.measure_type = None
self._measure_type = None
self._lesson_number = 0
if location is None:
self.data = None
else:

"The parameter {0} in Curriculum {1} must have {2} values "
"but {3} were found".format(key, location,
self.max_lesson_number + 1, len(parameters[key])))
self.set_lesson_number(0)
@property
def measure(self):

def get_lesson_number(self):
return self.lesson_number
def lesson_number(self):
return self._lesson_number
def set_lesson_number(self, value):
@lesson_number.setter
def lesson_number(self, lesson_number):
self.lesson_number = max(0, min(value, self.max_lesson_number))
self._lesson_number = max(0, min(lesson_number, self.max_lesson_number))
def increment_lesson(self, progress):
"""

2
python/unitytrainers/trainer_controller.py


self.env_name = 'editor_'+self.env.academy_name
else:
self.env_name = os.path.basename(os.path.normpath(env_path)) # Extract out name of environment
self.curriculum = Curriculum(curriculum_file, self.env._resetParameters)
self.curriculum = Curriculum(self.curriculum_file, self.env._resetParameters)
def _get_progress(self):
if self.curriculum_file is not None:

11
unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs


agentRB.velocity = Vector3.zero;
agentRB.angularVelocity = Vector3.zero;
}
private void FixedUpdate()
{
// Set the size of the goal according to the current lesson in the
// curriculum.
goal.transform.localScale = new Vector3(
academy.resetParameters["goal_width"],
goal.transform.localScale.y,
academy.resetParameters["goal_length"]);
}
}

11
python/curricula/push_curriculum.json


{
"measure" : "progress",
"thresholds" : [0.1],
"min_lesson_length" : 2,
"signal_smoothing" : true,
"parameters" :
{
"goal_width" : [25.0, 5.0],
"goal_length" : [5.0, 1.0]
}
}

83
python/tests/test_curriculum.py


import pytest
import json
from unittest.mock import patch, mock_open
from unityagents import UnityEnvironmentException
from unitytrainers import Curriculum
dummy_curriculum_json_str = '''
{
"measure" : "reward",
"thresholds" : [10, 20, 50],
"min_lesson_length" : 3,
"signal_smoothing" : true,
"parameters" :
{
"param1" : [0.7, 0.5, 0.3, 0.1],
"param2" : [100, 50, 20, 15],
"param3" : [0.2, 0.3, 0.7, 0.9]
}
}
'''
bad_curriculum_json_str = '''
{
"measure" : "reward",
"thresholds" : [10, 20, 50],
"min_lesson_length" : 3,
"signal_smoothing" : false,
"parameters" :
{
"param1" : [0.7, 0.5, 0.3, 0.1],
"param2" : [100, 50, 20],
"param3" : [0.2, 0.3, 0.7, 0.9]
}
}
'''
@patch('builtins.open', new_callable=mock_open, read_data=dummy_curriculum_json_str)
def test_init_curriculum_happy_path(mock_file):
curriculum = Curriculum('TestBrain.json', {"param1": 1, "param2": 1, "param3": 1})
assert curriculum.lesson_number == 0
assert curriculum.measure == 'reward'
@patch('builtins.open', new_callable=mock_open, read_data=bad_curriculum_json_str)
def test_init_curriculum_bad_curriculum_raises_error(mock_file):
with pytest.raises(UnityEnvironmentException):
Curriculum('TestBrainCurriculum.json', {"param1": 1, "param2": 1, "param3": 1})
@patch('builtins.open', new_callable=mock_open, read_data=dummy_curriculum_json_str)
def test_increment_lesson(mock_file):
curriculum = Curriculum('TestBrain.json', {"param1": 1, "param2": 1, "param3": 1})
assert curriculum.lesson_number == 0
curriculum.lesson_number = 1
assert curriculum.lesson_number == 1
curriculum.increment_lesson(10)
assert curriculum.lesson_number == 1
curriculum.increment_lesson(30)
curriculum.increment_lesson(30)
assert curriculum.lesson_number == 1
assert curriculum.lesson_length == 3
curriculum.increment_lesson(30)
assert curriculum.lesson_length == 0
assert curriculum.lesson_number == 2
@patch('builtins.open', new_callable=mock_open, read_data=dummy_curriculum_json_str)
def test_get_config(mock_file):
curriculum = Curriculum('TestBrain.json', {"param1": 1, "param2": 1, "param3": 1})
assert curriculum.get_config() == {"param1": 0.7, "param2": 100, "param3": 0.2}
curriculum.lesson_number = 2
assert curriculum.get_config() == {'param1': 0.3, 'param2': 20, 'param3': 0.7}
assert curriculum.get_config(0) == {"param1": 0.7, "param2": 100, "param3": 0.2}
正在加载...
取消
保存