Skip to content

Commit ce3a48c

Browse files
committed
Decrease number of training steps when testing
1 parent 1fc6673 commit ce3a48c

7 files changed

Lines changed: 182 additions & 90 deletions

File tree

docs/contributing.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ pytest --disable-pytest-warnings -k your_test_name_here
9797
# ignore specific test files and directories:
9898
pytest --ignore=path/to/your/test.py --ignore=path/to/other/
9999

100+
# display more logs:
101+
pytest --disable-pytest-warnings -s --log-cli-level=INFO path/to/your/test.py
102+
# display all logs:
103+
pytest --disable-pytest-warnings -s --log-cli-level=DEBUG path/to/your/test.py
100104
```
101105

102106
## Linting

docs/guides/reinforcement_learning/scripts.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,29 @@ Train a reinforcement learning agent.
8383

8484
```sh
8585
python -m smart_control.reinforcement_learning.scripts.train \
86-
--experiment_name my-experiment-1
86+
--experiment_name="my-experiment-1"
8787
```
8888

8989
```sh
9090
python -m smart_control.reinforcement_learning.scripts.train \
91-
--experiment_name my-experiment-1 \
92-
--agent_type="sac"
91+
--experiment_name=my-experiment-1 \
92+
--starter_buffer_name="default" \
93+
--agent_type="sac" \
9394
--learner_iterations=3 \
9495
--train_iterations=10 \
9596
--collect_steps_per_training_iteration=5
9697
```
9798

99+
```sh
100+
python -m smart_control.reinforcement_learning.scripts.train \
101+
--experiment_name="experiment-test-2" \
102+
--starter_buffer_name="test" \
103+
--agent_type="sac" \
104+
--learner_iterations=1 \
105+
--train_iterations=1 \
106+
--collect_steps_per_training_iteration=1
107+
```
108+
98109
This will generate a new experiment results directory under
99110
"smart_control/reinforcement_learning/data/experiment_results/`experiment_name`".
100111
In the experiment results directory will be the following files and directories:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Setup environment for fast testing."""
2+
3+
import gin
4+
5+
from smart_control.environment.environment import Environment
6+
from smart_control.reinforcement_learning.utils.constants import DEFAULT_OCCUPANCY_NORMALIZATION_CONSTANT
7+
8+
9+
def create_and_setup_test_environment(
10+
gin_config_file: str,
11+
metrics_path: str = None,
12+
occupancy_normalization_constant: float = DEFAULT_OCCUPANCY_NORMALIZATION_CONSTANT, # pylint: disable=line-too-long
13+
):
14+
"""Creates and sets up the environment."""
15+
with gin.unlock_config():
16+
gin.clear_config()
17+
gin.parse_config_file(gin_config_file)
18+
19+
# start to end is one day long ?
20+
# update time step interval to be longer, to decrease number of steps
21+
seconds_in_a_day = 60 * 60 * 24
22+
time_step_sec = seconds_in_a_day / 2 # produces 28 steps?
23+
time_step_sec = time_step_sec * 10 # produces 2 steps?
24+
time_step_sec = time_step_sec * 2 # produces 1 step
25+
gin.bind_parameter("sim_building/TFSimulator.time_step_sec", time_step_sec)
26+
27+
env = Environment() # pylint: disable=no-value-for-parameter
28+
29+
# print(env._num_timesteps_in_episode) # updated from 4032 to 1
30+
# breakpoint()
31+
env.metrics_path = metrics_path
32+
env.occupancy_normalization_constant = occupancy_normalization_constant
33+
34+
return env

smart_control/reinforcement_learning/scripts/train.py

Lines changed: 75 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,12 @@
66
components.
77
"""
88

9-
# OK so we are running into an error
10-
# TypeError: this __dict__ descriptor does not support '_DictWrapper' objects
11-
# https://github.com/tensorflow/tensorflow/issues/59869
12-
# As a workaround, we need to set this env var before loading tensorflow
13-
# https://github.com/GrahamDumpleton/wrapt/issues/231#issuecomment-1455800902
14-
# fmt: off
15-
import os # isort:skip
16-
os.environ['WRAPT_DISABLE_EXTENSIONS'] = 'true'
17-
# fmt: on
18-
19-
# pylint:disable=wrong-import-position
9+
import smart_control.reinforcement_learning.tf_import_fix # isort:skip # pylint:disable=bad-import-order,unused-import
10+
2011
from datetime import datetime
2112
import json
2213
import logging
14+
import os
2315
import shutil
2416
from typing import Sequence
2517

@@ -47,16 +39,9 @@
4739
from smart_control.reinforcement_learning.utils.constants import RL_STARTER_BUFFERS_DIR
4840
from smart_control.reinforcement_learning.utils.environment import create_and_setup_environment
4941

50-
# from smart_control.utils.constants import ROOT_DIR
51-
# from smart_control.utils.constants import DEFAULT_CONFIG_FILEPATH
52-
53-
# this is used by the gin config (see "sim_config_day1.gin")
54-
# pylint:disable-next=unused-import
55-
from smart_control.reinforcement_learning.utils.config import get_histogram_path # isort:skip
56-
57-
# pylint:enable=wrong-import-position
42+
# this is used by the gin config (see "sim_config_day1.gin"):
43+
from smart_control.reinforcement_learning.utils.config import get_histogram_path # isort:skip # pylint:disable=unused-import
5844

59-
DEFAULT_STARTER_BUFFER_DIRPATH = os.path.join(RL_STARTER_BUFFERS_DIR, 'default')
6045

6146
# LOGGING
6247

@@ -75,16 +60,18 @@
7560
name='experiment_name',
7661
default=None,
7762
help='Name of the experiment. This is used to save TensorBoard summaries',
78-
required=True,
63+
# required=True,
7964
)
8065
flags.DEFINE_string(
81-
name='starter_buffer_path',
82-
default=DEFAULT_STARTER_BUFFER_DIRPATH,
83-
help='Path to the starter replay buffer (e.g. "/path/to/my_buffer").',
84-
# required=True,
66+
name='starter_buffer_name',
67+
default='default',
68+
help=(
69+
'Name used to identify the replay buffer. Corresponds with directory'
70+
' name where the files have been saved.'
71+
),
8572
)
8673
flags.DEFINE_string(
87-
name='config_filepath',
74+
name='train_config_filepath',
8875
default=ONE_DAY_CONFIG_FILEPATH, # DEFAULT_CONFIG_FILEPATH,
8976
help='Path to the scenario config file (e.g. "/path/to/sim_config.gin")',
9077
)
@@ -166,7 +153,7 @@ class RLAgentTrainer:
166153
def __init__(
167154
self,
168155
experiment_name: str,
169-
starter_buffer_path: str = DEFAULT_STARTER_BUFFER_DIRPATH,
156+
starter_buffer_name: str = 'default', # DEFAULT_STARTER_BUFFER_DIRPATH,
170157
config_filepath: str = ONE_DAY_CONFIG_FILEPATH,
171158
agent_type: str = 'sac',
172159
train_iterations: int = 100000,
@@ -179,7 +166,8 @@ def __init__(
179166
learner_iterations: int = 200,
180167
):
181168
self.experiment_name = experiment_name
182-
self.starter_buffer_dirpath = starter_buffer_path
169+
self.starter_buffer_name = starter_buffer_name
170+
# self.starter_buffer_dirpath = starter_buffer_path
183171
self.config_filepath = config_filepath
184172
self.agent_type = agent_type
185173
self.train_iterations = int(train_iterations)
@@ -191,6 +179,10 @@ def __init__(
191179
self.checkpoint_interval = int(checkpoint_interval)
192180
self.learner_iterations = int(learner_iterations)
193181

182+
self.starter_buffer_dirpath = os.path.join(
183+
RL_STARTER_BUFFERS_DIR, self.starter_buffer_name
184+
)
185+
194186
if self.agent_type not in ['sac', 'ddpg']:
195187
raise ValueError(
196188
'Agent {self.agent_type} has not (yet) been implemented. Please'
@@ -199,34 +191,42 @@ def __init__(
199191

200192
# todo: validate all integers are greater than zero
201193

202-
self.experiment_dirname = self.experiment_name.replace(' ', '')
194+
experiment_dirname = self.experiment_name.replace(' ', '')
203195
self.results_dirpath = os.path.join(
204-
RL_EXPERIMENT_RESULTS_DIR, self.experiment_dirname
196+
RL_EXPERIMENT_RESULTS_DIR, experiment_dirname
205197
)
206198

199+
# allow customization of this env setup during testing:
200+
self.create_and_setup_environment = create_and_setup_environment
201+
207202
# these will be set later during training:
208-
self.train_env = None
209-
self.eval_env = None
203+
# self.train_env = None
204+
# self.eval_env = None
210205
self.agent = None
211206

212-
@property
213-
def done_filepath(self):
214-
"""The DONE file is a convention for replay buffers. We are borrowing it.
215-
After the agent is trained we will create this file.
216-
"""
217-
return os.path.join(self.results_dirpath, 'DONE')
207+
# @property
208+
# def done_filepath(self):
209+
# """The DONE file is a convention for replay buffers. We are borrowing it.
210+
# After the agent is trained we will create this file.
211+
# """
212+
# return os.path.join(self.results_dirpath, 'DONE')
218213

219-
def mark_as_complete(self):
220-
"""Create the DONE file to indicate the agent has completed its training."""
221-
with open(self.done_filepath, 'w', encoding='utf-8') as f:
222-
f.write('Training Complete!')
214+
# def mark_as_complete(self):
215+
# """Create the DONE file to indicate the agent has completed its training.
216+
# """
217+
# with open(self.done_filepath, 'w', encoding='utf-8') as f:
218+
# f.write('Training Complete!')
223219

224220
def setup_results_dir(self):
225221
logger.info(
226222
'Experiment results will be saved to %s',
227223
os.path.abspath(self.results_dirpath),
228224
)
229225

226+
## clear previous results if they exist
227+
# if os.path.isdir(self.saved_model_dirpath):
228+
# shutil.rmtree(self.saved_model_dirpath)
229+
230230
# try:
231231
# os.makedirs(self.results_dirpath, exist_ok=False)
232232
# except FileExistsError as exc:
@@ -238,7 +238,9 @@ def setup_results_dir(self):
238238
# ) from exc
239239
os.makedirs(self.results_dirpath, exist_ok=True)
240240
# when testing we are creating the dir beforehand, check for results instead
241-
if os.path.isfile(self.done_filepath):
241+
# if os.path.isfile(self.done_filepath):
242+
243+
if os.path.isdir(self.saved_model_dirpath):
242244
raise FileExistsError('Results directory already exists')
243245

244246
@property
@@ -275,7 +277,7 @@ def save_experiment_params(self, params: dict = None, save_path: str = None):
275277
save_path: Path to save the parameters file.
276278
"""
277279
params = params or self.experiment_params
278-
params['timestamp'] = datetime.now().strftime('%Y_%m_%d-%H:%M:%S')
280+
params['timestamp'] = datetime.now().strftime('%Y%m%d_%H%M%S')
279281

280282
save_path = save_path or self.results_dirpath
281283

@@ -296,7 +298,7 @@ def save_experiment_params(self, params: dict = None, save_path: str = None):
296298
for key, value in params.items():
297299
f.write(f'{key}: {value}\n')
298300

299-
def copy_replay_buffer(self):
301+
def copy_starter_buffer(self):
300302
# Create a new buffer path in the experiment directory
301303
new_buffer_path = os.path.join(self.results_dirpath, 'replay_buffer')
302304
os.makedirs(new_buffer_path, exist_ok=True)
@@ -314,8 +316,8 @@ def copy_replay_buffer(self):
314316
shutil.copy2(self.starter_buffer_dirpath, new_buffer_path)
315317
else:
316318
# If it's a directory, copy all contents
317-
for item in os.listdir(self.starter_buffer_path):
318-
source_item = os.path.join(self.starter_buffer_path, item)
319+
for item in os.listdir(self.starter_buffer_dirpath):
320+
source_item = os.path.join(self.starter_buffer_dirpath, item)
319321
dest_item = os.path.join(new_buffer_path, item)
320322
if os.path.isfile(source_item):
321323
shutil.copy2(source_item, dest_item)
@@ -361,19 +363,18 @@ def saved_model_dirpath(self):
361363

362364
def train_agent(self) -> tf_agent.TFAgent:
363365
self.setup_results_dir()
364-
self.save_experiment_parameters()
366+
self.save_experiment_params()
365367

366368
# ENVIRONMENTS
367369

368370
logger.info(
369371
'Creating train and eval environments with scenario config path: %s',
370372
self.config_filepath,
371373
)
372-
# metrics_dirpath = os.path.join(self.results_dirpath, 'metrics')
373-
train_env = create_and_setup_environment(
374+
train_env = self.create_and_setup_environment(
374375
self.config_filepath, metrics_path=self.metrics_dirpath
375376
)
376-
eval_env = create_and_setup_environment(
377+
eval_env = self.create_and_setup_environment(
377378
self.config_filepath, metrics_path=None
378379
)
379380

@@ -466,11 +467,10 @@ def train_agent(self) -> tf_agent.TFAgent:
466467

467468
# Create collect actor
468469
logger.info('Creating collect actor...')
469-
# collect_dirpath = os.path.join(self.results_dirpath, 'collect')
470470
collect_actor = actor.Actor(
471-
train_env,
472-
py_tf_eager_policy.PyTFEagerPolicy(collect_policy),
473-
train_step,
471+
env=train_env,
472+
policy=py_tf_eager_policy.PyTFEagerPolicy(collect_policy),
473+
train_step=train_step,
474474
steps_per_run=self.collect_steps_per_iteration,
475475
metrics=actor.collect_metrics(1),
476476
observers=[collect_observers],
@@ -480,7 +480,6 @@ def train_agent(self) -> tf_agent.TFAgent:
480480

481481
# Create eval actor
482482
logger.info('Creating eval actor...')
483-
# eval_dirpath = os.path.join(self.results_dirpath, 'eval')
484483
eval_actor = actor.Actor(
485484
env=eval_env,
486485
policy=py_tf_eager_policy.PyTFEagerPolicy(eval_policy),
@@ -581,7 +580,7 @@ def train_agent(self) -> tf_agent.TFAgent:
581580
logger.info('Final Eval %s: %s', m.name, m.result())
582581
eval_actor.summary_writer.flush()
583582

584-
self.mark_as_complete()
583+
# self.mark_as_complete()
585584
logger.info(
586585
'Agent training completed. Saved models in %s',
587586
os.path.abspath(self.results_dirpath),
@@ -593,29 +592,29 @@ def main(argv: Sequence[str]):
593592
if len(argv) > 1:
594593
raise app.UsageError('Too many command-line arguments.')
595594

596-
experiment_name = FLAGS.experiment_name
597-
experiment_name = experiment_name.replace(' ', '_')
595+
# experiment_name = FLAGS.experiment_name
596+
# experiment_name = experiment_name.replace(' ', '_')
598597

599598
# STARTER BUFFER DIRPATH:
600-
buffer_dirpath = FLAGS.starter_buffer_path
601-
if not buffer_dirpath:
602-
buffer_names = [d for d in os.listdir(RL_STARTER_BUFFERS_DIR) if 'buffer' in d] # pylint:disable=line-too-long
603-
if any(buffer_names):
604-
buffer_name = buffer_names[-1]
605-
print('USING MOST RECENTLY GENERATED STARTER BUFFER:', buffer_name)
606-
buffer_dirpath = os.path.join(RL_STARTER_BUFFERS_DIR, buffer_name)
607-
else:
608-
raise ValueError(
609-
'There are no starter buffer files available. Please generate one'
610-
' using the starter buffer generation script.'
611-
)
612-
if not os.path.isabs(buffer_dirpath):
613-
buffer_dirpath = os.path.join(RL_STARTER_BUFFERS_DIR, buffer_dirpath)
599+
# buffer_dirpath = FLAGS.starter_buffer_path
600+
# if not buffer_dirpath:
601+
# buffer_names = os.listdir(RL_STARTER_BUFFERS_DIR)
602+
# if any(buffer_names):
603+
# buffer_name = buffer_names[-1]
604+
# print('USING MOST RECENTLY GENERATED STARTER BUFFER:', buffer_name)
605+
# buffer_dirpath = os.path.join(RL_STARTER_BUFFERS_DIR, buffer_name)
606+
# else:
607+
# raise ValueError(
608+
# 'There are no starter buffer files available. Please generate one'
609+
# ' using the starter buffer generation script.'
610+
# )
611+
# if not os.path.isabs(buffer_dirpath):
612+
# buffer_dirpath = os.path.join(RL_STARTER_BUFFERS_DIR, buffer_dirpath)
614613

615614
trainer = RLAgentTrainer(
616-
starter_buffer_path=buffer_dirpath,
617-
config_filepath=FLAGS.config_filepath,
618-
experiment_name=experiment_name,
615+
starter_buffer_name=FLAGS.starter_buffer_name,
616+
config_filepath=FLAGS.train_config_filepath,
617+
experiment_name=FLAGS.experiment_name,
619618
agent_type=FLAGS.agent_type,
620619
train_iterations=FLAGS.train_iterations,
621620
collect_steps_per_iteration=FLAGS.collect_steps_per_training_iteration,

0 commit comments

Comments
 (0)