From a9f7e300eac7696e57abafb516e08b462380dcc4 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Thu, 11 Apr 2019 21:12:36 +0200 Subject: [PATCH 01/34] mode pretrain in base_calse --- stable_baselines/common/base_class.py | 45 +++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/stable_baselines/common/base_class.py b/stable_baselines/common/base_class.py index b2ae6952a9..9f31d48787 100644 --- a/stable_baselines/common/base_class.py +++ b/stable_baselines/common/base_class.py @@ -43,6 +43,10 @@ def __init__(self, policy, env, verbose=0, *, requires_vec_env, policy_base, pol self.graph = None self.sess = None self.params = None + self.initial_state = None + self.n_batch = None + self.nminibatches = None + self.n_steps = None if env is not None: if isinstance(env, str): @@ -196,13 +200,23 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, else: val_interval = int(n_epochs / 10) + if self.initial_state is None: + use_lstm = False + else: + use_lstm = True + + batch_size = self.n_batch // self.nminibatches + envs_per_batch = batch_size // self.n_steps + with self.graph.as_default(): with tf.variable_scope('pretrain'): if continuous_actions: - obs_ph, actions_ph, deterministic_actions_ph = self._get_pretrain_placeholders() + obs_ph, actions_ph, states_ph, snew_ph, masks_ph, \ + deterministic_actions_ph = self._get_pretrain_placeholders() loss = tf.reduce_mean(tf.square(actions_ph - deterministic_actions_ph)) else: - obs_ph, actions_ph, actions_logits_ph = self._get_pretrain_placeholders() + obs_ph, actions_ph, states_ph, snew_ph, masks_ph, \ + actions_logits_ph = self._get_pretrain_placeholders() # actions_ph has a shape if (n_batch,), we reshape it to (n_batch, 1) # so no additional changes is needed in the dataloader actions_ph = tf.expand_dims(actions_ph, axis=1) @@ -222,13 +236,22 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, for epoch_idx in range(int(n_epochs)): train_loss = 0.0 + state = self.initial_state[:envs_per_batch] + # Full pass on the training set for _ in range(len(dataset.train_loader)): - expert_obs, expert_actions = dataset.get_next_batch('train') + expert_obs, expert_actions, expert_mask = dataset.get_next_batch('train') feed_dict = { obs_ph: expert_obs, actions_ph: expert_actions, } + + if use_lstm: + feed_dict.update({states_ph: state, masks_ph: expert_mask}) + state, train_loss_, _ = self.sess.run([snew_ph, loss, optim_op], feed_dict) + else: + train_loss_, _ = self.sess.run([loss, optim_op], feed_dict) + train_loss_, _ = self.sess.run([loss, optim_op], feed_dict) train_loss += train_loss_ @@ -238,9 +261,19 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, val_loss = 0.0 # Full pass on the validation set for _ in range(len(dataset.val_loader)): - expert_obs, expert_actions = dataset.get_next_batch('val') - val_loss_, = self.sess.run([loss], {obs_ph: expert_obs, - actions_ph: expert_actions}) + expert_obs, expert_actions, expert_mask = dataset.get_next_batch('val') + + feed_dict = { + obs_ph: expert_obs, + actions_ph: expert_actions, + } + + if use_lstm: + feed_dict.update({states_ph: state, masks_ph: expert_mask}) + val_loss_, = self.sess.run([loss], feed_dict) + else: + val_loss_, = self.sess.run([loss], feed_dict) + val_loss += val_loss_ val_loss /= len(dataset.val_loader) From c708a37eaff9a814646f6b95631c75e2cf7bd910 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Thu, 11 Apr 2019 21:24:11 +0200 Subject: [PATCH 02/34] add mask support to DataLoader add frame index aliment to ExpertDataset --- stable_baselines/gail/dataset/dataset.py | 84 +++++++++++++++++++++--- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 65a4778828..9d7039172f 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -5,6 +5,7 @@ import cv2 import numpy as np from joblib import Parallel, delayed +from itertools import cycle, islice import matplotlib.pyplot as plt from stable_baselines import logger @@ -32,13 +33,23 @@ class ExpertDataset(object): def __init__(self, expert_path, train_fraction=0.7, batch_size=64, traj_limitation=-1, randomize=True, verbose=1, - sequential_preprocessing=False): + sequential_preprocessing=False, LSTM=False, + nminibatches=4, n_envs=4): + traj_data = np.load(expert_path) if verbose > 0: for key, val in traj_data.items(): print(key, val.shape) + if LSTM: + n_batch = n_envs * batch_size + _batch_size = n_batch // nminibatches + envs_per_batch = _batch_size // batch_size + use_batch_size = batch_size * envs_per_batch + else: + use_batch_size = batch_size + # Array of bool where episode_starts[i] = True for each new episode episode_starts = traj_data['episode_starts'] @@ -55,6 +66,15 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, observations = traj_data['obs'][:traj_limit_idx] actions = traj_data['actions'][:traj_limit_idx] + mask = episode_starts[:traj_limit_idx] + + start_index_list = [] + if LSTM: + for idx, episode_start in enumerate(mask): + if episode_start: + start_index_list.append(idx) + + start_index_list += [traj_limit_idx] # obs, actions: shape (N * L, ) + S # where N = # episodes, L = episode length @@ -65,12 +85,52 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, observations = np.reshape(observations, [-1, np.prod(observations.shape[1:])]) if len(actions.shape) > 2: actions = np.reshape(actions, [-1, np.prod(actions.shape[1:])]) + if len(mask.shape) > 2: + mask = np.reshape(mask, [-1, np.prod(mask.shape[1:])]) + + if LSTM: + indices = np.arange(start=0, stop=len(observations)).astype(np.int64) + split_indices = [indices[start_index_list[i]:start_index_list[i+1]].tolist() for i in range(0, len(start_index_list)-1)] + + ignor = len(split_indices) % envs_per_batch + if ignor > 0: + split_indices = split_indices[:-ignor] + + len_list = [len(s_i) for s_i in split_indices] + + print(len(len_list), envs_per_batch) + assert len(len_list) >= envs_per_batch*2, "Not enough saved episodes for this number of workers and nminibatches." + + sort_buffer = np.argsort(len_list) + stackt_indices = [[] for i in range(envs_per_batch)] - indices = np.random.permutation(len(observations)).astype(np.int64) + for i in range(0, len(sort_buffer), envs_per_batch): + for idx, k in enumerate(range(i, i + envs_per_batch)): + stackt_indices[idx] += split_indices[sort_buffer[k]] - # Train/Validation split when using behavior cloning - train_indices = indices[:int(train_fraction * len(indices))] - val_indices = indices[int(train_fraction * len(indices)):] + max_len = max([len(i) for i in stackt_indices]) + mod_max_len = max_len % batch_size + final_stack_len = max_len + (batch_size - mod_max_len) + + indices = [list(islice(cycle(i), None, final_stack_len)) for i in stackt_indices] + indices = np.array(indices).flatten() + + del split_indices, len_list, sort_buffer, stackt_indices, max_len, mod_max_len, final_stack_len + + # Train/Validation split when using behavior cloning + split_point = int(train_fraction * len(indices)) + split_point = split_point - (split_point % batch_size) + + train_indices = indices[:split_point] + val_indices = indices[split_point:] + + else: + + indices = np.random.permutation(len(observations)).astype(np.int64) + + # Train/Validation split when using behavior cloning + train_indices = indices[:int(train_fraction * len(indices))] + val_indices = indices[int(train_fraction * len(indices)):] assert len(train_indices) > 0, "No sample for the training set" assert len(val_indices) > 0, "No sample for the validation set" @@ -91,10 +151,10 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, batch_size, + self.train_loader = DataLoader(train_indices, self.observations, self.actions, use_batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, batch_size, + self.val_loader = DataLoader(val_indices, self.observations, self.actions, use_batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) @@ -185,7 +245,7 @@ class DataLoader(object): lesser than the batch_size) """ - def __init__(self, indices, observations, actions, batch_size, n_workers=1, + def __init__(self, indices, observations, actions, mask, batch_size, n_workers=1, infinite_loop=True, max_queue_len=1, shuffle=False, start_process=True, backend='threading', sequential=False, partial_minibatch=True): super(DataLoader, self).__init__() @@ -201,6 +261,7 @@ def __init__(self, indices, observations, actions, batch_size, n_workers=1, self.batch_size = batch_size self.observations = observations self.actions = actions + self.mask = mask self.shuffle = shuffle self.queue = Queue(max_queue_len) self.process = None @@ -249,8 +310,10 @@ def sequential_next(self): axis=0) actions = self.actions[self._minibatch_indices] + mask = self.mask[self._minibatch_indices] self.start_idx += self.batch_size - return obs, actions + + return obs, actions, mask def _run(self): start = True @@ -278,8 +341,9 @@ def _run(self): obs = np.concatenate(obs, axis=0) actions = self.actions[self._minibatch_indices] + mask = self.mask[self._minibatch_indices] - self.queue.put((obs, actions)) + self.queue.put((obs, actions, mask)) # Free memory del obs From 169a80b944226b206580f8ff2996cee648257695 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 13 Apr 2019 18:57:10 +0200 Subject: [PATCH 03/34] add better data split --- stable_baselines/gail/dataset/dataset.py | 32 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 9d7039172f..f7b6172e87 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -1,5 +1,6 @@ import queue import time +import warnings from multiprocessing import Queue, Process import cv2 @@ -101,26 +102,37 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, print(len(len_list), envs_per_batch) assert len(len_list) >= envs_per_batch*2, "Not enough saved episodes for this number of workers and nminibatches." - sort_buffer = np.argsort(len_list) - stackt_indices = [[] for i in range(envs_per_batch)] + sort_buffer = np.argsort(len_list).tolist()[::-1] + stackt_indices = [] + for i in range(envs_per_batch): + stackt_indices.append([split_indices[sort_buffer[0]]]) + sort_buffer.pop(0) - for i in range(0, len(sort_buffer), envs_per_batch): - for idx, k in enumerate(range(i, i + envs_per_batch)): - stackt_indices[idx] += split_indices[sort_buffer[k]] + for s_b in sort_buffer: + currend_stackt_indices_len = [len(st_i) for st_i in stackt_indices] + smalest_stackt_indices_pos = np.argmin(currend_stackt_indices_len) + stackt_indices[smalest_stackt_indices_pos] += split_indices[s_b] - max_len = max([len(i) for i in stackt_indices]) + pre_cycle_len = [len(st_i) for st_i in stackt_indices] + max_len = max(pre_cycle_len) + min_len = min(pre_cycle_len) mod_max_len = max_len % batch_size final_stack_len = max_len + (batch_size - mod_max_len) - indices = [list(islice(cycle(i), None, final_stack_len)) for i in stackt_indices] + split_point = int(train_fraction * final_stack_len * envs_per_batch) + split_point = split_point - (split_point % batch_size) + + if mod_max_len > (min_len - (final_stack_len * envs_per_batch - split_point)): + warnings.warn('The Episode are divide to unequal, your validation set will ' + 'get polluted with training data.') + + indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stackt_indices] + indices = [indices[i][pre_cycle_len[i]:] + indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] indices = np.array(indices).flatten() del split_indices, len_list, sort_buffer, stackt_indices, max_len, mod_max_len, final_stack_len # Train/Validation split when using behavior cloning - split_point = int(train_fraction * len(indices)) - split_point = split_point - (split_point % batch_size) - train_indices = indices[:split_point] val_indices = indices[split_point:] From b0ee4c71abc80b86a9b570d501608d57bed943f0 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 13 Apr 2019 19:27:41 +0200 Subject: [PATCH 04/34] add comments and fix some bugs --- stable_baselines/gail/dataset/dataset.py | 43 +++++++++++++++--------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index f7b6172e87..9b3e56da67 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -90,35 +90,39 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, mask = np.reshape(mask, [-1, np.prod(mask.shape[1:])]) if LSTM: + + # Creat indices list and split them per episode. indices = np.arange(start=0, stop=len(observations)).astype(np.int64) split_indices = [indices[start_index_list[i]:start_index_list[i+1]].tolist() for i in range(0, len(start_index_list)-1)] - ignor = len(split_indices) % envs_per_batch - if ignor > 0: - split_indices = split_indices[:-ignor] - + # Create list with episode lengths. len_list = [len(s_i) for s_i in split_indices] - print(len(len_list), envs_per_batch) - assert len(len_list) >= envs_per_batch*2, "Not enough saved episodes for this number of workers and nminibatches." + assert len(len_list) >= envs_per_batch, "Not enough saved episodes for this number of workers and nminibatches." + # Sort episode pos by lengths. sort_buffer = np.argsort(len_list).tolist()[::-1] - stackt_indices = [] + + # Creat stack list and pre fill then with the longest episodes. + stack_indices = [] for i in range(envs_per_batch): - stackt_indices.append([split_indices[sort_buffer[0]]]) + stack_indices.append([split_indices[sort_buffer[0]]]) sort_buffer.pop(0) + # Add next episode to the smallest stack. for s_b in sort_buffer: - currend_stackt_indices_len = [len(st_i) for st_i in stackt_indices] + currend_stackt_indices_len = [len(st_i) for st_i in stack_indices] smalest_stackt_indices_pos = np.argmin(currend_stackt_indices_len) - stackt_indices[smalest_stackt_indices_pos] += split_indices[s_b] + stack_indices[smalest_stackt_indices_pos] += split_indices[s_b] - pre_cycle_len = [len(st_i) for st_i in stackt_indices] + # Creat info varibelts used for data cycle. + pre_cycle_len = [len(st_i) for st_i in stack_indices] max_len = max(pre_cycle_len) min_len = min(pre_cycle_len) mod_max_len = max_len % batch_size final_stack_len = max_len + (batch_size - mod_max_len) + # Calculate split point for Train/Validation split. split_point = int(train_fraction * final_stack_len * envs_per_batch) split_point = split_point - (split_point % batch_size) @@ -126,11 +130,17 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, warnings.warn('The Episode are divide to unequal, your validation set will ' 'get polluted with training data.') - indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stackt_indices] + # Cycle to it self to creat enough data to split it to batch_size length. + indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] + + # Put the cycled data to the beginning to not affect the validation set. indices = [indices[i][pre_cycle_len[i]:] + indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] + + # Flatten the stack list to a single list. indices = np.array(indices).flatten() - del split_indices, len_list, sort_buffer, stackt_indices, max_len, mod_max_len, final_stack_len + # Free memory + del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len # Train/Validation split when using behavior cloning train_indices = indices[:split_point] @@ -149,6 +159,7 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, self.observations = observations self.actions = actions + self.mask = mask self.returns = traj_data['episode_returns'][:traj_limit_idx] self.avg_ret = sum(self.returns) / len(self.returns) @@ -163,10 +174,10 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, use_batch_size, + self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, use_batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, use_batch_size, + self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, use_batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) @@ -180,7 +191,7 @@ def init_dataloader(self, batch_size): :param batch_size: (int) """ indices = np.random.permutation(len(self.observations)).astype(np.int64) - self.dataloader = DataLoader(indices, self.observations, self.actions, batch_size, + self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, batch_size, shuffle=self.randomize, start_process=False, sequential=self.sequential_preprocessing) From 027891f3d96f53284ff9e7b08282386c8b40a2ac Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 13 Apr 2019 19:33:46 +0200 Subject: [PATCH 05/34] when using dataset.get_next_batch to expect fore returns. --- stable_baselines/trpo_mpi/trpo_mpi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stable_baselines/trpo_mpi/trpo_mpi.py b/stable_baselines/trpo_mpi/trpo_mpi.py index 975f593eff..efe1541624 100644 --- a/stable_baselines/trpo_mpi/trpo_mpi.py +++ b/stable_baselines/trpo_mpi/trpo_mpi.py @@ -427,7 +427,7 @@ def fisher_vector_product(vec): for ob_batch, ac_batch in dataset.iterbatches((observation, action), include_final_partial_batch=False, batch_size=batch_size): - ob_expert, ac_expert = self.expert_dataset.get_next_batch() + ob_expert, ac_expert, _ = self.expert_dataset.get_next_batch() # update running mean/std for reward_giver if self.reward_giver.normalize: self.reward_giver.obs_rms.update(np.concatenate((ob_batch, ob_expert), 0)) From b7541bd85d20ed06dc91a16ba206678c3506150b Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 13 Apr 2019 20:19:42 +0200 Subject: [PATCH 06/34] update _get_pretrain_placeholders in all models. --- stable_baselines/a2c/a2c.py | 14 ++++++++++++-- stable_baselines/acer/acer_simple.py | 12 +++++++++++- stable_baselines/acktr/acktr_disc.py | 12 +++++++++++- stable_baselines/common/base_class.py | 2 +- stable_baselines/ddpg/ddpg.py | 2 +- stable_baselines/deepq/dqn.py | 2 +- stable_baselines/ppo1/pposgd_simple.py | 14 ++++++++++++-- stable_baselines/ppo2/ppo2.py | 17 ++++++++++++++--- stable_baselines/sac/sac.py | 2 +- stable_baselines/trpo_mpi/trpo_mpi.py | 14 ++++++++++++-- 10 files changed, 76 insertions(+), 15 deletions(-) diff --git a/stable_baselines/a2c/a2c.py b/stable_baselines/a2c/a2c.py index 2dab42e9f6..e2a33fae80 100644 --- a/stable_baselines/a2c/a2c.py +++ b/stable_baselines/a2c/a2c.py @@ -87,9 +87,19 @@ def __init__(self, policy, env, gamma=0.99, n_steps=5, vf_coef=0.25, ent_coef=0. def _get_pretrain_placeholders(self): policy = self.train_model + + if self.initial_state is None: + states_ph = None + snew_ph = None + masks_ph = None + else: + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, self.actions_ph, policy.policy - return policy.obs_ph, self.actions_ph, policy.deterministic_action + return policy.obs_ph, self.actions_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, self.actions_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/acer/acer_simple.py b/stable_baselines/acer/acer_simple.py index e5b7055713..11047013d6 100644 --- a/stable_baselines/acer/acer_simple.py +++ b/stable_baselines/acer/acer_simple.py @@ -152,8 +152,18 @@ def __init__(self, policy, env, gamma=0.99, n_steps=20, num_procs=1, q_coef=0.5, def _get_pretrain_placeholders(self): policy = self.step_model action_ph = policy.pdtype.sample_placeholder([None]) + + if self.initial_state is None: + states_ph = None + snew_ph = None + masks_ph = None + else: + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, Discrete): - return policy.obs_ph, action_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy raise NotImplementedError('Only discrete actions are supported for ACER for now') def set_env(self, env): diff --git a/stable_baselines/acktr/acktr_disc.py b/stable_baselines/acktr/acktr_disc.py index 70de961f53..67309c1d5d 100644 --- a/stable_baselines/acktr/acktr_disc.py +++ b/stable_baselines/acktr/acktr_disc.py @@ -104,8 +104,18 @@ def __init__(self, policy, env, gamma=0.99, nprocs=1, n_steps=20, ent_coef=0.01, def _get_pretrain_placeholders(self): policy = self.train_model + + if self.initial_state is None: + states_ph = None + snew_ph = None + masks_ph = None + else: + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, Discrete): - return policy.obs_ph, self.action_ph, policy.policy + return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.policy raise NotImplementedError("WIP: ACKTR does not support Continuous actions yet.") def setup_model(self): diff --git a/stable_baselines/common/base_class.py b/stable_baselines/common/base_class.py index 9f31d48787..0e0af282e0 100644 --- a/stable_baselines/common/base_class.py +++ b/stable_baselines/common/base_class.py @@ -201,7 +201,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, val_interval = int(n_epochs / 10) if self.initial_state is None: - use_lstm = False + use_lstm = False else: use_lstm = True diff --git a/stable_baselines/ddpg/ddpg.py b/stable_baselines/ddpg/ddpg.py index 82e3a1b48a..0a78fe4434 100644 --- a/stable_baselines/ddpg/ddpg.py +++ b/stable_baselines/ddpg/ddpg.py @@ -273,7 +273,7 @@ def _get_pretrain_placeholders(self): policy = self.policy_tf # Rescale deterministic_action = self.actor_tf * np.abs(self.action_space.low) - return policy.obs_ph, self.actions, deterministic_action + return policy.obs_ph, self.actions, None, None, None, deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/deepq/dqn.py b/stable_baselines/deepq/dqn.py index d56dd34a8b..3aa97a94c2 100644 --- a/stable_baselines/deepq/dqn.py +++ b/stable_baselines/deepq/dqn.py @@ -99,7 +99,7 @@ def __init__(self, policy, env, gamma=0.99, learning_rate=5e-4, buffer_size=5000 def _get_pretrain_placeholders(self): policy = self.step_model - return policy.obs_ph, tf.placeholder(tf.int32, [None]), policy.q_values + return policy.obs_ph, tf.placeholder(tf.int32, [None]), None, None, None, policy.q_values def setup_model(self): diff --git a/stable_baselines/ppo1/pposgd_simple.py b/stable_baselines/ppo1/pposgd_simple.py index 04d34464c8..281b1e37ba 100644 --- a/stable_baselines/ppo1/pposgd_simple.py +++ b/stable_baselines/ppo1/pposgd_simple.py @@ -85,9 +85,19 @@ def __init__(self, policy, env, gamma=0.99, timesteps_per_actorbatch=256, clip_p def _get_pretrain_placeholders(self): policy = self.policy_pi action_ph = policy.pdtype.sample_placeholder([None]) + + if self.initial_state is None: + states_ph = None + snew_ph = None + masks_ph = None + else: + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, action_ph, policy.policy - return policy.obs_ph, action_ph, policy.deterministic_action + return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/ppo2/ppo2.py b/stable_baselines/ppo2/ppo2.py index f48f3859c6..c18d5783ae 100644 --- a/stable_baselines/ppo2/ppo2.py +++ b/stable_baselines/ppo2/ppo2.py @@ -93,10 +93,21 @@ def __init__(self, policy, env, gamma=0.99, n_steps=128, ent_coef=0.01, learning self.setup_model() def _get_pretrain_placeholders(self): - policy = self.act_model + + if self.initial_state is None: + policy = self.act_model + states_ph = None + snew_ph = None + masks_ph = None + else: + policy = self.train_model + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, self.action_ph, policy.policy - return policy.obs_ph, self.action_ph, policy.deterministic_action + return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/sac/sac.py b/stable_baselines/sac/sac.py index aef03eaa66..5c570c69bd 100644 --- a/stable_baselines/sac/sac.py +++ b/stable_baselines/sac/sac.py @@ -126,7 +126,7 @@ def _get_pretrain_placeholders(self): policy = self.policy_tf # Rescale deterministic_action = self.deterministic_action * np.abs(self.action_space.low) - return policy.obs_ph, self.actions_ph, deterministic_action + return policy.obs_ph, self.actions_ph, None, None, None, deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/trpo_mpi/trpo_mpi.py b/stable_baselines/trpo_mpi/trpo_mpi.py index efe1541624..23e976b4dc 100644 --- a/stable_baselines/trpo_mpi/trpo_mpi.py +++ b/stable_baselines/trpo_mpi/trpo_mpi.py @@ -99,9 +99,19 @@ def __init__(self, policy, env, gamma=0.99, timesteps_per_batch=1024, max_kl=0.0 def _get_pretrain_placeholders(self): policy = self.policy_pi action_ph = policy.pdtype.sample_placeholder([None]) + + if self.initial_state is None: + states_ph = None + snew_ph = None + masks_ph = None + else: + states_ph = policy.states_ph + snew_ph = policy.snew + masks_ph = policy.masks_ph + if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, action_ph, policy.policy - return policy.obs_ph, action_ph, policy.deterministic_action + return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action def setup_model(self): # prevent import loops From 11a9d007ca8625da7c77919bbc942ea7d0601cdf Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 8 May 2019 11:14:24 +0200 Subject: [PATCH 07/34] make it work. --- stable_baselines/common/base_class.py | 11 +++-- stable_baselines/gail/dataset/dataset.py | 28 ++++++------ tests/test_gail.py | 56 ++++++++++++++++-------- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/stable_baselines/common/base_class.py b/stable_baselines/common/base_class.py index 0e0af282e0..5281b1d280 100644 --- a/stable_baselines/common/base_class.py +++ b/stable_baselines/common/base_class.py @@ -205,8 +205,12 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, else: use_lstm = True - batch_size = self.n_batch // self.nminibatches - envs_per_batch = batch_size // self.n_steps + if use_lstm: + if self.nminibatches is None: + envs_per_batch = self.n_envs * self.n_steps + else: + batch_size = self.n_batch // self.nminibatches + envs_per_batch = batch_size // self.n_steps with self.graph.as_default(): with tf.variable_scope('pretrain'): @@ -236,7 +240,8 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, for epoch_idx in range(int(n_epochs)): train_loss = 0.0 - state = self.initial_state[:envs_per_batch] + if use_lstm: + state = self.initial_state[:envs_per_batch] # Full pass on the training set for _ in range(len(dataset.train_loader)): diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 9b3e56da67..165f56afdd 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -34,8 +34,7 @@ class ExpertDataset(object): def __init__(self, expert_path, train_fraction=0.7, batch_size=64, traj_limitation=-1, randomize=True, verbose=1, - sequential_preprocessing=False, LSTM=False, - nminibatches=4, n_envs=4): + sequential_preprocessing=False, LSTM=False, envs_per_batch=1): traj_data = np.load(expert_path) @@ -43,13 +42,7 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, for key, val in traj_data.items(): print(key, val.shape) - if LSTM: - n_batch = n_envs * batch_size - _batch_size = n_batch // nminibatches - envs_per_batch = _batch_size // batch_size - use_batch_size = batch_size * envs_per_batch - else: - use_batch_size = batch_size + use_batch_size = batch_size * envs_per_batch # Array of bool where episode_starts[i] = True for each new episode episode_starts = traj_data['episode_starts'] @@ -106,7 +99,7 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, # Creat stack list and pre fill then with the longest episodes. stack_indices = [] for i in range(envs_per_batch): - stack_indices.append([split_indices[sort_buffer[0]]]) + stack_indices.append(split_indices[sort_buffer[0]]) sort_buffer.pop(0) # Add next episode to the smallest stack. @@ -124,9 +117,9 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, # Calculate split point for Train/Validation split. split_point = int(train_fraction * final_stack_len * envs_per_batch) - split_point = split_point - (split_point % batch_size) + split_point = split_point - (split_point % use_batch_size) - if mod_max_len > (min_len - (final_stack_len * envs_per_batch - split_point)): + if mod_max_len > (min_len - (final_stack_len * envs_per_batch - split_point)) > 0: warnings.warn('The Episode are divide to unequal, your validation set will ' 'get polluted with training data.') @@ -137,7 +130,7 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, indices = [indices[i][pre_cycle_len[i]:] + indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] # Flatten the stack list to a single list. - indices = np.array(indices).flatten() + indices = np.array(indices).flatten('F') # Free memory del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len @@ -146,6 +139,9 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, train_indices = indices[:split_point] val_indices = indices[split_point:] + # Set randomize. + self.randomize = False + else: indices = np.random.permutation(len(observations)).astype(np.int64) @@ -154,6 +150,9 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, train_indices = indices[:int(train_fraction * len(indices))] val_indices = indices[int(train_fraction * len(indices)):] + # Set randomize. + self.randomize = randomize + assert len(train_indices) > 0, "No sample for the training set" assert len(val_indices) > 0, "No sample for the validation set" @@ -170,7 +169,6 @@ def __init__(self, expert_path, train_fraction=0.7, batch_size=64, "please check your expert dataset" self.num_traj = min(traj_limitation, np.sum(episode_starts)) self.num_transition = len(self.observations) - self.randomize = randomize self.sequential_preprocessing = sequential_preprocessing self.dataloader = None @@ -319,7 +317,7 @@ def sequential_next(self): """ Sequential version of the pre-processing. """ - if self.start_idx > len(self.indices): + if self.start_idx >= len(self.indices): raise StopIteration if self.start_idx == 0: diff --git a/tests/test_gail.py b/tests/test_gail.py index e57ef1de66..5f083a9090 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -5,7 +5,7 @@ from stable_baselines import A2C, ACER, ACKTR, GAIL, DDPG, DQN, PPO1, PPO2, TRPO, SAC from stable_baselines.common.cmd_util import make_atari_env -from stable_baselines.common.vec_env import VecFrameStack +from stable_baselines.common.vec_env import VecFrameStack, DummyVecEnv from stable_baselines.gail import ExpertDataset, generate_expert_traj EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" @@ -78,24 +78,42 @@ def test_pretrain_images(): del dataset, model, env -@pytest.mark.parametrize("model_class", [A2C, GAIL, DDPG, PPO1, PPO2, SAC, TRPO]) -def test_behavior_cloning_box(model_class): - """ - Behavior cloning with continuous actions. - """ - dataset = ExpertDataset(expert_path=EXPERT_PATH_PENDULUM, traj_limitation=10, - sequential_preprocessing=True, verbose=0) - model = model_class("MlpPolicy", "Pendulum-v0") - model.pretrain(dataset, n_epochs=20) - model.save("test-pretrain") - del dataset, model +@pytest.mark.parametrize("model_class_data", [[A2C, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 4], + [ACER, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 1, 4], + [ACKTR, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 4], + [PPO2, 8, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 2], + [A2C, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [ACER, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [ACKTR, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [DQN, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [GAIL, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [PPO1, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [PPO2, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [TRPO, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [A2C, 4, True, "MlpLstmPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 4], + [PPO2, 8, True, "MlpLstmPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 16, 2], + [A2C, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [GAIL, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [PPO1, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [PPO2, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [TRPO, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1]]) + +def test_behavior_cloning_discrete(model_class_data): -@pytest.mark.parametrize("model_class", [A2C, ACER, ACKTR, DQN, GAIL, PPO1, PPO2, TRPO]) -def test_behavior_cloning_discrete(model_class): - dataset = ExpertDataset(expert_path=EXPERT_PATH_DISCRETE, traj_limitation=10, - sequential_preprocessing=True, verbose=0) - model = model_class("MlpPolicy", "CartPole-v1") - model.pretrain(dataset, n_epochs=10) + model_class, num_env, lstm, policy, game, load_data, batch_size, envs_per_batch = model_class_data + dataset = ExpertDataset(expert_path=load_data, traj_limitation=3, + sequential_preprocessing=True, verbose=0, LSTM=lstm, + batch_size=batch_size, envs_per_batch=envs_per_batch) + + env = DummyVecEnv([lambda: gym.make(game) for i in range(num_env)]) + + try: + model = model_class(policy, env, n_steps=batch_size) + except TypeError: + model = model_class(policy, env) + + + model.pretrain(dataset, n_epochs=3) model.save("test-pretrain") - del dataset, model + del dataset, model, env \ No newline at end of file From 167a337cc8895300b0778d40cd0f7322c2668c6f Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 8 May 2019 16:32:18 +0200 Subject: [PATCH 08/34] Make it work with 2.5.1 --- stable_baselines/a2c/a2c.py | 8 ++++---- stable_baselines/acer/acer_simple.py | 6 +++--- stable_baselines/acktr/acktr_disc.py | 6 +++--- stable_baselines/common/base_class.py | 13 +++++-------- stable_baselines/gail/dataset/dataset.py | 2 -- stable_baselines/ppo1/pposgd_simple.py | 8 ++++---- stable_baselines/ppo2/ppo2.py | 8 ++++---- stable_baselines/trpo_mpi/trpo_mpi.py | 8 ++++---- tests/test_gail.py | 3 +-- 9 files changed, 28 insertions(+), 34 deletions(-) diff --git a/stable_baselines/a2c/a2c.py b/stable_baselines/a2c/a2c.py index e590efb944..6c625b59da 100644 --- a/stable_baselines/a2c/a2c.py +++ b/stable_baselines/a2c/a2c.py @@ -91,15 +91,15 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, self.actions_ph, states_ph, snew_ph, masks_ph, policy.policy - return policy.obs_ph, self.actions_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action + return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph, policy.policy + return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/acer/acer_simple.py b/stable_baselines/acer/acer_simple.py index 3549fd9b8c..fa85a8cf84 100644 --- a/stable_baselines/acer/acer_simple.py +++ b/stable_baselines/acer/acer_simple.py @@ -156,14 +156,14 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, Discrete): - return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.policy raise NotImplementedError('Only discrete actions are supported for ACER for now') def set_env(self, env): diff --git a/stable_baselines/acktr/acktr_disc.py b/stable_baselines/acktr/acktr_disc.py index fa27ca7cc9..d93982b1a2 100644 --- a/stable_baselines/acktr/acktr_disc.py +++ b/stable_baselines/acktr/acktr_disc.py @@ -108,14 +108,14 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, Discrete): - return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.policy + return policy.obs_ph, self.action_ph, states_ph, snew_ph, dones_ph, policy.policy raise NotImplementedError("WIP: ACKTR does not support Continuous actions yet.") def setup_model(self): diff --git a/stable_baselines/common/base_class.py b/stable_baselines/common/base_class.py index 4eb88b8e4a..da80220f69 100644 --- a/stable_baselines/common/base_class.py +++ b/stable_baselines/common/base_class.py @@ -200,10 +200,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, else: val_interval = int(n_epochs / 10) - if self.initial_state is None: - use_lstm = False - else: - use_lstm = True + use_lstm = self.initial_state is not None if use_lstm: if self.nminibatches is None: @@ -215,11 +212,11 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, with self.graph.as_default(): with tf.variable_scope('pretrain'): if continuous_actions: - obs_ph, actions_ph, states_ph, snew_ph, masks_ph, \ + obs_ph, actions_ph, states_ph, snew_ph, dones_ph, \ deterministic_actions_ph = self._get_pretrain_placeholders() loss = tf.reduce_mean(tf.square(actions_ph - deterministic_actions_ph)) else: - obs_ph, actions_ph, states_ph, snew_ph, masks_ph, \ + obs_ph, actions_ph, states_ph, snew_ph, dones_ph, \ actions_logits_ph = self._get_pretrain_placeholders() # actions_ph has a shape if (n_batch,), we reshape it to (n_batch, 1) # so no additional changes is needed in the dataloader @@ -252,7 +249,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, } if use_lstm: - feed_dict.update({states_ph: state, masks_ph: expert_mask}) + feed_dict.update({states_ph: state, dones_ph: expert_mask}) state, train_loss_, _ = self.sess.run([snew_ph, loss, optim_op], feed_dict) else: train_loss_, _ = self.sess.run([loss, optim_op], feed_dict) @@ -274,7 +271,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, } if use_lstm: - feed_dict.update({states_ph: state, masks_ph: expert_mask}) + feed_dict.update({states_ph: state, dones_ph: expert_mask}) val_loss_, = self.sess.run([loss], feed_dict) else: val_loss_, = self.sess.run([loss], feed_dict) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index a6b2cf4da7..cbd4c17823 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -46,8 +46,6 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if traj_data is None: traj_data = np.load(expert_path) - traj_data = np.load(expert_path) - if verbose > 0: for key, val in traj_data.items(): print(key, val.shape) diff --git a/stable_baselines/ppo1/pposgd_simple.py b/stable_baselines/ppo1/pposgd_simple.py index 5c8bcfbe91..ef6ac2fa8c 100644 --- a/stable_baselines/ppo1/pposgd_simple.py +++ b/stable_baselines/ppo1/pposgd_simple.py @@ -89,15 +89,15 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy - return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action + return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/ppo2/ppo2.py b/stable_baselines/ppo2/ppo2.py index 1e6f6d3458..1668c772ef 100644 --- a/stable_baselines/ppo2/ppo2.py +++ b/stable_baselines/ppo2/ppo2.py @@ -98,16 +98,16 @@ def _get_pretrain_placeholders(self): policy = self.act_model states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: policy = self.train_model states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.policy - return policy.obs_ph, self.action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action + return policy.obs_ph, self.action_ph, states_ph, snew_ph, dones_ph, policy.policy + return policy.obs_ph, self.action_ph, states_ph, snew_ph, dones_ph, policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/trpo_mpi/trpo_mpi.py b/stable_baselines/trpo_mpi/trpo_mpi.py index 57ae6842c2..5abfc6e253 100644 --- a/stable_baselines/trpo_mpi/trpo_mpi.py +++ b/stable_baselines/trpo_mpi/trpo_mpi.py @@ -103,15 +103,15 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: states_ph = None snew_ph = None - masks_ph = None + dones_ph = None else: states_ph = policy.states_ph snew_ph = policy.snew - masks_ph = policy.masks_ph + dones_ph = policy.dones_ph if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.policy - return policy.obs_ph, action_ph, states_ph, snew_ph, masks_ph, policy.deterministic_action + return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.policy + return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.deterministic_action def setup_model(self): # prevent import loops diff --git a/tests/test_gail.py b/tests/test_gail.py index 6d294511ef..79f2667667 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -125,8 +125,7 @@ def test_pretrain_images(): [PPO2, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], [TRPO, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1]]) -def test_behavior_cloning_discrete(model_class_data): - +def test_behavior_cloning(model_class_data): model_class, num_env, lstm, policy, game, load_data, batch_size, envs_per_batch = model_class_data dataset = ExpertDataset(expert_path=load_data, traj_limitation=3, From 1827b2d6a545983a64f2910dd461eb731730c7e4 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 8 May 2019 19:39:54 +0200 Subject: [PATCH 09/34] improve the syntax --- run_docker_gpu.sh.save | 13 ------ stable_baselines/gail/dataset/dataset.py | 8 ++-- tests/test_gail.py | 59 ++++++++++++++++-------- 3 files changed, 44 insertions(+), 36 deletions(-) delete mode 100755 run_docker_gpu.sh.save diff --git a/run_docker_gpu.sh.save b/run_docker_gpu.sh.save deleted file mode 100755 index cba53ea608..0000000000 --- a/run_docker_gpu.sh.save +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# Launch an experiment using the docker gpu image - -cmd_line="$@" - -echo "Executing in the docker (gpu image):" -echo $cmd_line - - -docker run -it ---rm --network host --ipc=host \ - --mount src=$(pwd),target=/root/code/stable-baselines,type=bind araffin/stable-baselines\ - bash -c "cd /root/code/stable-baselines/ && $cmd_line" diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index cbd4c17823..410e36e72c 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -7,7 +7,6 @@ import numpy as np from joblib import Parallel, delayed from itertools import cycle, islice -import matplotlib.pyplot as plt from stable_baselines import logger @@ -94,12 +93,15 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, # Creat indices list and split them per episode. indices = np.arange(start=0, stop=len(observations)).astype(np.int64) - split_indices = [indices[start_index_list[i]:start_index_list[i+1]].tolist() for i in range(0, len(start_index_list)-1)] + split_indices = [indices[start_index_list[i]:start_index_list[i+1]]\ + .tolist() for i in range(0, len(start_index_list)-1)] # Create list with episode lengths. len_list = [len(s_i) for s_i in split_indices] - assert len(len_list) >= envs_per_batch, "Not enough saved episodes for this number of workers and nminibatches." + assert len(len_list) >= envs_per_batch, "Not enough saved " \ + "episodes for this number " \ + "of workers and nminibatches." # Sort episode pos by lengths. sort_buffer = np.argsort(len_list).tolist()[::-1] diff --git a/tests/test_gail.py b/tests/test_gail.py index 79f2667667..23ff32a182 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from stable_baselines import A2C, ACER, ACKTR, GAIL, DDPG, DQN, PPO1, PPO2, TRPO, SAC +from stable_baselines import A2C, ACER, ACKTR, GAIL, DQN, PPO1, PPO2, TRPO, SAC from stable_baselines.common.cmd_util import make_atari_env from stable_baselines.common.vec_env import VecFrameStack, DummyVecEnv from stable_baselines.gail import ExpertDataset, generate_expert_traj @@ -105,25 +105,44 @@ def test_pretrain_images(): del dataset, model, env -@pytest.mark.parametrize("model_class_data", [[A2C, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 4], - [ACER, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 1, 4], - [ACKTR, 4, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 4], - [PPO2, 8, True, "MlpLstmPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 2], - [A2C, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [ACER, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [ACKTR, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [DQN, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [GAIL, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [PPO1, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [PPO2, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [TRPO, 1, False, "MlpPolicy", "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], - [A2C, 4, True, "MlpLstmPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 4], - [PPO2, 8, True, "MlpLstmPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 16, 2], - [A2C, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], - [GAIL, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], - [PPO1, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], - [PPO2, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], - [TRPO, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1]]) +@pytest.mark.parametrize("model_class_data", [[A2C, 4, True, "MlpLstmPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 4], + [ACER, 4, True, "MlpLstmPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 1, 4], + [ACKTR, 4, True, "MlpLstmPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 4], + [PPO2, 8, True, "MlpLstmPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 16, 2], + [A2C, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [ACER, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [ACKTR, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [DQN, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [GAIL, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [PPO1, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [PPO2, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [TRPO, 1, False, "MlpPolicy", + "CartPole-v1", EXPERT_PATH_DISCRETE, 32, 1], + [A2C, 4, True, "MlpLstmPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 4], + [PPO2, 8, True, "MlpLstmPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 16, 2], + [A2C, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [GAIL, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [PPO1, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [PPO2, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [TRPO, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1]]) def test_behavior_cloning(model_class_data): From c43b39a7b647d852bdd661405f45739a8bd77006 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Tue, 14 May 2019 22:22:22 +0200 Subject: [PATCH 10/34] -fix partial_minibatch for LSTMs -convert float envs_per_batch in to int envs_per_batch --- stable_baselines/POfD/__init__.py | 1 + stable_baselines/POfD/ppo2.py | 519 +++++++++++++++++++++++ stable_baselines/POfD/run_atari.py | 47 ++ stable_baselines/POfD/run_mujoco.py | 58 +++ stable_baselines/gail/dataset/dataset.py | 5 +- 5 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 stable_baselines/POfD/__init__.py create mode 100644 stable_baselines/POfD/ppo2.py create mode 100644 stable_baselines/POfD/run_atari.py create mode 100644 stable_baselines/POfD/run_mujoco.py diff --git a/stable_baselines/POfD/__init__.py b/stable_baselines/POfD/__init__.py new file mode 100644 index 0000000000..6eb9f827f7 --- /dev/null +++ b/stable_baselines/POfD/__init__.py @@ -0,0 +1 @@ +from stable_baselines.ppo2.ppo2 import PPO2 diff --git a/stable_baselines/POfD/ppo2.py b/stable_baselines/POfD/ppo2.py new file mode 100644 index 0000000000..eb009cee78 --- /dev/null +++ b/stable_baselines/POfD/ppo2.py @@ -0,0 +1,519 @@ +import time +import sys +import multiprocessing +from collections import deque + +import gym +import numpy as np +import tensorflow as tf + +from stable_baselines import logger +from stable_baselines.common import explained_variance, ActorCriticRLModel, tf_util, SetVerbosity, TensorboardWriter +from stable_baselines.common.runners import AbstractEnvRunner +from stable_baselines.common.policies import ActorCriticPolicy, RecurrentActorCriticPolicy +from stable_baselines.a2c.utils import total_episode_reward_logger + + +class PPO2(ActorCriticRLModel): + """ + Proximal Policy Optimization algorithm (GPU version). + Paper: https://arxiv.org/abs/1707.06347 + + :param policy: (ActorCriticPolicy or str) The policy model to use (MlpPolicy, CnnPolicy, CnnLstmPolicy, ...) + :param env: (Gym environment or str) The environment to learn from (if registered in Gym, can be str) + :param gamma: (float) Discount factor + :param n_steps: (int) The number of steps to run for each environment per update + (i.e. batch size is n_steps * n_env where n_env is number of environment copies running in parallel) + :param ent_coef: (float) Entropy coefficient for the loss caculation + :param learning_rate: (float or callable) The learning rate, it can be a function + :param vf_coef: (float) Value function coefficient for the loss calculation + :param max_grad_norm: (float) The maximum value for the gradient clipping + :param lam: (float) Factor for trade-off of bias vs variance for Generalized Advantage Estimator + :param nminibatches: (int) Number of training minibatches per update. For recurrent policies, + the number of environments run in parallel should be a multiple of nminibatches. + :param noptepochs: (int) Number of epoch when optimizing the surrogate + :param cliprange: (float or callable) Clipping parameter, it can be a function + :param verbose: (int) the verbosity level: 0 none, 1 training information, 2 tensorflow debug + :param tensorboard_log: (str) the log location for tensorboard (if None, no logging) + :param _init_setup_model: (bool) Whether or not to build the network at the creation of the instance + :param policy_kwargs: (dict) additional arguments to be passed to the policy on creation + :param full_tensorboard_log: (bool) enable additional logging when using tensorboard + WARNING: this logging can take a lot of space quickly + """ + + def __init__(self, policy, env, gamma=0.99, n_steps=128, ent_coef=0.01, learning_rate=2.5e-4, vf_coef=0.5, + max_grad_norm=0.5, lam=0.95, nminibatches=4, noptepochs=4, cliprange=0.2, verbose=0, + tensorboard_log=None, _init_setup_model=True, policy_kwargs=None, + full_tensorboard_log=False): + + super(PPO2, self).__init__(policy=policy, env=env, verbose=verbose, requires_vec_env=True, + _init_setup_model=_init_setup_model, policy_kwargs=policy_kwargs) + + self.learning_rate = learning_rate + self.cliprange = cliprange + self.n_steps = n_steps + self.ent_coef = ent_coef + self.vf_coef = vf_coef + self.max_grad_norm = max_grad_norm + self.gamma = gamma + self.lam = lam + self.nminibatches = nminibatches + self.noptepochs = noptepochs + self.tensorboard_log = tensorboard_log + self.full_tensorboard_log = full_tensorboard_log + + self.graph = None + self.sess = None + self.action_ph = None + self.advs_ph = None + self.rewards_ph = None + self.old_neglog_pac_ph = None + self.old_vpred_ph = None + self.learning_rate_ph = None + self.clip_range_ph = None + self.entropy = None + self.vf_loss = None + self.pg_loss = None + self.approxkl = None + self.clipfrac = None + self.params = None + self._train = None + self.loss_names = None + self.train_model = None + self.act_model = None + self.step = None + self.proba_step = None + self.value = None + self.initial_state = None + self.n_batch = None + self.summary = None + self.episode_reward = None + + if _init_setup_model: + self.setup_model() + + def _get_pretrain_placeholders(self): + policy = self.act_model + if isinstance(self.action_space, gym.spaces.Discrete): + return policy.obs_ph, self.action_ph, policy.policy + return policy.obs_ph, self.action_ph, policy.deterministic_action + + def setup_model(self): + with SetVerbosity(self.verbose): + + assert issubclass(self.policy, ActorCriticPolicy), "Error: the input policy for the PPO2 model must be " \ + "an instance of common.policies.ActorCriticPolicy." + + self.n_batch = self.n_envs * self.n_steps + + n_cpu = multiprocessing.cpu_count() + if sys.platform == 'darwin': + n_cpu //= 2 + + self.graph = tf.Graph() + with self.graph.as_default(): + self.sess = tf_util.make_session(num_cpu=n_cpu, graph=self.graph) + + n_batch_step = None + n_batch_train = None + if issubclass(self.policy, RecurrentActorCriticPolicy): + assert self.n_envs % self.nminibatches == 0, "For recurrent policies, "\ + "the number of environments run in parallel should be a multiple of nminibatches." + n_batch_step = self.n_envs + n_batch_train = self.n_batch // self.nminibatches + + act_model = self.policy(self.sess, self.observation_space, self.action_space, self.n_envs, 1, + n_batch_step, reuse=False, **self.policy_kwargs) + with tf.variable_scope("train_model", reuse=True, + custom_getter=tf_util.outer_scope_getter("train_model")): + train_model = self.policy(self.sess, self.observation_space, self.action_space, + self.n_envs // self.nminibatches, self.n_steps, n_batch_train, + reuse=True, **self.policy_kwargs) + + with tf.variable_scope("loss", reuse=False): + self.action_ph = train_model.pdtype.sample_placeholder([None], name="action_ph") + self.advs_ph = tf.placeholder(tf.float32, [None], name="advs_ph") + self.rewards_ph = tf.placeholder(tf.float32, [None], name="rewards_ph") + self.old_neglog_pac_ph = tf.placeholder(tf.float32, [None], name="old_neglog_pac_ph") + self.old_vpred_ph = tf.placeholder(tf.float32, [None], name="old_vpred_ph") + self.learning_rate_ph = tf.placeholder(tf.float32, [], name="learning_rate_ph") + self.clip_range_ph = tf.placeholder(tf.float32, [], name="clip_range_ph") + + neglogpac = train_model.proba_distribution.neglogp(self.action_ph) + self.entropy = tf.reduce_mean(train_model.proba_distribution.entropy()) + + vpred = train_model.value_flat + vpredclipped = self.old_vpred_ph + tf.clip_by_value( + train_model.value_flat - self.old_vpred_ph, - self.clip_range_ph, self.clip_range_ph) + vf_losses1 = tf.square(vpred - self.rewards_ph) + vf_losses2 = tf.square(vpredclipped - self.rewards_ph) + self.vf_loss = .5 * tf.reduce_mean(tf.maximum(vf_losses1, vf_losses2)) + ratio = tf.exp(self.old_neglog_pac_ph - neglogpac) + pg_losses = -self.advs_ph * ratio + pg_losses2 = -self.advs_ph * tf.clip_by_value(ratio, 1.0 - self.clip_range_ph, 1.0 + + self.clip_range_ph) + self.pg_loss = tf.reduce_mean(tf.maximum(pg_losses, pg_losses2)) + self.approxkl = .5 * tf.reduce_mean(tf.square(neglogpac - self.old_neglog_pac_ph)) + self.clipfrac = tf.reduce_mean(tf.cast(tf.greater(tf.abs(ratio - 1.0), + self.clip_range_ph), tf.float32)) + loss = self.pg_loss - self.entropy * self.ent_coef + self.vf_loss * self.vf_coef + + tf.summary.scalar('entropy_loss', self.entropy) + tf.summary.scalar('policy_gradient_loss', self.pg_loss) + tf.summary.scalar('value_function_loss', self.vf_loss) + tf.summary.scalar('approximate_kullback-leibler', self.approxkl) + tf.summary.scalar('clip_factor', self.clipfrac) + tf.summary.scalar('loss', loss) + + with tf.variable_scope('model'): + self.params = tf.trainable_variables() + if self.full_tensorboard_log: + for var in self.params: + tf.summary.histogram(var.name, var) + grads = tf.gradients(loss, self.params) + if self.max_grad_norm is not None: + grads, _grad_norm = tf.clip_by_global_norm(grads, self.max_grad_norm) + grads = list(zip(grads, self.params)) + trainer = tf.train.AdamOptimizer(learning_rate=self.learning_rate_ph, epsilon=1e-5) + self._train = trainer.apply_gradients(grads) + + self.loss_names = ['policy_loss', 'value_loss', 'policy_entropy', 'approxkl', 'clipfrac'] + + with tf.variable_scope("input_info", reuse=False): + tf.summary.scalar('discounted_rewards', tf.reduce_mean(self.rewards_ph)) + tf.summary.scalar('learning_rate', tf.reduce_mean(self.learning_rate_ph)) + tf.summary.scalar('advantage', tf.reduce_mean(self.advs_ph)) + tf.summary.scalar('clip_range', tf.reduce_mean(self.clip_range_ph)) + tf.summary.scalar('old_neglog_action_probabilty', tf.reduce_mean(self.old_neglog_pac_ph)) + tf.summary.scalar('old_value_pred', tf.reduce_mean(self.old_vpred_ph)) + + if self.full_tensorboard_log: + tf.summary.histogram('discounted_rewards', self.rewards_ph) + tf.summary.histogram('learning_rate', self.learning_rate_ph) + tf.summary.histogram('advantage', self.advs_ph) + tf.summary.histogram('clip_range', self.clip_range_ph) + tf.summary.histogram('old_neglog_action_probabilty', self.old_neglog_pac_ph) + tf.summary.histogram('old_value_pred', self.old_vpred_ph) + if tf_util.is_image(self.observation_space): + tf.summary.image('observation', train_model.obs_ph) + else: + tf.summary.histogram('observation', train_model.obs_ph) + + self.train_model = train_model + self.act_model = act_model + self.step = act_model.step + self.proba_step = act_model.proba_step + self.value = act_model.value + self.initial_state = act_model.initial_state + tf.global_variables_initializer().run(session=self.sess) # pylint: disable=E1101 + + self.summary = tf.summary.merge_all() + + def _train_step(self, learning_rate, cliprange, obs, returns, masks, actions, values, neglogpacs, update, + writer, states=None): + """ + Training of PPO2 Algorithm + + :param learning_rate: (float) learning rate + :param cliprange: (float) Clipping factor + :param obs: (np.ndarray) The current observation of the environment + :param returns: (np.ndarray) the rewards + :param masks: (np.ndarray) The last masks for done episodes (used in recurent policies) + :param actions: (np.ndarray) the actions + :param values: (np.ndarray) the values + :param neglogpacs: (np.ndarray) Negative Log-likelihood probability of Actions + :param update: (int) the current step iteration + :param writer: (TensorFlow Summary.writer) the writer for tensorboard + :param states: (np.ndarray) For recurrent policies, the internal state of the recurrent model + :return: policy gradient loss, value function loss, policy entropy, + approximation of kl divergence, updated clipping range, training update operation + """ + advs = returns - values + advs = (advs - advs.mean()) / (advs.std() + 1e-8) + td_map = {self.train_model.obs_ph: obs, self.action_ph: actions, self.advs_ph: advs, self.rewards_ph: returns, + self.learning_rate_ph: learning_rate, self.clip_range_ph: cliprange, + self.old_neglog_pac_ph: neglogpacs, self.old_vpred_ph: values} + if states is not None: + td_map[self.train_model.states_ph] = states + td_map[self.train_model.dones_ph] = masks + + if states is None: + update_fac = self.n_batch // self.nminibatches // self.noptepochs + 1 + else: + update_fac = self.n_batch // self.nminibatches // self.noptepochs // self.n_steps + 1 + + if writer is not None: + # run loss backprop with summary, but once every 10 runs save the metadata (memory, compute time, ...) + if self.full_tensorboard_log and (1 + update) % 10 == 0: + run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) + run_metadata = tf.RunMetadata() + summary, policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( + [self.summary, self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], + td_map, options=run_options, run_metadata=run_metadata) + writer.add_run_metadata(run_metadata, 'step%d' % (update * update_fac)) + else: + summary, policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( + [self.summary, self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], + td_map) + writer.add_summary(summary, (update * update_fac)) + else: + policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( + [self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], td_map) + + return policy_loss, value_loss, policy_entropy, approxkl, clipfrac + + def learn(self, total_timesteps, callback=None, seed=None, log_interval=1, tb_log_name="PPO2", + reset_num_timesteps=True): + # Transform to callable if needed + self.learning_rate = get_schedule_fn(self.learning_rate) + self.cliprange = get_schedule_fn(self.cliprange) + + new_tb_log = self._init_num_timesteps(reset_num_timesteps) + + with SetVerbosity(self.verbose), TensorboardWriter(self.graph, self.tensorboard_log, tb_log_name, new_tb_log) \ + as writer: + self._setup_learn(seed) + + runner = Runner(env=self.env, model=self, n_steps=self.n_steps, gamma=self.gamma, lam=self.lam) + self.episode_reward = np.zeros((self.n_envs,)) + + ep_info_buf = deque(maxlen=100) + t_first_start = time.time() + + nupdates = total_timesteps // self.n_batch + for update in range(1, nupdates + 1): + assert self.n_batch % self.nminibatches == 0 + batch_size = self.n_batch // self.nminibatches + t_start = time.time() + frac = 1.0 - (update - 1.0) / nupdates + lr_now = self.learning_rate(frac) + cliprangenow = self.cliprange(frac) + # true_reward is the reward without discount + obs, returns, masks, actions, values, neglogpacs, states, ep_infos, true_reward = runner.run() + ep_info_buf.extend(ep_infos) + mb_loss_vals = [] + if states is None: # nonrecurrent version + update_fac = self.n_batch // self.nminibatches // self.noptepochs + 1 + inds = np.arange(self.n_batch) + for epoch_num in range(self.noptepochs): + np.random.shuffle(inds) + for start in range(0, self.n_batch, batch_size): + timestep = self.num_timesteps // update_fac + ((self.noptepochs * self.n_batch + epoch_num * + self.n_batch + start) // batch_size) + end = start + batch_size + mbinds = inds[start:end] + slices = (arr[mbinds] for arr in (obs, returns, masks, actions, values, neglogpacs)) + mb_loss_vals.append(self._train_step(lr_now, cliprangenow, *slices, writer=writer, + update=timestep)) + self.num_timesteps += (self.n_batch * self.noptepochs) // batch_size * update_fac + else: # recurrent version + update_fac = self.n_batch // self.nminibatches // self.noptepochs // self.n_steps + 1 + assert self.n_envs % self.nminibatches == 0 + env_indices = np.arange(self.n_envs) + flat_indices = np.arange(self.n_envs * self.n_steps).reshape(self.n_envs, self.n_steps) + envs_per_batch = batch_size // self.n_steps + for epoch_num in range(self.noptepochs): + np.random.shuffle(env_indices) + for start in range(0, self.n_envs, envs_per_batch): + timestep = self.num_timesteps // update_fac + ((self.noptepochs * self.n_envs + epoch_num * + self.n_envs + start) // envs_per_batch) + end = start + envs_per_batch + mb_env_inds = env_indices[start:end] + mb_flat_inds = flat_indices[mb_env_inds].ravel() + slices = (arr[mb_flat_inds] for arr in (obs, returns, masks, actions, values, neglogpacs)) + mb_states = states[mb_env_inds] + mb_loss_vals.append(self._train_step(lr_now, cliprangenow, *slices, update=timestep, + writer=writer, states=mb_states)) + self.num_timesteps += (self.n_envs * self.noptepochs) // envs_per_batch * update_fac + + loss_vals = np.mean(mb_loss_vals, axis=0) + t_now = time.time() + fps = int(self.n_batch / (t_now - t_start)) + + if writer is not None: + self.episode_reward = total_episode_reward_logger(self.episode_reward, + true_reward.reshape((self.n_envs, self.n_steps)), + masks.reshape((self.n_envs, self.n_steps)), + writer, self.num_timesteps) + + if self.verbose >= 1 and (update % log_interval == 0 or update == 1): + explained_var = explained_variance(values, returns) + logger.logkv("serial_timesteps", update * self.n_steps) + logger.logkv("nupdates", update) + logger.logkv("total_timesteps", self.num_timesteps) + logger.logkv("fps", fps) + logger.logkv("explained_variance", float(explained_var)) + if len(ep_info_buf) > 0 and len(ep_info_buf[0]) > 0: + logger.logkv('ep_reward_mean', safe_mean([ep_info['r'] for ep_info in ep_info_buf])) + logger.logkv('ep_len_mean', safe_mean([ep_info['l'] for ep_info in ep_info_buf])) + logger.logkv('time_elapsed', t_start - t_first_start) + for (loss_val, loss_name) in zip(loss_vals, self.loss_names): + logger.logkv(loss_name, loss_val) + logger.dumpkvs() + + if callback is not None: + # Only stop training if return value is False, not when it is None. This is for backwards + # compatibility with callbacks that have no return statement. + if callback(locals(), globals()) is False: + break + + return self + + def save(self, save_path): + data = { + "gamma": self.gamma, + "n_steps": self.n_steps, + "vf_coef": self.vf_coef, + "ent_coef": self.ent_coef, + "max_grad_norm": self.max_grad_norm, + "learning_rate": self.learning_rate, + "lam": self.lam, + "nminibatches": self.nminibatches, + "noptepochs": self.noptepochs, + "cliprange": self.cliprange, + "verbose": self.verbose, + "policy": self.policy, + "observation_space": self.observation_space, + "action_space": self.action_space, + "n_envs": self.n_envs, + "_vectorize_action": self._vectorize_action, + "policy_kwargs": self.policy_kwargs + } + + params = self.sess.run(self.params) + + self._save_to_file(save_path, data=data, params=params) + + +class Runner(AbstractEnvRunner): + def __init__(self, *, env, model, n_steps, gamma, lam): + """ + A runner to learn the policy of an environment for a model + + :param env: (Gym environment) The environment to learn from + :param model: (Model) The model to learn + :param n_steps: (int) The number of steps to run for each environment + :param gamma: (float) Discount factor + :param lam: (float) Factor for trade-off of bias vs variance for Generalized Advantage Estimator + """ + super().__init__(env=env, model=model, n_steps=n_steps) + self.lam = lam + self.gamma = gamma + + def run(self): + """ + Run a learning step of the model + + :return: + - observations: (np.ndarray) the observations + - rewards: (np.ndarray) the rewards + - masks: (numpy bool) whether an episode is over or not + - actions: (np.ndarray) the actions + - values: (np.ndarray) the value function output + - negative log probabilities: (np.ndarray) + - states: (np.ndarray) the internal states of the recurrent policies + - infos: (dict) the extra information of the model + """ + # mb stands for minibatch + mb_obs, mb_rewards, mb_actions, mb_values, mb_dones, mb_neglogpacs = [], [], [], [], [], [] + mb_states = self.states + ep_infos = [] + for _ in range(self.n_steps): + actions, values, self.states, neglogpacs = self.model.step(self.obs, self.states, self.dones) + mb_obs.append(self.obs.copy()) + mb_actions.append(actions) + mb_values.append(values) + mb_neglogpacs.append(neglogpacs) + mb_dones.append(self.dones) + clipped_actions = actions + # Clip the actions to avoid out of bound error + if isinstance(self.env.action_space, gym.spaces.Box): + clipped_actions = np.clip(actions, self.env.action_space.low, self.env.action_space.high) + self.obs[:], rewards, self.dones, infos = self.env.step(clipped_actions) + for info in infos: + maybe_ep_info = info.get('episode') + if maybe_ep_info is not None: + ep_infos.append(maybe_ep_info) + mb_rewards.append(rewards) + # batch of steps to batch of rollouts + mb_obs = np.asarray(mb_obs, dtype=self.obs.dtype) + mb_rewards = np.asarray(mb_rewards, dtype=np.float32) + mb_actions = np.asarray(mb_actions) + mb_values = np.asarray(mb_values, dtype=np.float32) + mb_neglogpacs = np.asarray(mb_neglogpacs, dtype=np.float32) + mb_dones = np.asarray(mb_dones, dtype=np.bool) + last_values = self.model.value(self.obs, self.states, self.dones) + # discount/bootstrap off value fn + mb_advs = np.zeros_like(mb_rewards) + true_reward = np.copy(mb_rewards) + last_gae_lam = 0 + for step in reversed(range(self.n_steps)): + if step == self.n_steps - 1: + nextnonterminal = 1.0 - self.dones + nextvalues = last_values + else: + nextnonterminal = 1.0 - mb_dones[step + 1] + nextvalues = mb_values[step + 1] + delta = mb_rewards[step] + self.gamma * nextvalues * nextnonterminal - mb_values[step] + mb_advs[step] = last_gae_lam = delta + self.gamma * self.lam * nextnonterminal * last_gae_lam + mb_returns = mb_advs + mb_values + + mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, true_reward = \ + map(swap_and_flatten, (mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, true_reward)) + + return mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, mb_states, ep_infos, true_reward + + +def get_schedule_fn(value_schedule): + """ + Transform (if needed) learning rate and clip range + to callable. + + :param value_schedule: (callable or float) + :return: (function) + """ + # If the passed schedule is a float + # create a constant function + if isinstance(value_schedule, float): + value_schedule = constfn(value_schedule) + else: + assert callable(value_schedule) + return value_schedule + + +# obs, returns, masks, actions, values, neglogpacs, states = runner.run() +def swap_and_flatten(arr): + """ + swap and then flatten axes 0 and 1 + + :param arr: (np.ndarray) + :return: (np.ndarray) + """ + shape = arr.shape + return arr.swapaxes(0, 1).reshape(shape[0] * shape[1], *shape[2:]) + + +def constfn(val): + """ + Create a function that returns a constant + It is useful for learning rate schedule (to avoid code duplication) + + :param val: (float) + :return: (function) + """ + + def func(_): + return val + + return func + + +def safe_mean(arr): + """ + Compute the mean of an array if there is at least one element. + For empty array, return nan. It is used for logging only. + + :param arr: (np.ndarray) + :return: (float) + """ + return np.nan if len(arr) == 0 else np.mean(arr) diff --git a/stable_baselines/POfD/run_atari.py b/stable_baselines/POfD/run_atari.py new file mode 100644 index 0000000000..5260532ccd --- /dev/null +++ b/stable_baselines/POfD/run_atari.py @@ -0,0 +1,47 @@ +from stable_baselines import PPO2, logger +from stable_baselines.common.cmd_util import make_atari_env, atari_arg_parser +from stable_baselines.common.vec_env import VecFrameStack +from stable_baselines.common.policies import CnnPolicy, CnnLstmPolicy, CnnLnLstmPolicy, MlpPolicy + + +def train(env_id, num_timesteps, seed, policy, + n_envs=8, nminibatches=4, n_steps=128): + """ + Train PPO2 model for atari environment, for testing purposes + + :param env_id: (str) the environment id string + :param num_timesteps: (int) the number of timesteps to run + :param seed: (int) Used to seed the random generator. + :param policy: (Object) The policy model to use (MLP, CNN, LSTM, ...) + :param n_envs: (int) Number of parallel environments + :param nminibatches: (int) Number of training minibatches per update. For recurrent policies, + the number of environments run in parallel should be a multiple of nminibatches. + :param n_steps: (int) The number of steps to run for each environment per update + (i.e. batch size is n_steps * n_env where n_env is number of environment copies running in parallel) + """ + + env = VecFrameStack(make_atari_env(env_id, n_envs, seed), 4) + policy = {'cnn': CnnPolicy, 'lstm': CnnLstmPolicy, 'lnlstm': CnnLnLstmPolicy, 'mlp': MlpPolicy}[policy] + model = PPO2(policy=policy, env=env, n_steps=n_steps, nminibatches=nminibatches, + lam=0.95, gamma=0.99, noptepochs=4, ent_coef=.01, + learning_rate=lambda f: f * 2.5e-4, cliprange=lambda f: f * 0.1, verbose=1) + model.learn(total_timesteps=num_timesteps) + + env.close() + # Free memory + del model + +def main(): + """ + Runs the test + """ + parser = atari_arg_parser() + parser.add_argument('--policy', help='Policy architecture', choices=['cnn', 'lstm', 'lnlstm', 'mlp'], default='cnn') + args = parser.parse_args() + logger.configure() + train(args.env, num_timesteps=args.num_timesteps, seed=args.seed, + policy=args.policy) + + +if __name__ == '__main__': + main() diff --git a/stable_baselines/POfD/run_mujoco.py b/stable_baselines/POfD/run_mujoco.py new file mode 100644 index 0000000000..a99efbca92 --- /dev/null +++ b/stable_baselines/POfD/run_mujoco.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +import numpy as np +import gym + +from stable_baselines.common.cmd_util import mujoco_arg_parser +from stable_baselines import bench, logger +from stable_baselines.common import set_global_seeds +from stable_baselines.common.vec_env.vec_normalize import VecNormalize +from stable_baselines.ppo2 import PPO2 +from stable_baselines.common.policies import MlpPolicy +from stable_baselines.common.vec_env.dummy_vec_env import DummyVecEnv + + +def train(env_id, num_timesteps, seed): + """ + Train PPO2 model for Mujoco environment, for testing purposes + + :param env_id: (str) the environment id string + :param num_timesteps: (int) the number of timesteps to run + :param seed: (int) Used to seed the random generator. + """ + def make_env(): + env_out = gym.make(env_id) + env_out = bench.Monitor(env_out, logger.get_dir(), allow_early_resets=True) + return env_out + + env = DummyVecEnv([make_env]) + env = VecNormalize(env) + + set_global_seeds(seed) + policy = MlpPolicy + model = PPO2(policy=policy, env=env, n_steps=2048, nminibatches=32, lam=0.95, gamma=0.99, noptepochs=10, + ent_coef=0.0, learning_rate=3e-4, cliprange=0.2) + model.learn(total_timesteps=num_timesteps) + + return model, env + + +def main(): + """ + Runs the test + """ + args = mujoco_arg_parser().parse_args() + logger.configure() + model, env = train(args.env, num_timesteps=args.num_timesteps, seed=args.seed) + + if args.play: + logger.log("Running trained model") + obs = np.zeros((env.num_envs,) + env.observation_space.shape) + obs[:] = env.reset() + while True: + actions = model.step(obs)[0] + obs[:] = env.step(actions)[0] + env.render() + + +if __name__ == '__main__': + main() diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 410e36e72c..377ef3ffcf 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -49,6 +49,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, for key, val in traj_data.items(): print(key, val.shape) + envs_per_batch = int(envs_per_batch) use_batch_size = batch_size * envs_per_batch # Array of bool where episode_starts[i] = True for each new episode @@ -184,10 +185,10 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.dataloader = None self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, use_batch_size, shuffle=self.randomize, start_process=False, - sequential=sequential_preprocessing) + sequential=sequential_preprocessing, partial_minibatch=not LSTM) self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, use_batch_size, shuffle=self.randomize, start_process=False, - sequential=sequential_preprocessing) + sequential=sequential_preprocessing, partial_minibatch=not LSTM) if self.verbose >= 1: self.log_info() From c7b795a34082fdce3572ceb9a13bcb969f341a36 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 16:50:35 +0200 Subject: [PATCH 11/34] -fix data alignment for LSTMs --- stable_baselines/gail/dataset/dataset.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 377ef3ffcf..b792d5cb4d 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -135,13 +135,16 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, 'get polluted with training data.') # Cycle to it self to creat enough data to split it to batch_size length. - indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] + cycle_indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] # Put the cycled data to the beginning to not affect the validation set. - indices = [indices[i][pre_cycle_len[i]:] + indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] + cycle_indices = [cycle_indices[i][pre_cycle_len[i]:] + cycle_indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] - # Flatten the stack list to a single list. - indices = np.array(indices).flatten('F') + # Flatten the stack cycle list to a single list. + indices = [] + for i in range(0, len(cycle_indices[0]), batch_size): + for k in range(len(cycle_indices)): + indices += cycle_indices[k][i:i+batch_size] # Free memory del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len From ccddbb2afc276d47eae609fc81f97efa44b4c54f Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 17:04:18 +0200 Subject: [PATCH 12/34] Delete __init__.py --- stable_baselines/POfD/__init__.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 stable_baselines/POfD/__init__.py diff --git a/stable_baselines/POfD/__init__.py b/stable_baselines/POfD/__init__.py deleted file mode 100644 index 6eb9f827f7..0000000000 --- a/stable_baselines/POfD/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from stable_baselines.ppo2.ppo2 import PPO2 From ee29e78083034e0b6a2c515bc3d7e4773d1c53ea Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 17:04:29 +0200 Subject: [PATCH 13/34] Delete run_atari.py --- stable_baselines/POfD/run_atari.py | 47 ------------------------------ 1 file changed, 47 deletions(-) delete mode 100644 stable_baselines/POfD/run_atari.py diff --git a/stable_baselines/POfD/run_atari.py b/stable_baselines/POfD/run_atari.py deleted file mode 100644 index 5260532ccd..0000000000 --- a/stable_baselines/POfD/run_atari.py +++ /dev/null @@ -1,47 +0,0 @@ -from stable_baselines import PPO2, logger -from stable_baselines.common.cmd_util import make_atari_env, atari_arg_parser -from stable_baselines.common.vec_env import VecFrameStack -from stable_baselines.common.policies import CnnPolicy, CnnLstmPolicy, CnnLnLstmPolicy, MlpPolicy - - -def train(env_id, num_timesteps, seed, policy, - n_envs=8, nminibatches=4, n_steps=128): - """ - Train PPO2 model for atari environment, for testing purposes - - :param env_id: (str) the environment id string - :param num_timesteps: (int) the number of timesteps to run - :param seed: (int) Used to seed the random generator. - :param policy: (Object) The policy model to use (MLP, CNN, LSTM, ...) - :param n_envs: (int) Number of parallel environments - :param nminibatches: (int) Number of training minibatches per update. For recurrent policies, - the number of environments run in parallel should be a multiple of nminibatches. - :param n_steps: (int) The number of steps to run for each environment per update - (i.e. batch size is n_steps * n_env where n_env is number of environment copies running in parallel) - """ - - env = VecFrameStack(make_atari_env(env_id, n_envs, seed), 4) - policy = {'cnn': CnnPolicy, 'lstm': CnnLstmPolicy, 'lnlstm': CnnLnLstmPolicy, 'mlp': MlpPolicy}[policy] - model = PPO2(policy=policy, env=env, n_steps=n_steps, nminibatches=nminibatches, - lam=0.95, gamma=0.99, noptepochs=4, ent_coef=.01, - learning_rate=lambda f: f * 2.5e-4, cliprange=lambda f: f * 0.1, verbose=1) - model.learn(total_timesteps=num_timesteps) - - env.close() - # Free memory - del model - -def main(): - """ - Runs the test - """ - parser = atari_arg_parser() - parser.add_argument('--policy', help='Policy architecture', choices=['cnn', 'lstm', 'lnlstm', 'mlp'], default='cnn') - args = parser.parse_args() - logger.configure() - train(args.env, num_timesteps=args.num_timesteps, seed=args.seed, - policy=args.policy) - - -if __name__ == '__main__': - main() From 938a4f80734ad132f4495ac94182698751a918bc Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 17:04:43 +0200 Subject: [PATCH 14/34] Delete run_mujoco.py --- stable_baselines/POfD/run_mujoco.py | 58 ----------------------------- 1 file changed, 58 deletions(-) delete mode 100644 stable_baselines/POfD/run_mujoco.py diff --git a/stable_baselines/POfD/run_mujoco.py b/stable_baselines/POfD/run_mujoco.py deleted file mode 100644 index a99efbca92..0000000000 --- a/stable_baselines/POfD/run_mujoco.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 -import numpy as np -import gym - -from stable_baselines.common.cmd_util import mujoco_arg_parser -from stable_baselines import bench, logger -from stable_baselines.common import set_global_seeds -from stable_baselines.common.vec_env.vec_normalize import VecNormalize -from stable_baselines.ppo2 import PPO2 -from stable_baselines.common.policies import MlpPolicy -from stable_baselines.common.vec_env.dummy_vec_env import DummyVecEnv - - -def train(env_id, num_timesteps, seed): - """ - Train PPO2 model for Mujoco environment, for testing purposes - - :param env_id: (str) the environment id string - :param num_timesteps: (int) the number of timesteps to run - :param seed: (int) Used to seed the random generator. - """ - def make_env(): - env_out = gym.make(env_id) - env_out = bench.Monitor(env_out, logger.get_dir(), allow_early_resets=True) - return env_out - - env = DummyVecEnv([make_env]) - env = VecNormalize(env) - - set_global_seeds(seed) - policy = MlpPolicy - model = PPO2(policy=policy, env=env, n_steps=2048, nminibatches=32, lam=0.95, gamma=0.99, noptepochs=10, - ent_coef=0.0, learning_rate=3e-4, cliprange=0.2) - model.learn(total_timesteps=num_timesteps) - - return model, env - - -def main(): - """ - Runs the test - """ - args = mujoco_arg_parser().parse_args() - logger.configure() - model, env = train(args.env, num_timesteps=args.num_timesteps, seed=args.seed) - - if args.play: - logger.log("Running trained model") - obs = np.zeros((env.num_envs,) + env.observation_space.shape) - obs[:] = env.reset() - while True: - actions = model.step(obs)[0] - obs[:] = env.step(actions)[0] - env.render() - - -if __name__ == '__main__': - main() From a952d029c8085e0559b3d39ec77642da2c4a6684 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 17:05:17 +0200 Subject: [PATCH 15/34] Delete ppo2.py --- stable_baselines/POfD/ppo2.py | 519 ---------------------------------- 1 file changed, 519 deletions(-) delete mode 100644 stable_baselines/POfD/ppo2.py diff --git a/stable_baselines/POfD/ppo2.py b/stable_baselines/POfD/ppo2.py deleted file mode 100644 index eb009cee78..0000000000 --- a/stable_baselines/POfD/ppo2.py +++ /dev/null @@ -1,519 +0,0 @@ -import time -import sys -import multiprocessing -from collections import deque - -import gym -import numpy as np -import tensorflow as tf - -from stable_baselines import logger -from stable_baselines.common import explained_variance, ActorCriticRLModel, tf_util, SetVerbosity, TensorboardWriter -from stable_baselines.common.runners import AbstractEnvRunner -from stable_baselines.common.policies import ActorCriticPolicy, RecurrentActorCriticPolicy -from stable_baselines.a2c.utils import total_episode_reward_logger - - -class PPO2(ActorCriticRLModel): - """ - Proximal Policy Optimization algorithm (GPU version). - Paper: https://arxiv.org/abs/1707.06347 - - :param policy: (ActorCriticPolicy or str) The policy model to use (MlpPolicy, CnnPolicy, CnnLstmPolicy, ...) - :param env: (Gym environment or str) The environment to learn from (if registered in Gym, can be str) - :param gamma: (float) Discount factor - :param n_steps: (int) The number of steps to run for each environment per update - (i.e. batch size is n_steps * n_env where n_env is number of environment copies running in parallel) - :param ent_coef: (float) Entropy coefficient for the loss caculation - :param learning_rate: (float or callable) The learning rate, it can be a function - :param vf_coef: (float) Value function coefficient for the loss calculation - :param max_grad_norm: (float) The maximum value for the gradient clipping - :param lam: (float) Factor for trade-off of bias vs variance for Generalized Advantage Estimator - :param nminibatches: (int) Number of training minibatches per update. For recurrent policies, - the number of environments run in parallel should be a multiple of nminibatches. - :param noptepochs: (int) Number of epoch when optimizing the surrogate - :param cliprange: (float or callable) Clipping parameter, it can be a function - :param verbose: (int) the verbosity level: 0 none, 1 training information, 2 tensorflow debug - :param tensorboard_log: (str) the log location for tensorboard (if None, no logging) - :param _init_setup_model: (bool) Whether or not to build the network at the creation of the instance - :param policy_kwargs: (dict) additional arguments to be passed to the policy on creation - :param full_tensorboard_log: (bool) enable additional logging when using tensorboard - WARNING: this logging can take a lot of space quickly - """ - - def __init__(self, policy, env, gamma=0.99, n_steps=128, ent_coef=0.01, learning_rate=2.5e-4, vf_coef=0.5, - max_grad_norm=0.5, lam=0.95, nminibatches=4, noptepochs=4, cliprange=0.2, verbose=0, - tensorboard_log=None, _init_setup_model=True, policy_kwargs=None, - full_tensorboard_log=False): - - super(PPO2, self).__init__(policy=policy, env=env, verbose=verbose, requires_vec_env=True, - _init_setup_model=_init_setup_model, policy_kwargs=policy_kwargs) - - self.learning_rate = learning_rate - self.cliprange = cliprange - self.n_steps = n_steps - self.ent_coef = ent_coef - self.vf_coef = vf_coef - self.max_grad_norm = max_grad_norm - self.gamma = gamma - self.lam = lam - self.nminibatches = nminibatches - self.noptepochs = noptepochs - self.tensorboard_log = tensorboard_log - self.full_tensorboard_log = full_tensorboard_log - - self.graph = None - self.sess = None - self.action_ph = None - self.advs_ph = None - self.rewards_ph = None - self.old_neglog_pac_ph = None - self.old_vpred_ph = None - self.learning_rate_ph = None - self.clip_range_ph = None - self.entropy = None - self.vf_loss = None - self.pg_loss = None - self.approxkl = None - self.clipfrac = None - self.params = None - self._train = None - self.loss_names = None - self.train_model = None - self.act_model = None - self.step = None - self.proba_step = None - self.value = None - self.initial_state = None - self.n_batch = None - self.summary = None - self.episode_reward = None - - if _init_setup_model: - self.setup_model() - - def _get_pretrain_placeholders(self): - policy = self.act_model - if isinstance(self.action_space, gym.spaces.Discrete): - return policy.obs_ph, self.action_ph, policy.policy - return policy.obs_ph, self.action_ph, policy.deterministic_action - - def setup_model(self): - with SetVerbosity(self.verbose): - - assert issubclass(self.policy, ActorCriticPolicy), "Error: the input policy for the PPO2 model must be " \ - "an instance of common.policies.ActorCriticPolicy." - - self.n_batch = self.n_envs * self.n_steps - - n_cpu = multiprocessing.cpu_count() - if sys.platform == 'darwin': - n_cpu //= 2 - - self.graph = tf.Graph() - with self.graph.as_default(): - self.sess = tf_util.make_session(num_cpu=n_cpu, graph=self.graph) - - n_batch_step = None - n_batch_train = None - if issubclass(self.policy, RecurrentActorCriticPolicy): - assert self.n_envs % self.nminibatches == 0, "For recurrent policies, "\ - "the number of environments run in parallel should be a multiple of nminibatches." - n_batch_step = self.n_envs - n_batch_train = self.n_batch // self.nminibatches - - act_model = self.policy(self.sess, self.observation_space, self.action_space, self.n_envs, 1, - n_batch_step, reuse=False, **self.policy_kwargs) - with tf.variable_scope("train_model", reuse=True, - custom_getter=tf_util.outer_scope_getter("train_model")): - train_model = self.policy(self.sess, self.observation_space, self.action_space, - self.n_envs // self.nminibatches, self.n_steps, n_batch_train, - reuse=True, **self.policy_kwargs) - - with tf.variable_scope("loss", reuse=False): - self.action_ph = train_model.pdtype.sample_placeholder([None], name="action_ph") - self.advs_ph = tf.placeholder(tf.float32, [None], name="advs_ph") - self.rewards_ph = tf.placeholder(tf.float32, [None], name="rewards_ph") - self.old_neglog_pac_ph = tf.placeholder(tf.float32, [None], name="old_neglog_pac_ph") - self.old_vpred_ph = tf.placeholder(tf.float32, [None], name="old_vpred_ph") - self.learning_rate_ph = tf.placeholder(tf.float32, [], name="learning_rate_ph") - self.clip_range_ph = tf.placeholder(tf.float32, [], name="clip_range_ph") - - neglogpac = train_model.proba_distribution.neglogp(self.action_ph) - self.entropy = tf.reduce_mean(train_model.proba_distribution.entropy()) - - vpred = train_model.value_flat - vpredclipped = self.old_vpred_ph + tf.clip_by_value( - train_model.value_flat - self.old_vpred_ph, - self.clip_range_ph, self.clip_range_ph) - vf_losses1 = tf.square(vpred - self.rewards_ph) - vf_losses2 = tf.square(vpredclipped - self.rewards_ph) - self.vf_loss = .5 * tf.reduce_mean(tf.maximum(vf_losses1, vf_losses2)) - ratio = tf.exp(self.old_neglog_pac_ph - neglogpac) - pg_losses = -self.advs_ph * ratio - pg_losses2 = -self.advs_ph * tf.clip_by_value(ratio, 1.0 - self.clip_range_ph, 1.0 + - self.clip_range_ph) - self.pg_loss = tf.reduce_mean(tf.maximum(pg_losses, pg_losses2)) - self.approxkl = .5 * tf.reduce_mean(tf.square(neglogpac - self.old_neglog_pac_ph)) - self.clipfrac = tf.reduce_mean(tf.cast(tf.greater(tf.abs(ratio - 1.0), - self.clip_range_ph), tf.float32)) - loss = self.pg_loss - self.entropy * self.ent_coef + self.vf_loss * self.vf_coef - - tf.summary.scalar('entropy_loss', self.entropy) - tf.summary.scalar('policy_gradient_loss', self.pg_loss) - tf.summary.scalar('value_function_loss', self.vf_loss) - tf.summary.scalar('approximate_kullback-leibler', self.approxkl) - tf.summary.scalar('clip_factor', self.clipfrac) - tf.summary.scalar('loss', loss) - - with tf.variable_scope('model'): - self.params = tf.trainable_variables() - if self.full_tensorboard_log: - for var in self.params: - tf.summary.histogram(var.name, var) - grads = tf.gradients(loss, self.params) - if self.max_grad_norm is not None: - grads, _grad_norm = tf.clip_by_global_norm(grads, self.max_grad_norm) - grads = list(zip(grads, self.params)) - trainer = tf.train.AdamOptimizer(learning_rate=self.learning_rate_ph, epsilon=1e-5) - self._train = trainer.apply_gradients(grads) - - self.loss_names = ['policy_loss', 'value_loss', 'policy_entropy', 'approxkl', 'clipfrac'] - - with tf.variable_scope("input_info", reuse=False): - tf.summary.scalar('discounted_rewards', tf.reduce_mean(self.rewards_ph)) - tf.summary.scalar('learning_rate', tf.reduce_mean(self.learning_rate_ph)) - tf.summary.scalar('advantage', tf.reduce_mean(self.advs_ph)) - tf.summary.scalar('clip_range', tf.reduce_mean(self.clip_range_ph)) - tf.summary.scalar('old_neglog_action_probabilty', tf.reduce_mean(self.old_neglog_pac_ph)) - tf.summary.scalar('old_value_pred', tf.reduce_mean(self.old_vpred_ph)) - - if self.full_tensorboard_log: - tf.summary.histogram('discounted_rewards', self.rewards_ph) - tf.summary.histogram('learning_rate', self.learning_rate_ph) - tf.summary.histogram('advantage', self.advs_ph) - tf.summary.histogram('clip_range', self.clip_range_ph) - tf.summary.histogram('old_neglog_action_probabilty', self.old_neglog_pac_ph) - tf.summary.histogram('old_value_pred', self.old_vpred_ph) - if tf_util.is_image(self.observation_space): - tf.summary.image('observation', train_model.obs_ph) - else: - tf.summary.histogram('observation', train_model.obs_ph) - - self.train_model = train_model - self.act_model = act_model - self.step = act_model.step - self.proba_step = act_model.proba_step - self.value = act_model.value - self.initial_state = act_model.initial_state - tf.global_variables_initializer().run(session=self.sess) # pylint: disable=E1101 - - self.summary = tf.summary.merge_all() - - def _train_step(self, learning_rate, cliprange, obs, returns, masks, actions, values, neglogpacs, update, - writer, states=None): - """ - Training of PPO2 Algorithm - - :param learning_rate: (float) learning rate - :param cliprange: (float) Clipping factor - :param obs: (np.ndarray) The current observation of the environment - :param returns: (np.ndarray) the rewards - :param masks: (np.ndarray) The last masks for done episodes (used in recurent policies) - :param actions: (np.ndarray) the actions - :param values: (np.ndarray) the values - :param neglogpacs: (np.ndarray) Negative Log-likelihood probability of Actions - :param update: (int) the current step iteration - :param writer: (TensorFlow Summary.writer) the writer for tensorboard - :param states: (np.ndarray) For recurrent policies, the internal state of the recurrent model - :return: policy gradient loss, value function loss, policy entropy, - approximation of kl divergence, updated clipping range, training update operation - """ - advs = returns - values - advs = (advs - advs.mean()) / (advs.std() + 1e-8) - td_map = {self.train_model.obs_ph: obs, self.action_ph: actions, self.advs_ph: advs, self.rewards_ph: returns, - self.learning_rate_ph: learning_rate, self.clip_range_ph: cliprange, - self.old_neglog_pac_ph: neglogpacs, self.old_vpred_ph: values} - if states is not None: - td_map[self.train_model.states_ph] = states - td_map[self.train_model.dones_ph] = masks - - if states is None: - update_fac = self.n_batch // self.nminibatches // self.noptepochs + 1 - else: - update_fac = self.n_batch // self.nminibatches // self.noptepochs // self.n_steps + 1 - - if writer is not None: - # run loss backprop with summary, but once every 10 runs save the metadata (memory, compute time, ...) - if self.full_tensorboard_log and (1 + update) % 10 == 0: - run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) - run_metadata = tf.RunMetadata() - summary, policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( - [self.summary, self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], - td_map, options=run_options, run_metadata=run_metadata) - writer.add_run_metadata(run_metadata, 'step%d' % (update * update_fac)) - else: - summary, policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( - [self.summary, self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], - td_map) - writer.add_summary(summary, (update * update_fac)) - else: - policy_loss, value_loss, policy_entropy, approxkl, clipfrac, _ = self.sess.run( - [self.pg_loss, self.vf_loss, self.entropy, self.approxkl, self.clipfrac, self._train], td_map) - - return policy_loss, value_loss, policy_entropy, approxkl, clipfrac - - def learn(self, total_timesteps, callback=None, seed=None, log_interval=1, tb_log_name="PPO2", - reset_num_timesteps=True): - # Transform to callable if needed - self.learning_rate = get_schedule_fn(self.learning_rate) - self.cliprange = get_schedule_fn(self.cliprange) - - new_tb_log = self._init_num_timesteps(reset_num_timesteps) - - with SetVerbosity(self.verbose), TensorboardWriter(self.graph, self.tensorboard_log, tb_log_name, new_tb_log) \ - as writer: - self._setup_learn(seed) - - runner = Runner(env=self.env, model=self, n_steps=self.n_steps, gamma=self.gamma, lam=self.lam) - self.episode_reward = np.zeros((self.n_envs,)) - - ep_info_buf = deque(maxlen=100) - t_first_start = time.time() - - nupdates = total_timesteps // self.n_batch - for update in range(1, nupdates + 1): - assert self.n_batch % self.nminibatches == 0 - batch_size = self.n_batch // self.nminibatches - t_start = time.time() - frac = 1.0 - (update - 1.0) / nupdates - lr_now = self.learning_rate(frac) - cliprangenow = self.cliprange(frac) - # true_reward is the reward without discount - obs, returns, masks, actions, values, neglogpacs, states, ep_infos, true_reward = runner.run() - ep_info_buf.extend(ep_infos) - mb_loss_vals = [] - if states is None: # nonrecurrent version - update_fac = self.n_batch // self.nminibatches // self.noptepochs + 1 - inds = np.arange(self.n_batch) - for epoch_num in range(self.noptepochs): - np.random.shuffle(inds) - for start in range(0, self.n_batch, batch_size): - timestep = self.num_timesteps // update_fac + ((self.noptepochs * self.n_batch + epoch_num * - self.n_batch + start) // batch_size) - end = start + batch_size - mbinds = inds[start:end] - slices = (arr[mbinds] for arr in (obs, returns, masks, actions, values, neglogpacs)) - mb_loss_vals.append(self._train_step(lr_now, cliprangenow, *slices, writer=writer, - update=timestep)) - self.num_timesteps += (self.n_batch * self.noptepochs) // batch_size * update_fac - else: # recurrent version - update_fac = self.n_batch // self.nminibatches // self.noptepochs // self.n_steps + 1 - assert self.n_envs % self.nminibatches == 0 - env_indices = np.arange(self.n_envs) - flat_indices = np.arange(self.n_envs * self.n_steps).reshape(self.n_envs, self.n_steps) - envs_per_batch = batch_size // self.n_steps - for epoch_num in range(self.noptepochs): - np.random.shuffle(env_indices) - for start in range(0, self.n_envs, envs_per_batch): - timestep = self.num_timesteps // update_fac + ((self.noptepochs * self.n_envs + epoch_num * - self.n_envs + start) // envs_per_batch) - end = start + envs_per_batch - mb_env_inds = env_indices[start:end] - mb_flat_inds = flat_indices[mb_env_inds].ravel() - slices = (arr[mb_flat_inds] for arr in (obs, returns, masks, actions, values, neglogpacs)) - mb_states = states[mb_env_inds] - mb_loss_vals.append(self._train_step(lr_now, cliprangenow, *slices, update=timestep, - writer=writer, states=mb_states)) - self.num_timesteps += (self.n_envs * self.noptepochs) // envs_per_batch * update_fac - - loss_vals = np.mean(mb_loss_vals, axis=0) - t_now = time.time() - fps = int(self.n_batch / (t_now - t_start)) - - if writer is not None: - self.episode_reward = total_episode_reward_logger(self.episode_reward, - true_reward.reshape((self.n_envs, self.n_steps)), - masks.reshape((self.n_envs, self.n_steps)), - writer, self.num_timesteps) - - if self.verbose >= 1 and (update % log_interval == 0 or update == 1): - explained_var = explained_variance(values, returns) - logger.logkv("serial_timesteps", update * self.n_steps) - logger.logkv("nupdates", update) - logger.logkv("total_timesteps", self.num_timesteps) - logger.logkv("fps", fps) - logger.logkv("explained_variance", float(explained_var)) - if len(ep_info_buf) > 0 and len(ep_info_buf[0]) > 0: - logger.logkv('ep_reward_mean', safe_mean([ep_info['r'] for ep_info in ep_info_buf])) - logger.logkv('ep_len_mean', safe_mean([ep_info['l'] for ep_info in ep_info_buf])) - logger.logkv('time_elapsed', t_start - t_first_start) - for (loss_val, loss_name) in zip(loss_vals, self.loss_names): - logger.logkv(loss_name, loss_val) - logger.dumpkvs() - - if callback is not None: - # Only stop training if return value is False, not when it is None. This is for backwards - # compatibility with callbacks that have no return statement. - if callback(locals(), globals()) is False: - break - - return self - - def save(self, save_path): - data = { - "gamma": self.gamma, - "n_steps": self.n_steps, - "vf_coef": self.vf_coef, - "ent_coef": self.ent_coef, - "max_grad_norm": self.max_grad_norm, - "learning_rate": self.learning_rate, - "lam": self.lam, - "nminibatches": self.nminibatches, - "noptepochs": self.noptepochs, - "cliprange": self.cliprange, - "verbose": self.verbose, - "policy": self.policy, - "observation_space": self.observation_space, - "action_space": self.action_space, - "n_envs": self.n_envs, - "_vectorize_action": self._vectorize_action, - "policy_kwargs": self.policy_kwargs - } - - params = self.sess.run(self.params) - - self._save_to_file(save_path, data=data, params=params) - - -class Runner(AbstractEnvRunner): - def __init__(self, *, env, model, n_steps, gamma, lam): - """ - A runner to learn the policy of an environment for a model - - :param env: (Gym environment) The environment to learn from - :param model: (Model) The model to learn - :param n_steps: (int) The number of steps to run for each environment - :param gamma: (float) Discount factor - :param lam: (float) Factor for trade-off of bias vs variance for Generalized Advantage Estimator - """ - super().__init__(env=env, model=model, n_steps=n_steps) - self.lam = lam - self.gamma = gamma - - def run(self): - """ - Run a learning step of the model - - :return: - - observations: (np.ndarray) the observations - - rewards: (np.ndarray) the rewards - - masks: (numpy bool) whether an episode is over or not - - actions: (np.ndarray) the actions - - values: (np.ndarray) the value function output - - negative log probabilities: (np.ndarray) - - states: (np.ndarray) the internal states of the recurrent policies - - infos: (dict) the extra information of the model - """ - # mb stands for minibatch - mb_obs, mb_rewards, mb_actions, mb_values, mb_dones, mb_neglogpacs = [], [], [], [], [], [] - mb_states = self.states - ep_infos = [] - for _ in range(self.n_steps): - actions, values, self.states, neglogpacs = self.model.step(self.obs, self.states, self.dones) - mb_obs.append(self.obs.copy()) - mb_actions.append(actions) - mb_values.append(values) - mb_neglogpacs.append(neglogpacs) - mb_dones.append(self.dones) - clipped_actions = actions - # Clip the actions to avoid out of bound error - if isinstance(self.env.action_space, gym.spaces.Box): - clipped_actions = np.clip(actions, self.env.action_space.low, self.env.action_space.high) - self.obs[:], rewards, self.dones, infos = self.env.step(clipped_actions) - for info in infos: - maybe_ep_info = info.get('episode') - if maybe_ep_info is not None: - ep_infos.append(maybe_ep_info) - mb_rewards.append(rewards) - # batch of steps to batch of rollouts - mb_obs = np.asarray(mb_obs, dtype=self.obs.dtype) - mb_rewards = np.asarray(mb_rewards, dtype=np.float32) - mb_actions = np.asarray(mb_actions) - mb_values = np.asarray(mb_values, dtype=np.float32) - mb_neglogpacs = np.asarray(mb_neglogpacs, dtype=np.float32) - mb_dones = np.asarray(mb_dones, dtype=np.bool) - last_values = self.model.value(self.obs, self.states, self.dones) - # discount/bootstrap off value fn - mb_advs = np.zeros_like(mb_rewards) - true_reward = np.copy(mb_rewards) - last_gae_lam = 0 - for step in reversed(range(self.n_steps)): - if step == self.n_steps - 1: - nextnonterminal = 1.0 - self.dones - nextvalues = last_values - else: - nextnonterminal = 1.0 - mb_dones[step + 1] - nextvalues = mb_values[step + 1] - delta = mb_rewards[step] + self.gamma * nextvalues * nextnonterminal - mb_values[step] - mb_advs[step] = last_gae_lam = delta + self.gamma * self.lam * nextnonterminal * last_gae_lam - mb_returns = mb_advs + mb_values - - mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, true_reward = \ - map(swap_and_flatten, (mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, true_reward)) - - return mb_obs, mb_returns, mb_dones, mb_actions, mb_values, mb_neglogpacs, mb_states, ep_infos, true_reward - - -def get_schedule_fn(value_schedule): - """ - Transform (if needed) learning rate and clip range - to callable. - - :param value_schedule: (callable or float) - :return: (function) - """ - # If the passed schedule is a float - # create a constant function - if isinstance(value_schedule, float): - value_schedule = constfn(value_schedule) - else: - assert callable(value_schedule) - return value_schedule - - -# obs, returns, masks, actions, values, neglogpacs, states = runner.run() -def swap_and_flatten(arr): - """ - swap and then flatten axes 0 and 1 - - :param arr: (np.ndarray) - :return: (np.ndarray) - """ - shape = arr.shape - return arr.swapaxes(0, 1).reshape(shape[0] * shape[1], *shape[2:]) - - -def constfn(val): - """ - Create a function that returns a constant - It is useful for learning rate schedule (to avoid code duplication) - - :param val: (float) - :return: (function) - """ - - def func(_): - return val - - return func - - -def safe_mean(arr): - """ - Compute the mean of an array if there is at least one element. - For empty array, return nan. It is used for logging only. - - :param arr: (np.ndarray) - :return: (float) - """ - return np.nan if len(arr) == 0 else np.mean(arr) From a2a94adf68de5d158a21577b08c5b2628a18d7ad Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 17:29:44 +0200 Subject: [PATCH 16/34] -fix syntax line length. --- stable_baselines/gail/dataset/dataset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index b792d5cb4d..481f781203 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -138,7 +138,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, cycle_indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] # Put the cycled data to the beginning to not affect the validation set. - cycle_indices = [cycle_indices[i][pre_cycle_len[i]:] + cycle_indices[i][:pre_cycle_len[i]] for i in range(len(pre_cycle_len))] + cycle_indices = [cycle_indices[i][pre_cycle_len[i]:] + cycle_indices[i][:pre_cycle_len[i]]\ + for i in range(len(pre_cycle_len))] # Flatten the stack cycle list to a single list. indices = [] From 77538dae32c7e9d2f1cefe9d366c310c03222489 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 18:30:17 +0200 Subject: [PATCH 17/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 481f781203..a1d6986303 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -144,11 +144,11 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, # Flatten the stack cycle list to a single list. indices = [] for i in range(0, len(cycle_indices[0]), batch_size): - for k in range(len(cycle_indices)): - indices += cycle_indices[k][i:i+batch_size] + for c_i in cycle_indices: + indices += c_i[i:i+batch_size] # Free memory - del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len + del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len, cycle_indices # Train/Validation split when using behavior cloning train_indices = indices[:split_point] From a124dcb40b1be67781e8e73da89aa493633eaf6c Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Wed, 15 May 2019 18:50:19 +0200 Subject: [PATCH 18/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index a1d6986303..ec7c784b42 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -148,7 +148,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, indices += c_i[i:i+batch_size] # Free memory - del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len, cycle_indices + del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len,\ + cycle_indices # Train/Validation split when using behavior cloning train_indices = indices[:split_point] From c4d9c47e1ad9842e1a7b9aa5b8cc119a32d60ede Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Mon, 20 May 2019 08:58:05 +0200 Subject: [PATCH 19/34] remove nano.save --- nano.save | 1 - 1 file changed, 1 deletion(-) delete mode 100644 nano.save diff --git a/nano.save b/nano.save deleted file mode 100644 index 8b13789179..0000000000 --- a/nano.save +++ /dev/null @@ -1 +0,0 @@ - From b30413e5876ab5c0f17748e7db7a7eed438d262a Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 20 Jul 2019 22:25:21 +0200 Subject: [PATCH 20/34] split LSTM dataset from Expert dataset. --- stable_baselines/gail/__init__.py | 2 +- stable_baselines/gail/dataset/dataset.py | 363 ++++++++++++++--------- tests/test_gail.py | 14 +- 3 files changed, 242 insertions(+), 137 deletions(-) diff --git a/stable_baselines/gail/__init__.py b/stable_baselines/gail/__init__.py index 0a4c7ac4ea..0cd9db8609 100644 --- a/stable_baselines/gail/__init__.py +++ b/stable_baselines/gail/__init__.py @@ -1,3 +1,3 @@ from stable_baselines.gail.model import GAIL -from stable_baselines.gail.dataset.dataset import ExpertDataset, DataLoader +from stable_baselines.gail.dataset.dataset import ExpertDataset, ExpertDatasetLSTM, DataLoader from stable_baselines.gail.dataset.record_expert import generate_expert_traj diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index ec7c784b42..7996cf3c3b 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -10,8 +10,174 @@ from stable_baselines import logger +class Dataset(object): -class ExpertDataset(object): + def __del__(self): + del self.dataloader, self.train_loader, self.val_loader + + def prepare_pickling(self): + """ + Exit processes in order to pickle the dataset. + """ + self.dataloader, self.train_loader, self.val_loader = None, None, None + + def log_info(self): + """ + Log the information of the dataset. + """ + logger.log("Total trajectories: {}".format(self.num_traj)) + logger.log("Total transitions: {}".format(self.num_transition)) + logger.log("Average returns: {}".format(self.avg_ret)) + logger.log("Std for returns: {}".format(self.std_ret)) + + def get_next_batch(self, split=None): + """ + Get the batch from the dataset. + :param split: (str) the type of data split (can be None, 'train', 'val') + :return: (np.ndarray, np.ndarray) inputs and labels + """ + dataloader = { + None: self.dataloader, + 'train': self.train_loader, + 'val': self.val_loader + }[split] + + if dataloader.process is None: + dataloader.start_process() + try: + return next(dataloader) + except StopIteration: + dataloader = iter(dataloader) + return next(dataloader) + + def plot(self): + """ + Show histogram plotting of the episode returns + """ + # Isolate dependency since it is only used for plotting and also since + # different matplotlib backends have further dependencies themselves. + import matplotlib.pyplot as plt + plt.hist(self.returns) + plt.show() + +class ExpertDataset(Dataset): + """ + Dataset for using behavior cloning or GAIL. + The structure of the expert dataset is a dict, saved as an ".npz" archive. + The dictionary contains the keys 'actions', 'episode_returns', 'rewards', 'obs' and 'episode_starts'. + The corresponding values have data concatenated across episode: the first axis is the timestep, + the remaining axes index into the data. In case of images, 'obs' contains the relative path to + the images, to enable space saving from image compression. + :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. + :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. + :param train_fraction: (float) the train validation split (0 to 1) + for pre-training using behavior cloning (BC) + :param batch_size: (int) the minibatch size for behavior cloning + :param traj_limitation: (int) the number of trajectory to use (if -1, load all) + :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False if LSTM is True. + :param verbose: (int) Verbosity + :param sequential_preprocessing: (bool) Do not use subprocess to preprocess + the data (slower but use less memory for the CI) + """ + + def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, + batch_size=64, traj_limitation=-1, randomize=True, verbose=1, + sequential_preprocessing=False): + + if traj_data is not None and expert_path is not None: + raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") + if traj_data is None and expert_path is None: + raise ValueError("Must specify one of 'traj_data' or 'expert_path'") + if traj_data is None: + traj_data = np.load(expert_path) + + if verbose > 0: + for key, val in traj_data.items(): + print(key, val.shape) + + # Array of bool where episode_starts[i] = True for each new episode + episode_starts = traj_data['episode_starts'] + + traj_limit_idx = len(traj_data['obs']) + + if traj_limitation > 0: + n_episodes = 0 + # Retrieve the index corresponding + # to the traj_limitation trajectory + for idx, episode_start in enumerate(episode_starts): + n_episodes += int(episode_start) + if n_episodes == (traj_limitation + 1): + traj_limit_idx = idx - 1 + + observations = traj_data['obs'][:traj_limit_idx] + actions = traj_data['actions'][:traj_limit_idx] + mask = episode_starts[:traj_limit_idx] + + start_index_list = [] + + # obs, actions: shape (N * L, ) + S + # where N = # episodes, L = episode length + # and S is the environment observation/action space. + # S = (1, ) for discrete space + # Flatten to (N * L, prod(S)) + if len(observations.shape) > 2: + observations = np.reshape(observations, [-1, np.prod(observations.shape[1:])]) + if len(actions.shape) > 2: + actions = np.reshape(actions, [-1, np.prod(actions.shape[1:])]) + if len(mask.shape) > 2: + mask = np.reshape(mask, [-1, np.prod(mask.shape[1:])]) + + indices = np.random.permutation(len(observations)).astype(np.int64) + + # Train/Validation split when using behavior cloning + train_indices = indices[:int(train_fraction * len(indices))] + val_indices = indices[int(train_fraction * len(indices)):] + + # Set randomize. + self.randomize = randomize + + assert len(train_indices) > 0, "No sample for the training set" + assert len(val_indices) > 0, "No sample for the validation set" + + self.observations = observations + self.actions = actions + self.mask = mask + + self.returns = traj_data['episode_returns'][:traj_limit_idx] + self.avg_ret = sum(self.returns) / len(self.returns) + self.std_ret = np.std(np.array(self.returns)) + self.verbose = verbose + + assert len(self.observations) == len(self.actions), "The number of actions and observations differ " \ + "please check your expert dataset" + self.num_traj = min(traj_limitation, np.sum(episode_starts)) + self.num_transition = len(self.observations) + self.sequential_preprocessing = sequential_preprocessing + + self.dataloader = None + self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, batch_size, + shuffle=self.randomize, start_process=False, + sequential=sequential_preprocessing) + self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, batch_size, + shuffle=self.randomize, start_process=False, + sequential=sequential_preprocessing) + + if self.verbose >= 1: + self.log_info() + + def init_dataloader(self, batch_size): + """ + Initialize the dataloader used by GAIL. + :param batch_size: (int) + """ + indices = np.random.permutation(len(self.observations)).astype(np.int64) + self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, batch_size, + shuffle=self.randomize, start_process=False, + sequential=self.sequential_preprocessing) + + + +class ExpertDatasetLSTM(Dataset): """ Dataset for using behavior cloning or GAIL. @@ -27,17 +193,16 @@ class ExpertDataset(object): for pre-training using behavior cloning (BC) :param batch_size: (int) the minibatch size for behavior cloning :param traj_limitation: (int) the number of trajectory to use (if -1, load all) - :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False if LSTM is True. :param verbose: (int) Verbosity :param sequential_preprocessing: (bool) Do not use subprocess to preprocess the data (slower but use less memory for the CI) - :param LSTM: (bool) If model to pretrain uses a recurrent policy. :param envs_per_batch: (int) Only used if LSTM is True. Number of envs that are processed per batch. """ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, - batch_size=64, traj_limitation=-1, randomize=True, verbose=1, - sequential_preprocessing=False, LSTM=False, envs_per_batch=1): + batch_size=64, traj_limitation=-1, verbose=1, envs_per_batch=1, + sequential_preprocessing=False): + if traj_data is not None and expert_path is not None: raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") if traj_data is None and expert_path is None: @@ -71,12 +236,11 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, mask = episode_starts[:traj_limit_idx] start_index_list = [] - if LSTM: - for idx, episode_start in enumerate(mask): - if episode_start: - start_index_list.append(idx) + for idx, episode_start in enumerate(mask): + if episode_start: + start_index_list.append(idx) - start_index_list += [traj_limit_idx] + start_index_list += [traj_limit_idx] # obs, actions: shape (N * L, ) + S # where N = # episodes, L = episode length @@ -90,84 +254,69 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if len(mask.shape) > 2: mask = np.reshape(mask, [-1, np.prod(mask.shape[1:])]) - if LSTM: - - # Creat indices list and split them per episode. - indices = np.arange(start=0, stop=len(observations)).astype(np.int64) - split_indices = [indices[start_index_list[i]:start_index_list[i+1]]\ + # Creat indices list and split them per episode. + indices = np.arange(start=0, stop=len(observations)).astype(np.int64) + split_indices = [indices[start_index_list[i]:start_index_list[i+1]]\ .tolist() for i in range(0, len(start_index_list)-1)] - # Create list with episode lengths. - len_list = [len(s_i) for s_i in split_indices] + # Create list with episode lengths. + len_list = [len(s_i) for s_i in split_indices] - assert len(len_list) >= envs_per_batch, "Not enough saved " \ + assert len(len_list) >= envs_per_batch, "Not enough saved " \ "episodes for this number " \ "of workers and nminibatches." - # Sort episode pos by lengths. - sort_buffer = np.argsort(len_list).tolist()[::-1] - - # Creat stack list and pre fill then with the longest episodes. - stack_indices = [] - for i in range(envs_per_batch): - stack_indices.append(split_indices[sort_buffer[0]]) - sort_buffer.pop(0) - - # Add next episode to the smallest stack. - for s_b in sort_buffer: - currend_stackt_indices_len = [len(st_i) for st_i in stack_indices] - smalest_stackt_indices_pos = np.argmin(currend_stackt_indices_len) - stack_indices[smalest_stackt_indices_pos] += split_indices[s_b] - - # Creat info varibelts used for data cycle. - pre_cycle_len = [len(st_i) for st_i in stack_indices] - max_len = max(pre_cycle_len) - min_len = min(pre_cycle_len) - mod_max_len = max_len % batch_size - final_stack_len = max_len + (batch_size - mod_max_len) - - # Calculate split point for Train/Validation split. - split_point = int(train_fraction * final_stack_len * envs_per_batch) - split_point = split_point - (split_point % use_batch_size) - - if mod_max_len > (min_len - (final_stack_len * envs_per_batch - split_point)) > 0: - warnings.warn('The Episode are divide to unequal, your validation set will ' - 'get polluted with training data.') - - # Cycle to it self to creat enough data to split it to batch_size length. - cycle_indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] - - # Put the cycled data to the beginning to not affect the validation set. - cycle_indices = [cycle_indices[i][pre_cycle_len[i]:] + cycle_indices[i][:pre_cycle_len[i]]\ + # Sort episode pos by lengths. + sort_buffer = np.argsort(len_list).tolist()[::-1] + + # Creat stack list and pre fill then with the longest episodes. + stack_indices = [] + for i in range(envs_per_batch): + stack_indices.append(split_indices[sort_buffer[0]]) + sort_buffer.pop(0) + + # Add next episode to the smallest stack. + for s_b in sort_buffer: + currend_stackt_indices_len = [len(st_i) for st_i in stack_indices] + smalest_stackt_indices_pos = np.argmin(currend_stackt_indices_len) + stack_indices[smalest_stackt_indices_pos] += split_indices[s_b] + + # Creat info varibelts used for data cycle. + pre_cycle_len = [len(st_i) for st_i in stack_indices] + max_len = max(pre_cycle_len) + min_len = min(pre_cycle_len) + mod_max_len = max_len % batch_size + final_stack_len = max_len + (batch_size - mod_max_len) + + # Calculate split point for Train/Validation split. + split_point = int(train_fraction * final_stack_len * envs_per_batch) + split_point = split_point - (split_point % use_batch_size) + + if mod_max_len > (min_len - (final_stack_len * envs_per_batch - split_point)) > 0: + warnings.warn('The Episode are divide to unequal, your validation set will ' + 'get polluted with training data.') + + # Cycle to it self to creat enough data to split it to batch_size length. + cycle_indices = [list(islice(cycle(st_i), None, final_stack_len)) for st_i in stack_indices] + + # Put the cycled data to the beginning to not affect the validation set. + cycle_indices = [cycle_indices[i][pre_cycle_len[i]:] + cycle_indices[i][:pre_cycle_len[i]]\ for i in range(len(pre_cycle_len))] - # Flatten the stack cycle list to a single list. - indices = [] - for i in range(0, len(cycle_indices[0]), batch_size): - for c_i in cycle_indices: - indices += c_i[i:i+batch_size] - - # Free memory - del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len,\ - cycle_indices - - # Train/Validation split when using behavior cloning - train_indices = indices[:split_point] - val_indices = indices[split_point:] - - # Set randomize. - self.randomize = False - - else: + # Flatten the stack cycle list to a single list. + indices = [] + for i in range(0, len(cycle_indices[0]), batch_size): + for c_i in cycle_indices: + indices += c_i[i:i+batch_size] - indices = np.random.permutation(len(observations)).astype(np.int64) + # Free memory + del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len,\ + cycle_indices - # Train/Validation split when using behavior cloning - train_indices = indices[:int(train_fraction * len(indices))] - val_indices = indices[int(train_fraction * len(indices)):] + # Train/Validation split when using behavior cloning + train_indices = indices[:split_point] + val_indices = indices[split_point:] - # Set randomize. - self.randomize = randomize assert len(train_indices) > 0, "No sample for the training set" assert len(val_indices) > 0, "No sample for the validation set" @@ -189,11 +338,11 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.dataloader = None self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, use_batch_size, - shuffle=self.randomize, start_process=False, - sequential=sequential_preprocessing, partial_minibatch=not LSTM) + start_process=False, sequential=sequential_preprocessing, + partial_minibatch=False) self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, use_batch_size, - shuffle=self.randomize, start_process=False, - sequential=sequential_preprocessing, partial_minibatch=not LSTM) + start_process=False, sequential=sequential_preprocessing, + partial_minibatch=False) if self.verbose >= 1: self.log_info() @@ -206,57 +355,7 @@ def init_dataloader(self, batch_size): """ indices = np.random.permutation(len(self.observations)).astype(np.int64) self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, batch_size, - shuffle=self.randomize, start_process=False, - sequential=self.sequential_preprocessing) - - def __del__(self): - del self.dataloader, self.train_loader, self.val_loader - - def prepare_pickling(self): - """ - Exit processes in order to pickle the dataset. - """ - self.dataloader, self.train_loader, self.val_loader = None, None, None - - def log_info(self): - """ - Log the information of the dataset. - """ - logger.log("Total trajectories: {}".format(self.num_traj)) - logger.log("Total transitions: {}".format(self.num_transition)) - logger.log("Average returns: {}".format(self.avg_ret)) - logger.log("Std for returns: {}".format(self.std_ret)) - - def get_next_batch(self, split=None): - """ - Get the batch from the dataset. - - :param split: (str) the type of data split (can be None, 'train', 'val') - :return: (np.ndarray, np.ndarray) inputs and labels - """ - dataloader = { - None: self.dataloader, - 'train': self.train_loader, - 'val': self.val_loader - }[split] - - if dataloader.process is None: - dataloader.start_process() - try: - return next(dataloader) - except StopIteration: - dataloader = iter(dataloader) - return next(dataloader) - - def plot(self): - """ - Show histogram plotting of the episode returns - """ - # Isolate dependency since it is only used for plotting and also since - # different matplotlib backends have further dependencies themselves. - import matplotlib.pyplot as plt - plt.hist(self.returns) - plt.show() + start_process=False, sequential=self.sequential_preprocessing) class DataLoader(object): diff --git a/tests/test_gail.py b/tests/test_gail.py index 23ff32a182..f6d8d067f7 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -7,7 +7,7 @@ from stable_baselines import A2C, ACER, ACKTR, GAIL, DQN, PPO1, PPO2, TRPO, SAC from stable_baselines.common.cmd_util import make_atari_env from stable_baselines.common.vec_env import VecFrameStack, DummyVecEnv -from stable_baselines.gail import ExpertDataset, generate_expert_traj +from stable_baselines.gail import ExpertDataset, ExpertDatasetLSTM, generate_expert_traj EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" EXPERT_PATH_DISCRETE = "stable_baselines/gail/dataset/expert_cartpole.npz" @@ -147,9 +147,15 @@ def test_pretrain_images(): def test_behavior_cloning(model_class_data): model_class, num_env, lstm, policy, game, load_data, batch_size, envs_per_batch = model_class_data - dataset = ExpertDataset(expert_path=load_data, traj_limitation=3, - sequential_preprocessing=True, verbose=0, LSTM=lstm, - batch_size=batch_size, envs_per_batch=envs_per_batch) + + if lstm: + dataset = ExpertDatasetLSTM(expert_path=load_data, traj_limitation=3, + sequential_preprocessing=True, verbose=0, + batch_size=batch_size, envs_per_batch=envs_per_batch) + else: + dataset = ExpertDataset(expert_path=load_data, traj_limitation=3, + sequential_preprocessing=True, verbose=0, + batch_size=batch_size) env = DummyVecEnv([lambda: gym.make(game) for i in range(num_env)]) From 40a94ade8208feffe6ae1f8be9e690c678e31e4e Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 20 Jul 2019 22:36:12 +0200 Subject: [PATCH 21/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 7996cf3c3b..d8bb0110dc 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -113,8 +113,6 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, actions = traj_data['actions'][:traj_limit_idx] mask = episode_starts[:traj_limit_idx] - start_index_list = [] - # obs, actions: shape (N * L, ) + S # where N = # episodes, L = episode length # and S is the environment observation/action space. From 9ed3cfaf6d2a699dc402ff01b95f774aaaff11ed Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Thu, 8 Aug 2019 00:44:45 +0200 Subject: [PATCH 22/34] add TD3 support --- stable_baselines/td3/td3.py | 2 +- tests/test_gail.py | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/stable_baselines/td3/td3.py b/stable_baselines/td3/td3.py index 905a3eb8b7..42b5f7ef17 100644 --- a/stable_baselines/td3/td3.py +++ b/stable_baselines/td3/td3.py @@ -116,7 +116,7 @@ def _get_pretrain_placeholders(self): policy = self.policy_tf # Rescale policy_out = self.policy_out * np.abs(self.action_space.low) - return policy.obs_ph, self.actions_ph, policy_out + return policy.obs_ph, self.actions_ph, None, None, None, policy_out def setup_model(self): with SetVerbosity(self.verbose): diff --git a/tests/test_gail.py b/tests/test_gail.py index 93d8476f16..8ad9b9084f 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -144,7 +144,10 @@ def test_pretrain_images(): [PPO2, 1, False, "MlpPolicy", "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], [TRPO, 1, False, "MlpPolicy", - "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1]]) + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1], + [TD3, 1, False, "MlpPolicy", + "Pendulum-v0", EXPERT_PATH_PENDULUM, 32, 1] + ]) def test_behavior_cloning(model_class_data): @@ -158,18 +161,6 @@ def test_behavior_cloning(model_class_data): dataset = ExpertDataset(expert_path=load_data, traj_limitation=3, sequential_preprocessing=True, verbose=0, batch_size=batch_size) - -@pytest.mark.parametrize("model_class", [A2C, GAIL, DDPG, PPO1, PPO2, SAC, TD3, TRPO]) -def test_behavior_cloning_box(model_class): - """ - Behavior cloning with continuous actions. - """ - dataset = ExpertDataset(expert_path=EXPERT_PATH_PENDULUM, traj_limitation=10, - sequential_preprocessing=True, verbose=0) - model = model_class("MlpPolicy", "Pendulum-v0") - model.pretrain(dataset, n_epochs=20) - model.save("test-pretrain") - del dataset, model env = DummyVecEnv([lambda: gym.make(game) for i in range(num_env)]) @@ -183,7 +174,6 @@ def test_behavior_cloning_box(model_class): del dataset, model, env - def test_dataset_param_validation(): with pytest.raises(ValueError): ExpertDataset() From 4bfb988a4c95bb372ee9d4fbe9866348fdb58414 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Mon, 2 Sep 2019 23:01:34 +0200 Subject: [PATCH 23/34] -fix indentation --- stable_baselines/gail/dataset/dataset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index d8bb0110dc..c285ae27c4 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -61,6 +61,7 @@ def plot(self): plt.show() class ExpertDataset(Dataset): + """ Dataset for using behavior cloning or GAIL. The structure of the expert dataset is a dict, saved as an ".npz" archive. @@ -71,7 +72,7 @@ class ExpertDataset(Dataset): :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. :param train_fraction: (float) the train validation split (0 to 1) - for pre-training using behavior cloning (BC) + for pre-training using behavior cloning (BC). :param batch_size: (int) the minibatch size for behavior cloning :param traj_limitation: (int) the number of trajectory to use (if -1, load all) :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False if LSTM is True. From 30bdb19c63cda8a30a9aa50191824a83808ed237 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Mon, 2 Sep 2019 23:47:53 +0200 Subject: [PATCH 24/34] -fix syntax --- stable_baselines/a2c/a2c.py | 3 +- stable_baselines/gail/dataset/dataset.py | 46 ++++++++++++++--------- test_recorded_images/0.jpg | Bin 0 -> 1872 bytes test_recorded_images/1.jpg | Bin 0 -> 1873 bytes test_recorded_images/10.jpg | Bin 0 -> 1908 bytes test_recorded_images/11.jpg | Bin 0 -> 1922 bytes test_recorded_images/12.jpg | Bin 0 -> 1911 bytes test_recorded_images/13.jpg | Bin 0 -> 1909 bytes test_recorded_images/14.jpg | Bin 0 -> 1939 bytes test_recorded_images/15.jpg | Bin 0 -> 1915 bytes test_recorded_images/16.jpg | Bin 0 -> 1924 bytes test_recorded_images/17.jpg | Bin 0 -> 1907 bytes test_recorded_images/18.jpg | Bin 0 -> 1914 bytes test_recorded_images/19.jpg | Bin 0 -> 1936 bytes test_recorded_images/2.jpg | Bin 0 -> 1846 bytes test_recorded_images/20.jpg | Bin 0 -> 1913 bytes test_recorded_images/21.jpg | Bin 0 -> 1933 bytes test_recorded_images/22.jpg | Bin 0 -> 1910 bytes test_recorded_images/23.jpg | Bin 0 -> 1907 bytes test_recorded_images/24.jpg | Bin 0 -> 1918 bytes test_recorded_images/25.jpg | Bin 0 -> 1900 bytes test_recorded_images/26.jpg | Bin 0 -> 1921 bytes test_recorded_images/27.jpg | Bin 0 -> 1911 bytes test_recorded_images/28.jpg | Bin 0 -> 1879 bytes test_recorded_images/29.jpg | Bin 0 -> 1905 bytes test_recorded_images/3.jpg | Bin 0 -> 1839 bytes test_recorded_images/30.jpg | Bin 0 -> 1901 bytes test_recorded_images/31.jpg | Bin 0 -> 1920 bytes test_recorded_images/32.jpg | Bin 0 -> 1930 bytes test_recorded_images/33.jpg | Bin 0 -> 1919 bytes test_recorded_images/34.jpg | Bin 0 -> 1936 bytes test_recorded_images/35.jpg | Bin 0 -> 1902 bytes test_recorded_images/36.jpg | Bin 0 -> 1892 bytes test_recorded_images/37.jpg | Bin 0 -> 1949 bytes test_recorded_images/38.jpg | Bin 0 -> 1971 bytes test_recorded_images/39.jpg | Bin 0 -> 1969 bytes test_recorded_images/4.jpg | Bin 0 -> 1863 bytes test_recorded_images/40.jpg | Bin 0 -> 2012 bytes test_recorded_images/41.jpg | Bin 0 -> 1948 bytes test_recorded_images/42.jpg | Bin 0 -> 1951 bytes test_recorded_images/43.jpg | Bin 0 -> 1943 bytes test_recorded_images/44.jpg | Bin 0 -> 1932 bytes test_recorded_images/45.jpg | Bin 0 -> 2034 bytes test_recorded_images/46.jpg | Bin 0 -> 1949 bytes test_recorded_images/47.jpg | Bin 0 -> 1949 bytes test_recorded_images/48.jpg | Bin 0 -> 1957 bytes test_recorded_images/49.jpg | Bin 0 -> 1948 bytes test_recorded_images/5.jpg | Bin 0 -> 1881 bytes test_recorded_images/50.jpg | Bin 0 -> 1988 bytes test_recorded_images/51.jpg | Bin 0 -> 1938 bytes test_recorded_images/52.jpg | Bin 0 -> 1955 bytes test_recorded_images/53.jpg | Bin 0 -> 1962 bytes test_recorded_images/54.jpg | Bin 0 -> 1975 bytes test_recorded_images/55.jpg | Bin 0 -> 1982 bytes test_recorded_images/56.jpg | Bin 0 -> 1944 bytes test_recorded_images/57.jpg | Bin 0 -> 1933 bytes test_recorded_images/58.jpg | Bin 0 -> 1937 bytes test_recorded_images/59.jpg | Bin 0 -> 1919 bytes test_recorded_images/6.jpg | Bin 0 -> 1901 bytes test_recorded_images/60.jpg | Bin 0 -> 1930 bytes test_recorded_images/61.jpg | Bin 0 -> 1918 bytes test_recorded_images/62.jpg | Bin 0 -> 1927 bytes test_recorded_images/63.jpg | Bin 0 -> 1942 bytes test_recorded_images/64.jpg | Bin 0 -> 1921 bytes test_recorded_images/65.jpg | Bin 0 -> 1939 bytes test_recorded_images/66.jpg | Bin 0 -> 1983 bytes test_recorded_images/67.jpg | Bin 0 -> 2001 bytes test_recorded_images/68.jpg | Bin 0 -> 2008 bytes test_recorded_images/69.jpg | Bin 0 -> 1980 bytes test_recorded_images/7.jpg | Bin 0 -> 1916 bytes test_recorded_images/70.jpg | Bin 0 -> 1977 bytes test_recorded_images/71.jpg | Bin 0 -> 1982 bytes test_recorded_images/72.jpg | Bin 0 -> 2003 bytes test_recorded_images/73.jpg | Bin 0 -> 2007 bytes test_recorded_images/74.jpg | Bin 0 -> 1985 bytes test_recorded_images/75.jpg | Bin 0 -> 1945 bytes test_recorded_images/76.jpg | Bin 0 -> 1919 bytes test_recorded_images/77.jpg | Bin 0 -> 1902 bytes test_recorded_images/78.jpg | Bin 0 -> 1902 bytes test_recorded_images/79.jpg | Bin 0 -> 1902 bytes test_recorded_images/8.jpg | Bin 0 -> 1912 bytes test_recorded_images/80.jpg | Bin 0 -> 1902 bytes test_recorded_images/81.jpg | Bin 0 -> 1902 bytes test_recorded_images/82.jpg | Bin 0 -> 1902 bytes test_recorded_images/9.jpg | Bin 0 -> 1929 bytes tests/test_gail.py | 3 +- 86 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 test_recorded_images/0.jpg create mode 100644 test_recorded_images/1.jpg create mode 100644 test_recorded_images/10.jpg create mode 100644 test_recorded_images/11.jpg create mode 100644 test_recorded_images/12.jpg create mode 100644 test_recorded_images/13.jpg create mode 100644 test_recorded_images/14.jpg create mode 100644 test_recorded_images/15.jpg create mode 100644 test_recorded_images/16.jpg create mode 100644 test_recorded_images/17.jpg create mode 100644 test_recorded_images/18.jpg create mode 100644 test_recorded_images/19.jpg create mode 100644 test_recorded_images/2.jpg create mode 100644 test_recorded_images/20.jpg create mode 100644 test_recorded_images/21.jpg create mode 100644 test_recorded_images/22.jpg create mode 100644 test_recorded_images/23.jpg create mode 100644 test_recorded_images/24.jpg create mode 100644 test_recorded_images/25.jpg create mode 100644 test_recorded_images/26.jpg create mode 100644 test_recorded_images/27.jpg create mode 100644 test_recorded_images/28.jpg create mode 100644 test_recorded_images/29.jpg create mode 100644 test_recorded_images/3.jpg create mode 100644 test_recorded_images/30.jpg create mode 100644 test_recorded_images/31.jpg create mode 100644 test_recorded_images/32.jpg create mode 100644 test_recorded_images/33.jpg create mode 100644 test_recorded_images/34.jpg create mode 100644 test_recorded_images/35.jpg create mode 100644 test_recorded_images/36.jpg create mode 100644 test_recorded_images/37.jpg create mode 100644 test_recorded_images/38.jpg create mode 100644 test_recorded_images/39.jpg create mode 100644 test_recorded_images/4.jpg create mode 100644 test_recorded_images/40.jpg create mode 100644 test_recorded_images/41.jpg create mode 100644 test_recorded_images/42.jpg create mode 100644 test_recorded_images/43.jpg create mode 100644 test_recorded_images/44.jpg create mode 100644 test_recorded_images/45.jpg create mode 100644 test_recorded_images/46.jpg create mode 100644 test_recorded_images/47.jpg create mode 100644 test_recorded_images/48.jpg create mode 100644 test_recorded_images/49.jpg create mode 100644 test_recorded_images/5.jpg create mode 100644 test_recorded_images/50.jpg create mode 100644 test_recorded_images/51.jpg create mode 100644 test_recorded_images/52.jpg create mode 100644 test_recorded_images/53.jpg create mode 100644 test_recorded_images/54.jpg create mode 100644 test_recorded_images/55.jpg create mode 100644 test_recorded_images/56.jpg create mode 100644 test_recorded_images/57.jpg create mode 100644 test_recorded_images/58.jpg create mode 100644 test_recorded_images/59.jpg create mode 100644 test_recorded_images/6.jpg create mode 100644 test_recorded_images/60.jpg create mode 100644 test_recorded_images/61.jpg create mode 100644 test_recorded_images/62.jpg create mode 100644 test_recorded_images/63.jpg create mode 100644 test_recorded_images/64.jpg create mode 100644 test_recorded_images/65.jpg create mode 100644 test_recorded_images/66.jpg create mode 100644 test_recorded_images/67.jpg create mode 100644 test_recorded_images/68.jpg create mode 100644 test_recorded_images/69.jpg create mode 100644 test_recorded_images/7.jpg create mode 100644 test_recorded_images/70.jpg create mode 100644 test_recorded_images/71.jpg create mode 100644 test_recorded_images/72.jpg create mode 100644 test_recorded_images/73.jpg create mode 100644 test_recorded_images/74.jpg create mode 100644 test_recorded_images/75.jpg create mode 100644 test_recorded_images/76.jpg create mode 100644 test_recorded_images/77.jpg create mode 100644 test_recorded_images/78.jpg create mode 100644 test_recorded_images/79.jpg create mode 100644 test_recorded_images/8.jpg create mode 100644 test_recorded_images/80.jpg create mode 100644 test_recorded_images/81.jpg create mode 100644 test_recorded_images/82.jpg create mode 100644 test_recorded_images/9.jpg diff --git a/stable_baselines/a2c/a2c.py b/stable_baselines/a2c/a2c.py index 47457f32f3..65e7c3cc10 100644 --- a/stable_baselines/a2c/a2c.py +++ b/stable_baselines/a2c/a2c.py @@ -99,7 +99,8 @@ def _get_pretrain_placeholders(self): if isinstance(self.action_space, gym.spaces.Discrete): return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph, policy.policy - return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph, policy.deterministic_action + return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph,\ + policy.deterministic_action def setup_model(self): with SetVerbosity(self.verbose): diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index c285ae27c4..c5c00c05af 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -75,7 +75,8 @@ class ExpertDataset(Dataset): for pre-training using behavior cloning (BC). :param batch_size: (int) the minibatch size for behavior cloning :param traj_limitation: (int) the number of trajectory to use (if -1, load all) - :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False if LSTM is True. + :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False + if LSTM is True. :param verbose: (int) Verbosity :param sequential_preprocessing: (bool) Do not use subprocess to preprocess the data (slower but use less memory for the CI) @@ -154,10 +155,12 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, batch_size, + self.train_loader = DataLoader(train_indices, self.observations, self.actions, + self.mask, batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, batch_size, + self.val_loader = DataLoader(val_indices, self.observations, self.actions, + self.mask, batch_size, shuffle=self.randomize, start_process=False, sequential=sequential_preprocessing) @@ -181,13 +184,17 @@ class ExpertDatasetLSTM(Dataset): Dataset for using behavior cloning or GAIL. The structure of the expert dataset is a dict, saved as an ".npz" archive. - The dictionary contains the keys 'actions', 'episode_returns', 'rewards', 'obs' and 'episode_starts'. - The corresponding values have data concatenated across episode: the first axis is the timestep, - the remaining axes index into the data. In case of images, 'obs' contains the relative path to - the images, to enable space saving from image compression. - - :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. - :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. + The dictionary contains the keys 'actions', 'episode_returns', 'rewards', + 'obs' and 'episode_starts'. The corresponding values have data + concatenated across episode: the first axis is the timestep, + the remaining axes index into the data. In case of images, + 'obs' contains the relative path to the images, to enable space + saving from image compression. + + :param expert_path: (str) The path to trajectory data (.npz file). + Mutually exclusive with traj_data. + :param traj_data: (dict) Trajectory data, in format described above. + Mutually exclusive with expert_path. :param train_fraction: (float) the train validation split (0 to 1) for pre-training using behavior cloning (BC) :param batch_size: (int) the minibatch size for behavior cloning @@ -195,7 +202,8 @@ class ExpertDatasetLSTM(Dataset): :param verbose: (int) Verbosity :param sequential_preprocessing: (bool) Do not use subprocess to preprocess the data (slower but use less memory for the CI) - :param envs_per_batch: (int) Only used if LSTM is True. Number of envs that are processed per batch. + :param envs_per_batch: (int) Only used if LSTM is True. Number of envs that + are processed per batch. """ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, @@ -309,8 +317,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, indices += c_i[i:i+batch_size] # Free memory - del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len, final_stack_len,\ - cycle_indices + del split_indices, len_list, sort_buffer, stack_indices, max_len, mod_max_len,\ + final_stack_len, cycle_indices # Train/Validation split when using behavior cloning train_indices = indices[:split_point] @@ -329,17 +337,21 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.std_ret = np.std(np.array(self.returns)) self.verbose = verbose - assert len(self.observations) == len(self.actions), "The number of actions and observations differ " \ - "please check your expert dataset" + assert len(self.observations) == len(self.actions), "The number of actions and " \ + "observations differ " \ + "please check your expert" \ + "dataset" self.num_traj = min(traj_limitation, np.sum(episode_starts)) self.num_transition = len(self.observations) self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, self.mask, use_batch_size, + self.train_loader = DataLoader(train_indices, self.observations, self.actions, + self.mask, use_batch_size, start_process=False, sequential=sequential_preprocessing, partial_minibatch=False) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, self.mask, use_batch_size, + self.val_loader = DataLoader(val_indices, self.observations, self.actions, + self.mask, use_batch_size, start_process=False, sequential=sequential_preprocessing, partial_minibatch=False) diff --git a/test_recorded_images/0.jpg b/test_recorded_images/0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4ca1ed9aa5dd71f371dc77523751ed1eccc96e17 GIT binary patch literal 1872 zcmcgsi(6A=82=`0Foq!_D59=_zyw7kniP*G1%{TF@B)hF!fD(}vZavDokvhaNaiIY zhqZ(-%gY|Qh(USMfs2&Z#0wW?888O7jED2VP;l#j_9-9d-4lD-&=I>Q1RiCBc&%! zetGJvimy-0s;a-QIrqc)AAhQ?t8cj4cA_xvXRzcvGOf6KKPC~%HVUSZ{ ze`BOn@2k+?(vhXqe46ATdEPZz0N^6XHUBtJ| z*LpTLO@9_+Zl1$?>{ys9$)h5*WHki(SIpY7csa@cl=rb?=E!LDH`nvk@?W=%9L6%_ zUJxinIRf)B$(=cI5FCmyzK>@@(8{~KUt7x!|69=wfx*DtXR+rFsL2d@PdI(FNQIHB z9^sbQUNOU2EQyEUW=a$_U)oiaLf`4EL>WWP+LD-~kL=v8vStZ3ptxOr=D~hLDz zbU^B92)s`_78Z2Sz7UZ7`B+1|bn9!)1Mhz8L>VKK_Q!EL1OV7X&R2hY3@KLnL18Jn}3aJ1N8#Y*@XXm3ahT<1{b*!PdQkkN7KVIGy4SJi`VeyCDNBM9 zf|oK#k#1GmmVFWJD<5C3*giTV;nk~mdzRkXb7uc!i5ORgNjl_XOXD}8s5pX@VfvF; zwtD>KZzCbNF-uFW;+os!^#jf+YXWdxc^(}mCAX`)MRZAc8D>uAP4Ib9rU|hr(XUlb zh9E*5sip&CY-b>-V)v;jU$mkY%>)Tn;~IBMChcj2pf3xZjFrwGu))FtG(UF{BA7@? z)Jjd!J|&T16*{c+{#0x5o$k=zz^v`gZs*gBgkM3%FUya8*Kxwo7Ae_JEZ8+Xc2Q1l zP(ZNk3D@pJA;?4N5R5HY3c)c5Zb|hfn-=3_@&~#B8jbAe?pQ02@)y~ZWP>9# ztC#&Nna28ZW7uo}(RS)<|+RNz+o2{P!uj)?aHL7S3ABz@fHb@FkzY^44I++21pu3SikS&nar?_ypnpM;nP5Dkd z0fMuobm;}_1)AgGSVsjotLrgFIu&N=FRmS5)m!!A_70qae8_p zCN`o$(Z$FQyr!|IzZ1KX6C}v=j@Uip{cnz6@R{>bQ(N%gd(4q>+w%|j`h|psg}?o7 zRP@}xzPC931KyIQ%Mz24`6;Vbf4n|5ZA1FTO&M7`KL1B{&dyv>!JfT^MgQDaa_~@T zS^43L6DPkt_3x_hPFL5|{^#PQy31GUo3FRD{&3^wt=sL2j?M?lhh6{e?dyN?bYM_D zq#GH1`HOzc@arp!b;9NkOD&t8A z_-&&yD(VeJRy*g|zoJVEFmnAeA+G?6--Eya2OwcG1J1wbYa%439`p6v#HYWe6^6XQS zQR)gHWlYG1(+~ulb}cIEW2Qks^5QVA#NGh%g->4g><*3P;b-U4jhWJhm+k9_$xXHvx>Ox zU5V@bnch4y1s^%nkBw?_l$2P0W&p#hM+jXh{)No>LEtR(zr5WLbPS9W#wwRcyo5gd zIsv;ZPBdS-QNOVK(yhw=oG#zk?~*>h;b@K)F3t)!>}tn!6n;IOp1uyHYmQ*ds#=Dt zbj9O6krowAUWedi#s4j&TEY0sUA$bLd8b7jWod7jh{?^Enc&gElG&vDTzl_Nh2Vfz z{2qDAlBj^-txQs+U6a0L|Ge%`pI@umF%g#d?hn1gD3_>`{03hKTX|Hl z$gUt;U6DC2eD9IzoNrCno(nIU>=#>3fQXHLMs-9Mot3@RxGlLJZ`)F9{@1ZzXD>6$ z$`>0ydEM0Y;k}8CUeaWIU531WfK~Dt6RNI7m+WE3NOC0Sv|i}e!4Cxyf5?)3j!?I87n-8nT3QS z>9Ay&h|D|~X zD~R0u)j^YBAgjP8FPlWDc(eSiVX+@?%4P9ZOJ2E6Z8SyfkL)QZzb1G*t0~`lVcQBr gV6d|aO{9W8jvH#)P=RYcf#CR6i`88gy5~XlAIa^_p8x;= literal 0 HcmV?d00001 diff --git a/test_recorded_images/10.jpg b/test_recorded_images/10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..196063e82d877bf8c3468333e05b581de09f7afd GIT binary patch literal 1908 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 akv0zH=W06X$&Myd71}#gd*`Kq!@mK$a@%?U literal 0 HcmV?d00001 diff --git a/test_recorded_images/12.jpg b/test_recorded_images/12.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1a1f052b0945c6d10631c65b81ecb60c7553ec05 GIT binary patch literal 1911 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 H3Wxs(dfVp7 literal 0 HcmV?d00001 diff --git a/test_recorded_images/15.jpg b/test_recorded_images/15.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b24145c5bcb42d5cbae8f4271aabca8614f1ba02 GIT binary patch literal 1915 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 Z_h?IG0ex6RG_kW1HT`sDmX(M){{sDK*2Mq- literal 0 HcmV?d00001 diff --git a/test_recorded_images/19.jpg b/test_recorded_images/19.jpg new file mode 100644 index 0000000000000000000000000000000000000000..95219ae3750552b474c57d8324a30ef5eef57fc1 GIT binary patch literal 1936 zcmchXe^e7!7RMh#5<*Zw6hT*msGzn|H6jItIm)jhYRig5p_1Ycf<;RaTf_rQkuI^( zZK`o~jfE)af{KeEKLl*17%`mnF+n;pk@R2lO`q7WGPk#1!&Z*qf zMPL4{SakL)@kQySe_X!u&#SVs@|(B*RZ)5SPVIxb`i91bP0f#$ZS7A~9Z!FF(cRPg zQ(ympMmMY<`Pnc!_RDM2&ux_x(Irqu23E21X%ekgK>)NkMENyY0L|)Lf?5t|jdoLW8 z*IhBjnl3}2-(8OkqYU@ zGz}1FATaG3f$){1ugn#!g7Srj1iM|LMpU@By6sHisJIrr)b0b4UI(1>tfh=Qn5byKm z1JY-yu9pYnjrhC z4#8uB-+Uw+g%fnSB0byX#ENSWd{s{Q@XX&rP{tlslOCNAwDqdzQ9mGcZQ;K6Wr8oL zw-Vwy&hgTv0Axum8J0V>mq5G+RiJVyeNGNz+@d1+CR+$yAkdiq8oAQy?+s8x8MD10#@%8SUaxLW;L{F>U9 zQ;oWHStU1xK4JM8Qhb#33V0kEBdXeT_u7Hfk@{Nk8t&|-&4vWLC~rBf6;+4g~V0hah0kJf1E3_`+YHr=gTy=CInW#YA#Vr1kvbjIZ8(PuS3e`Deu2$X%Ir=D-#w)62^<+DjkUW<9uNB?dokH0H0Eb(>N zyrVa3lSN)9KD@qv**aC~M{EbN-giE4@9RG(v>=}UXafW*0!!#aJ%?cIAXavVyhB54 zrFv)@So(z9_lX$$QEqCLLYh1$7`BT^Ocw0Ajsjejw={TihIHX ziN?0m$IO-sVHeYzBl)Yx=Iv|B{h-?SBui|IqyGu*1s&LQ{6{oR|634r^b%G(Li$<= G2Yv@jzub2K literal 0 HcmV?d00001 diff --git a/test_recorded_images/2.jpg b/test_recorded_images/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97cd06ef251550150c06cf0617e5a5e98bb3e66b GIT binary patch literal 1846 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 a&1)kj;@?HI`CWsct&6hSxw0n*d;bDeqR=1! literal 0 HcmV?d00001 diff --git a/test_recorded_images/21.jpg b/test_recorded_images/21.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17a98f10f7972c91158a8fc05625be22f98d9980 GIT binary patch literal 1933 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 I-b&Q}Zv(y6Gynhq literal 0 HcmV?d00001 diff --git a/test_recorded_images/23.jpg b/test_recorded_images/23.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad341e5388424e7902a246005ef3a8a8d3f20588 GIT binary patch literal 1907 zcmcgrdsGu=7XNr9fzSd)2++kSA}A_8FwKILIm$~^u&h)Rl^lE!ENxSyD%~SYfi9`h zZE9n&Mj?gR;sd2351)((7<6@0KnjEdA%q6DCc6{BWCD}>c8`;@!E6;s*US6xb^uv#Jm#LhSA~Cx6Mh2E@1k=%n7Nn zf12tsh=#E0d$))8+~pXf@OumSBlBzWOGM;KEun-!w;0!+id7IvNBAGj2mNbiZB^TG zwcN6DhU^9v`?+(;7vK{XZ`Q@96fL5xx3D6uEWiFks&6D*(Q0~W&@aqJ#KFRGzj~8hX=aA@8UfdK*#QPR!2!8l6DQO3E)Ef}ig& zsdxy2kpG<{gUFuJ(X$*}UaqhSDc*~LNeD=exRY9n4~XM}5b=rl;=1z#tqdmow4aC|S;(U;mCF16;H#tCO?tK;R|E1tjs3 zORNx3o0SxoH-_2FzaaQdj69P}#^tx8Gx~aT>^kb0z7qpw5KO9e(Yj|rFrCQ7Z4GV^ zsK2^Nx273_2??T`$!0^K2tELT8?DEa1!#xiJ_mxh7!~C)Ku>JM<8!o2iXXE4AUfC* z)0SK1E!>uEWRhg&R98t64P8P5Wf3_L2sEu!>0yDqDLrvPdSW)NB2V8vZbxZ-Yb2E9 z+Kh@~TOkM;=rY5it4F89 u8&f%(CBFtc{f)Ca!f)cu&&`4>C{8pCaVW`3E)n_yvjt&XN3vsKaOmI7+tYdg literal 0 HcmV?d00001 diff --git a/test_recorded_images/24.jpg b/test_recorded_images/24.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3edb945c34255e74e9acc3eea5624197c9973f89 GIT binary patch literal 1918 zcmcgrYgAKL7CtE#Qzg zSTYt1LoB2aEk3X*2>8Hqi#&pkP6VVt7z`maU=7n7py2{H_sos+cYe;AebzbaoVEA) zzH`34Hynavz=$$Lu#npCzKLEB95CDOlodz7-J}6B`%LdoN+fUcvkOlJ*}+K63O}nkfDFiL8%4K7A%T=WNlr zzZ6S8{Y?5r*~Kr*EB;m~uT@^Y@=e{=Xwzszo{YCEG* ze4kK9wd-6i6Ed^+uc%1n5%+amy;cVHpLqV7dGD64O4)p8;vZu#=v#NzcN%<_k1Lug zObO<42n@TM&nzKSPg_X;{QwBksE4;&`ogzglzI0$XRez_*q$cbO8&fcH&b9Q#90p!IWM}ri%r(YTkt5Xoks)#2!x&kCsp_NdcpRc4m(cvOBGK6Vc zAkac!-Zct=S|x82FE;Duxp}%v{qiX!T{9#yaLG5^mO;=FO+8*6K|kh=r36gB3IeJ4 z_YlbPlpOO+oA?7Ol_C8vxe|U0L5pzu32v|ieTP#uX153O=U3YTI+L+-+1Y@Sr ztGf2OF8q?(rT=lmwe$~hwmTE;d;8_ImWZL)1^A8eq%Jo%GD4!)6oenjG^xTvPv1LK z_BhqGd?fKC%U7E@7rtPIz_oH|H`?oH7Ew+{2*%TC*>+m%kg3A#TM#&Aq2@5OBQU>T zG51c?0SF2sFhY*#%aG%mMgMAAllI^0$Xy)#p`vNh>b}Pt9V-=6fimK#Mw>-_8dQSd zJnpL|2@y@x>5BF2QV?q{LGYQ9@(s0o1wpOzxQ6t20zv11<~P(Mq^UF7|2w(x6Kazn zv8N<7y$pcNviXep>y6|teX%*<-J;!zvb7Bh7V@rI)z^sX_hDA{U(pG~tfZD_K=AY~ zi;9835Bc9Y1VqY|p04FpMMa7Q5f%Pya1sJ?g`|^OhYw1k{SZlROkQ23>SO+f#@6iH z`YoANmqosB=Vg@PlcaahgGipFKJ3P&L#Y$ZjnWOArLZ@R0`QepS`9}obhmjX}WOPP5I%}v$$8Msw>dPH0gkVy=pVmDYf|)oDzMx`2 zpeb#jQ_~E=gcQ-wrm!JUtU3Y#gVy7r7usRGzXF2jNHyg$NLTE}?h4u^!;e|6h>x~J zwxw0Mi*}}%SR|P=)s>%3L+8^#$wVpyLhWs;;J8rU#E69o^HccWgp9Z ziwbBE`Xpq_`K{+q?5Sgf)~_s{^+7MT{nHR7x|yilBF}!*8}{PppEIv@`{xKYh2#_+ z_g`k$9kOY0o$8T_*vy&UgCDe%J|!6$bn}$^{rv^^Y>945MdeaWz{t6vv!$&o>#pQR z*gou)l!>1n8ROqM88iM%NiOdjjX1}1II!e$+^Nz}ek!T>(q)GAyKL1njL1zgl|T^Z W?M5y;AtXN+$}YZA%!@CC!~X_qyVAM< literal 0 HcmV?d00001 diff --git a/test_recorded_images/25.jpg b/test_recorded_images/25.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69650c6f377020af228995f71984006c2a4d631d GIT binary patch literal 1900 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 KF;7F`@V^1_?$nw9 literal 0 HcmV?d00001 diff --git a/test_recorded_images/28.jpg b/test_recorded_images/28.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce6d41040a371c7cc0d7eb8eae7cf83f3acd8dea GIT binary patch literal 1879 zcmcgreOOaf96o$)z%W1r!O|HbC?f#LN?CK16H|Ol(?(XK!@?f!MU$&Pgi|xf`u{=4R zUf#}NRz4hWALj@98E`y78c1_-@dv04a2arqSxkoEpKx(?bN67enSVJ&;&m}KjY6*O$lMIXA`*yLHchLOckOfP_ zBbF_XT*rGh=DFCogv6v|{>GF|+tXg%A=tSqec%2AS)%NNujd_p=iMVm-+RC0!;eZO zAAchKT>izEWv9M6t*EL#`|Wo%=e|E*ce!5O(D+l+l^d;X?Kd?Yw{Cao?sxyz)7z&v z4w{C3HxG~e@uzisV)C(Vin325J@9nOh5a+Ds%sO@n=I?B*jvYV-Gg+YnJe!Ty|lh$O+7(BjjB41|d9*3P~ zaUW56^{4*bSLR!y$*YTE24+_06pHC*3{*7&#-~Zcu?@4oYvJNwWAcXZtf(;xfl4AOE^jx{fLWpkacWn(h+ZqQw3uF^ z_{{c$>*4+J4KcNEK;1xuvT(O|uVz5xL} z0@keq2xwG_X7RMzFcni^DAy@QuxxFw$P`1b@|}x7YdpNOD3;mGs+knRxDWxU_+Zc(eF52h5TFORt1KAkZKjyGxpE5kHdfjMevs;=#G*P=$GYYIRuH%}oC?gSn$3 zzw@~0jLH)Mi51=zPNq1UUHA+F_D~sxb1mHnB+50|)SwoD&zJr0RgpQqR1{$uIA>_7 zX(!7y-nu)NzR!Mxzmw@x z*1!1>J4By5$+KG#@HsuR4exZfilC<%fx&D>wk?htY^3<;Wdz*waO*m}HM~%#oP1%! zE(D5W2}*$(<=8>(^x{fJla{9p^j0o;OIbhc@Ovo;e|SO+!)4Tdtv(Na9B~XI`7yJX zWUXk7X;)%EyOLT`j=(3?FeKXcH3C&$gIe1EE&^@c+9%*`tiCON@sA4O2XIB&=8j|0 z*>V7K^NgG^B_DJFvV3PcVf|}E+cT$(vT|L@pT$x*O zRuuAlL5`dprh_7G#PKDy>n@b<$sAJGNtbhH);()Z17AC;EBWb72>2>UAx({PsTD%F zu^MuD4+*>VH;mjt&?otHd`=5KVXDO+Uc{a5%kL>hU|6%0(LEi3@gy#3S9u_yJ#mR? zjT(U=DQ29=;2@w}xDNpjMvq(b@K*D+`3S_vX`puxKkFvL7}2PHECXIQUPNb3EsxLVbS&(Rj!2 literal 0 HcmV?d00001 diff --git a/test_recorded_images/29.jpg b/test_recorded_images/29.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d8793a4747b51a8a3547af737cbd8972ef01a097 GIT binary patch literal 1905 zcmcgreNSjeJ6Kav2BOnFBfe=CiTSI*Tn!Lcvo4(M0`{$m$b7s!Wxp#iQ zJHLAe_QMh2y^Wv92QDrExX=T@K@bOAU7Y4zU7f~obFNGV!;QgWvRLzz?cvU1d$3t7 zcaFPufG<0+k?FS4W<_j;cf1Tx_zvGH*U20z1@W`3*Y~KsfVZkqJY4l zb#<+_R=@s)?NPYO5@EYRr9SMZr^#JZfk$2>FE5iyXR@|&wc#^ zI>V@O>=)Dc#D9OaOij=HZnY8iS*Qc!!KI+h#_F=z;vO^+&e{e znZyHF_1zx^_uW}!4#)2>#xg}U(+MHawY}vz1p9;OH zqpGm$6Vb&6cL*dF>alPp(OK-`S0Jzl%LtTb?u8&;u0d?0S_nR0`G1dEoyR4@F!Ru5 zeQRAiUa9fyd358uocC~!Hw*3F@@!H^#8I3Q{OV|GJC{pFNetSOi1d7OLqzxochcpL zGQBDWw;yH)>hfnI>=p>T&d=>cyBHP`4XLhocUeC_R1?0!9I9*@&uF6!$1+ zUXR%eL1`35C=i1j$<@v-t)?|;eMwIy@$gP%)40R?O@DOcQ!%wdMjX`Y3aF1mPb0V> za{iNS5KYqMiuY|-5+RikoT{Y)!>tz}sPP!pl0J_iXzSJfjrtL3YKvWZT_OAzwI*eI z$La7KIRN=`Tb}JoBbj6cq<`pxXn~}D>eiWsIdI1nfoAAo>K>(RLoRh#ZDf*>|pLwWYm9lQGBIoc(|v#j5U4>m`) zWLJ5Mc4U~@B$+zVUVNN}E~bIfh)f8Cx?5C9u29jGoUkxCAp_TtpWHd-Kxut1N-62p zX${4(K@i-h=FU>R*bHYI*;^xBStDI-D@Vq%da!4+Jcn26%sawr1Q%j<|CRu>&w34l zuhUXZ*J#9r$*K3&Ll6>HMRPrYU}8U3bA_avveW@VhYD9ym`dz$?ZzT<=5g;EWcI)# z&u1wK1aW>2ztmq+Nq?@jj#xV<$SHPJ5lP0M7G%v--cNX5@zW#6le32(_}&+!pXupt zd1)R%nUoZp#2?<0mU}>z`{dnDSJqKkNd8+}86_87`AHvgOAjO2OiTLY^HYUc#x)#H zI)77F%$cC!6Imz!UZJ#I@o9_>`;B|8n9f%{iX9ZruDp(p$ls>*Iz$%EGtjSx1AhR6 C63 zgQ823AGl3*pEf%>!NZ@Q?HRg#`r>bnob?J@(by62QMV~P=F=T}y?p|Mf;HUZwv1W-vi(ik$Ke3*a?*wYY8?dSA#@Y2?~4;cu!;~N=2T7Kr`E90hs6)ySO&rVdAf~wE(CYD*Gg4QoXFR*0SL5O&K|S9U|30JO9vyFLuCq# zO#K}<$NnK=(dFVe2yXKiQu8JKWqjsgUmdC#Zc8ByT>}8Yh`FG81e0d)2VPvD#@vCgV%^Bahq!H4ReU|Ln4f)dHLA9fJjZYpj##`q z+^nR@W(ZzX{cj<)a)vE)aPzsQt!7b#`F6`#RDR~nIG0YA)GFES*mY|P1bfw@x5?w? zL^%YLvq_;kHRF>#^SahNzgDwlEI4t_Pmc!^?(RBWI!P?TMme7X-;lF}eTj&A$)m6g3B>U#d!{7HD)!vU1ml6xMk65ot z$#fY6D_(HyeiVY-p9z6=K>`GaA-F5~4}8btgW8tjWXfjsFoP&Nv@_O1PyuXPySZkx zPJ>O(7kl4m&U(IiQ$q{)MB3s9QK3%pC${ zwR0t{PUSZKh}l{`u9iQx}p#dV<wD-$8kt(TSLFuaZLG6cFa9^Ju{)9vXHxR=qF7`C{3fb(^O*uTUg z-%uK1$0XKmYOiZBJxnj0B+d}U=*#8eGsko;A literal 0 HcmV?d00001 diff --git a/test_recorded_images/30.jpg b/test_recorded_images/30.jpg new file mode 100644 index 0000000000000000000000000000000000000000..56a42369914dccd42205ca9c4af3c31d399ec592 GIT binary patch literal 1901 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 Sq(e}3%`)c{g8nwc@&5qZjNAPH literal 0 HcmV?d00001 diff --git a/test_recorded_images/32.jpg b/test_recorded_images/32.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5e5800d2b4874540d0deaf8d0570d5ac4d3a28d GIT binary patch literal 1930 zcmcgrYgAKL7CyWZAUJ^{&sL&{;uDcaQ_yl(%Ok~S8L3e$WT8T^=wv8bX-BvNbclx9 zj76yZtYTAvUS8@Rb=ZkWIGbJpy0&spcLz0ddU z^X+}$ARGmr+me!#fP(`74)g$U7{mid2fNu_6}az;XqtAl1Ra3&2jmp}}1iF=>YXn1iE}vkQYspJmYjDo>iz z$%$rip=s#oLfQ|UydvH2~AcSy-u}Rf@^ZQ#ZcRM<}?y0-)|Jd92r2px_ z;E+~tFpfPpjZggYt9g26_IJx1VV#Fs;A)o*0c0u!WdXJZbYgI8J_MhRs3Gv?k>Q#t z83ak~Mg_V0H-wPSueAKxR(2dA_QVRvFx^n;0XnvW@=Xv7qr=Z$H76l@|LH?Br=*kp z(^QX1G=x>Rem{Jm#cwhaZw=y(EQIG4iO3B)q80-E3S3vdRY4?u$UU|Y_;O}*Roh98 z;!biM)vj~DOi0bXzoSB>SK`IQdaV@f`{3CU^PY`e7o>BY+y9hsPT#ttzSHRMV^B1m zpG-DaKw#XZI=O&Q-E9$lw}T7bDeCfHN%t z#0&&(2^ijtWG~?@L>?5;SCMrTEq}z#A49XlrU(eCv9Q?u16VUM8EHU?{b@onLO9uO z+)eQ4^!=NtC(~QG^+&0`kx<3WsTU?=PzEAi7W439T``iW(26PVv#(O#=uoK|8N{^B z5NIJV?;L?Zt(3Qk=2f~mZlSKSPd~m7uCxWqOLk=z54qF{EQBu$dfpb1;jzT+D7xgJ- z-`ct#f|3}FkRy5-azrz~yqeae{WTrAlY`$^G>zLlcl)BFpNpu~QsS^in@^n%Ek|%3 zckz)#2&d?BC3tr!h?SKPoT;S(A}wD*P~&FMkX{cV=Wo|dom}u&YJKYV z?()bS831{*x!k#{4dhOJnK}6F(p}r7AvdfR@|IfJ+koo#Vm8*_(J{naOZntN@c0&! ziiaQ&`QJHGiHr$7-OI~LOBGfj75!vj90Jl$+)1s%2gGrKi1<`|VciAgiIlYstpzvr z8}q6z3j^LP%$4Eeq;KfmSf02(>RM%b=9sEMvX-+D^|~n)d}XVx=B3?&fGx)bB=Len ztQS!4)KZ-2QOs(7ir{-O@*Izh%WX$zjP>Z~b=2N{rv^$O7+3G3bx(s}I+250l`ary zKEFYiMg_r`1kulAupm$@I|P9Xt;hYPXou;x9|Uo+YRY|p?$~wr&eJX_o@M!3bhtUT zExXE7xFchdNs|1DuA%}Ox`+l!BQhZnXm3)*M+EYwl*FYei5a+>{H*1q4W;$HB%vhN zX4DjG4uar;4)#3NkIk~Sk^ME2H8qlTb7ja_Rv-3ao@4Xi&%P(9MsNXU^=qQyA&B>}`S73fNnf_5j@Y=s%PDeH5j%}PEy0GjM1xwO3 zqk_|MQLX(I;YY8lHn9)HJ2fZ8w>;`fihLZD_kPfs6FwD=Ng28aF)xQyM? literal 0 HcmV?d00001 diff --git a/test_recorded_images/33.jpg b/test_recorded_images/33.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f0ba514ca2f881cb00de3a2850f6fd8667f4d268 GIT binary patch literal 1919 zcmcgre^gUP79Jo!fZzrMBG_syqNr7>M#_SgcUpc#ROnLCC{}V1B`CU-VyoQ)yailh zLv3nfaSeqOu*E7iihurk5v!>BVF) zJXxMz-Y%n7J}hq^*9QIsSe_siq`JBJ0oVz+6gYhzlVbS8+}u5AbOw_;%c2sReJM^4 z4~mIS(NNiiR2nsgcdmB?zSo0=@(z4h;^oa*6coI8 z#mcZ%tJiFbcr)_PQPHt+@d^B`iQ9Ij?%FNbvo|gC;Gry0_TeM>$3Ob`#K}+oR(k3m zW#ZGHO1_kx`>NvnKQG8@>n?u#UHzr+FE`$3YHqptV{6+TO=s6#ZTG#Od;1>u|EeDt zG?+%rqt7g33DV zK|+UFL9F~8!R52d?H@SHjwATaXdw}994y^O2Z8A|%vioffhT+zd2DX+i>VD&suMaz zdtyD=Vf4O;OKqH&s7UD-|4n>@K??R9d9uK^b6wX3=}hPLzs8+4-P+O6X$}e;Q8b;m zCfX_>Fef*km_x{J)yBTtArNGd_inWGMr=MO<@9*vtr$(*oF!aO{I))sk?JnQnD$_N z3IeY&Z;V9WR9HzKA@!VownvRHjp&TNa79lLI^Z5__< z>8>j1`Ak%!^n^fcBOeN<6J5nFS_^?AM2e$aYd-{WGA%MQqJ!YeRsZ*_H92fNTx}h` zWbCN#!YZ}ieGjgGpM4Z#`7+Snx1LWJ@K};nj9nQKbg|h)l-Q&zj@X}PRYveWZrd+= zkl|A?wEY+}*pN3J;jlsAb73wS?V;I3q^AXfk!(t~9nN}WyyWB!2x$4JZ4;_lS=6VP zetXMa2uh;VxEwLbki)v!W!01>9j_XRBrbMO(KP1teV2ni{XCakDa8-!4Ef~guyO?B zN6vqejiL#vTyg$g3VeAb1fSNC!94rd5Y&2&=m@`u5OntI{zU$aGoil>j8s9s)DTB>k}$cV@KF$jo7;!bh}rWeO7M#KfNh4mMdAEm5rymj)X zX-B+M5fnZF#htfR_g2{L;=1|fh z(0zWLDory4qY}h4mCk}du_O}$I;F?G090eSy$FJsXf5fjr#g1c-SbpPiXF0ln|rV& zT9sAhE83B6WfFv7ysPLW1zkh|rQsP62n{#M;=@9DQ%Zb5N_;w|B|d9A;Y2BYYb2!P z%9NI5%|H;M*RW^Fe)TkK8_{1YSyd}pGgF3)9_mv+pXEAz1k<~O)d(h3J2Is*mI1O$g|ugBNT@w1EEoAD&`{RM}nE8F8=RNQ~ye028M9shRz{xf~O zs#ht1DRPuV~wsOn=#RinX>!`>$Hws!Z!vWt<9oVLe*Gi>b72*6Kb8 z$#hRLmG4R@D5yEz8tP*X3w-ufPF$Ph{@$kcs%u{iC;XoGh(ViH>J@l_z*-JLJcmsz TJR&5{2&L!dB@0Lq!omLlA)?wD literal 0 HcmV?d00001 diff --git a/test_recorded_images/34.jpg b/test_recorded_images/34.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ee18732583660c8019b74fa27f56a4540a43468 GIT binary patch literal 1936 zcmcgsdsI_L8Xq7eKyZQbwrVV(_^6;@ngx-2EQA#CQ7Scxl`K9;Y-CxA7TN>c1-hh- zZL^jZ*C3>V7ON-)c_;{Jco=APBOn6dU<|>)*0A0H!iC)2*&F)r{<&wrIWuSGeBbVVk zr#ms7oLy{2&0Lu-uC@jI88Dqd5=gSM^8m05uqbfHWlW0UceAs1pgGbR)LteP(CAKa zIyg{FjuZ_Qok#fr&BO7vH@5AfdnTqb0y4eA3eI143Vgdx<^5hC78HK$qe5pFA74NJ zmFw0AZ`inLJNqrpA0r}TV!3g=cj9*+NP7Pu|Ip#&<0nq02}P$q%sO-SJQb|e!O0PyP>hE`Oe*zj?S*``|6(FU-}0g4?Y`h^?CG z5(wf{1_iPH-v};W3Y`CowfGEzABYqXA-a*GBUEfB=@Tm$MMs~$ZjM9rely2sb7iK% z8M4oqF`}$!y)$~G#n%*$wXWfeS+^{snqx(t5ao(Ua^27-QZa zpM}6VR*5wsX)Ab^@M9U&RZ2SZ*Zz}}HG!suOydw#C_^H%jwqWDQ}{TFA5In$VM3G2 zupj49$MAJ0T_YEF{_W5J5%=@&-BniNE`I^y9cx&kCsp_P!HU%gIxq9a9WWLT+f zfRNew#!{nhfs>~z8<0;SBF(VSz#&52UW1@BntZS(f;vp7C0?mt4S_V{ zT?k}(RV?#Nd&UP=QY`&1xf0xhph+pFn8}BNxp-T$^WTJEF+hf+EYlzau_bC`VO#^jHyi%%QJchWc!<(8 zc1@?M?#9a0E&~theiWU?nC^76f9H#7EgnNM3$PpG{BAclB0{3q6tItGnrhkMAGaJW zd64Q_I+~Eq@YiO}u@}t{xL&mEL;GlEA?aj+=T` zbGxDrLr@r@#N~*-1UaQyT3bPBqFSXR_Oh^EMZ=`keZLR-?CT72y$nC0(PojK2cJVQ z9%uQHgbAmqbj5mhEAYTF2)?Ky{ln)kK~U*Dt|2@gLeMp+`2+b2($E#X_9waEujJ;W zgr0NZq7ncyOBTcn*XxPB`eJjy+eP~lWI=U{^Tb_sZGSzgKd7`a|Bg-|<|@)#48fzj z3^E3SmB|0jk%XsA>8V;?T~wr46q4-6Lz55?zLG9-9X2G1UWrI@WAdsm)}Bq=Sl^n{ ztlyGZensfNGf!NCO%guA9g#dq&Gs8*M^h&n>!ll6mhEpDlfWfwRRu5kE(C6JOhDi- zSomfE`A!wdVn0(Znx7!pK_zjXM?{NN=&YdzeRdPIRbTExFh2@A*Oy9jPW=hNz0&bpHb7l3^$3uV$QR zifm6ScNgwSF);{&Kh>R|LqX?LK*@M21Oja{S#U}qZ%E{NC2~_RHSuLjwiTuHy(}fA zH)ho&a{+>Yp-#6Ya!@(P+)WHtN;gzWH!Tz+6DJ3hFP2zVSN`1lf(ir^C>MR&{m`NL zn-F}T%s1Yo5WN!l_qIV07*bAgJ%V8Bn6mOZK^0}86@s2dtdmqWW?1d}m2A;6Zkt}V z=zr$r5-EWo#@p)6f6ga-+~%wCEf$_A-@XywYxs4=$+@yN?#t3&A6OrqPw((-;~o8K zpuc^U4WP|e)xt8>oz<5m$kycUGGDE@)ssJ({zJ~ET9HTdDq41V!iqal1-5Nx141g*vbfVa`ySTbBnDky29ia54 zIbB?6CO4XfjxMDAz}3g?6t$*v!rznX@R>#HVjZ12$Tic8}W&OjRgpNHmpX#mq)G9 zOv(^QX)`FOus<+TJ{My7o4xEXMs7Bt%c^sf@SlN%Le%AvS}wnZtxi z(>YVBxf}sQn)0X(gI%rbdhY}ykOLoFZ|;fR@TD}M+arJZSn7rx!5ZrKHEE0tX92;q z1d-DScqFTcW-Mm`&lbH$L|;YLUbO6&xPmb}Cu)*Jph^{$P_RqYjG3ZGadKy-kXk1+ zwHe+adGzrEo8XhFjd67!!rtL<#f{15M#Iu9OuQui(Z{-CEL))!L*G-2p)WpIs>TLX z+GYf_2$;7HBcN`Ow~FSJy4kowT}7{a0?XA52n})6YWB+rv?s!cOXKOothS}9^h*$s zh~7m&T3Ev|Pqm8vVuyK>|B@@gj|emiCLa+7OZZg+UNE!o$ww}=2Fr~b(rZFP?`Qjz z>x^BM$Gg7}UTAPfKx~GO1T(3QWEZ`LfHhc3;v7>S0?9HpHan_8;OvV3dsIXon~YMK zhA-*bYCDMvwP)|cYd_?ENU*#ac+VTpC$(e}WEB%vM){p=HWe?{Yl>rc=bIX0qd&T} zTlO&9t9)qlL1vIPeH4CA;5rNTMTDC3rT5O`^*mVS43vhD`-X2!e ztC)Fn<4y!h;#H&^)61{}nz?0Fv?gt@=%}q6;(?-R-0uBO0RHr}2!=_?eHv{6JQ02p zBY1K1k7S*2l1^8$Z>NF`sX*ZK8WaoJV5;O{Up zV{_NZ=v)~9`Lfx(*~^X8R(+W{_^r~k&C<|oRtwdlZs=*m_1jf;)<5wv%v=Ng^ALF4 z!h}f(EW-YGjtnwuLQmK7lG0LzRS09B^p7JzEfjaaW+SzTrsv%EsHr zZs=F#S6&nby-}DaBgUzK@Oue7ab3)nirv{`%0|gbjxA=rF#~*Kuc_i?wjjWk69S5S z&LJZO@a-DNiG8ZFnt#QJ?JDXFk4nsI!>0{(_|tmaQGLhzOAr`W@1S+hL|}@`A*>B< z2xv}Uqf?_qU`&GPr?XfHD3U`9fgj#(yt5F2!~`|;?58U>;{G|>B_;M-z7y?h zPH4@k^cHT(GBGKNKharqjD{|vfilT#1O(a}u=s#L-jvSuOXp@0YU+zyN9{PR?*$2z zT$xrw)+_?S{q5{I*r%FdZKC?BB`c~W5wm63*#2JC^Er;)i$C+epb8@dDr-P%Al`4O zN8sB`zOkN0^h@X8S&KkOR3**z7=ejBs_M%WU6dtu1iF+&J5(t}cIO^dZ0*{oR+3u{KQGunQ*oF3qWtHF_Qz)q-t)c7+kL9H zr}dS2fD!VDkQlLbFxZk$jPSjoZ%0jW2aqSbamPJx!R zv2CuV#TtZEqQxo}MS}IkDFzI*+6YL2urP$sz^$R408LKdWTq$d@BMk#-Lqz|nYH(P z-^{o7pnfzA{5PkhrT{lL0Nj`X&>%)N0n0oMy;fDAXc0D#&6j{*0b!(7(i3OBB3`@N8uVrtxg>h;yJg-!!3#n{ z!b8{I_)%zPs3Xtx4T{{f8Sj?`qoG?`bs8V(|_9Rlw$_zftO1*4A2<}RD?Pk@$vo*MF@N}q(vZ*Pp{TZ z$Pq|sH7V(3e_)hiCc^eFXT@QR+8!^UqYMM(yO~@K3{DaZ;)9Q$v!-CikjZ^h#WG9p zB){3kAK2uS`Wxn3^=I}bjdXWhQ4{j|*9w&kBmCyckY*0-5Lf<}~0 zr!1+~N(4;X)JJDA*wM1K=XN*(xv=wEb9c=8FJ-}9-i1p?Q`hGTR@1+)-p0;w7myrV zC^dzEcM?H1W4ZJAv(bA+%v0nV@#0@%i$?L>s0j*z8X_vbXgAS}S)xa9YFCz!UMsY; znqH^)%=JT>;G@Y6vGwo3o}ozP^@%5D)1qulvM}z!`-W01N2!;~r`rdaxAzh@E9B*6QN;+V_4Jex`w7a|}P zy@7zNM8&gCwus(#!UE}ksg>Y+1eygC4@i?O@(KyhTK(=S9$#n)SD4qQtClRemlIHF zFn3fJcYP*2+u((O#0nn>rc+(T7QcjmBV0z|JWDSENpdY_AJHLja{2!~Yh{5S6-8Kv zE*M(t+Q}-dPtX0U-{rkSa{bwO_r@m^dMXieOUX+kneBdlbezPfD~;JxXlaOve(&ZU z`TZQ<%E2v%IHCH&=@^F<0pHWJ+wd-yRS3Pz2#n-0vTb$NVdG`Tt|7oG!maCY%`$P1 za{AQ`yAUXgBPa!Clw)qL`MfaK%lKx_YC|AYidhad_^Jn5WbkP zrQ>*Xo*aNexxK)Cv5`(QR#?MdE8n(7w&beAM&HmjbT{J09fXtnZ+sN9s$ft70uOI+ zU?Kux*#9n&L1m8{nO)FoG^4_Nr9Xkqk|*w#`7ih>n>I8$r)8QN>}h^*S%uS0B4-48h+Ld1pE}FfTo`C zs22rrlM3=;h6#uDSB%_2&?oqGLP0A&Wva)AFXOK6EAA^pU`)G{(LD=+$z&esXz)Zp z_r+DFG-?D!rI>Lln~Q*Q;XVXB89h4Z;~Mkr1qdX>YoSjc)3Gb>onk^V@__BUXn%8j zOK!ElaBH@OL(`e#?c!q$w3q?PqH+)r=&!@le1W1VJ$Zh5ayF@@Kf8I6y3JAP^B%&2T+LV0jXto(iI{D*IMy0eeSA`0Kw#40`Go|5*#y{}Z__8no>YLYr{^{_{u pQ(_+4-Ns3ZE*>4z|IZ;J8A$p0HT4toy}~kz0DjQY^#%_qk|*OiAH-h=`PMRx(l5~ zb7nZZxY~@`xiMVbYzNo^7|wtLICgfP0IC3s0(W|aNoDwt+1WcdI??FVT?Q3U??L5s zaG)|dQE8~?JjxFoJ)IV>diy<^S5g|?KWoW`g7X#5tKYxV%KWes3kdt@(?S$qHrfzCa3Co5v(}>HeOt02I5Vh*z$=~z)l7*Y zh-)=SiM78YxMY5{`4emL2?XCA$tBk7`il-wu}acAhC6@`Jb&F3hv||jb(z-FL$1ZPl=xYJFR)nW(wAtjBf#(n` zp8e{RY~W2%a>aPHN%7T}Avh}|{ld&wAgFX1))1agAyD;b7LkvUI#txl+Y;^<H`QT#8?&$fc9f$%IH*0n_+F5UTj@Ki&ZaI}^vhh$;~(`R zi{FVC^P~`hXr`5!JSHN1UXZc!V%AG*H9GEn!BTCjaLJw*ZfN_zs?gq9WZqXkep3;w z7`lztBdr4M=4gy5e<)b7j~{Y%a3UnPA(i+0nRCZI$|fR>$ICBZzuN96U(5N+R_pn( zpN?HK#jDU|0~5RWeu_ek@?=-^vVpjlar`g#N2l9w4LHf{m{hk&*ed3wmdIw=>5740 zTFkwl->Ou8(&8A>dz8q1MH9so?EeEF C(CK~v literal 0 HcmV?d00001 diff --git a/test_recorded_images/38.jpg b/test_recorded_images/38.jpg new file mode 100644 index 0000000000000000000000000000000000000000..182fa0246fb757c4c72bef0fd7496a2e23da3eba GIT binary patch literal 1971 zcmcgsZCDdm7QTEW0fG&PAn0loQ4|Uyh%6s6Ps>*krAv(SX$5-mJB-G zf@xuCWen=hnrUTie1Ja!rUl>tj){pafL(x1fz#e%QVjnI6H_yD8l6GC%cKgLZ75DN zGm42u(NNX7R34by($;R>^B&zUCW+ykxz0Pkbu{4-_Y39+|v4>?cw9juI?wYp5CV~`v(SJ4GoVd zRFmqde`=;@UjL$-Us!yjU&5DHpaNJJWkUeLfuP9A(16Yi2W3HUc}xa@T?FAJpDTqR zT&flmJN|{>qLpp>KN^ZYLGZ%?T*6a1Qh1E2?IaySxufXl_(okgqH>&1UdRz@2j|H? zO~#0%qW!_>v4`umK3Mx^zp+)X^t=q>T_s)xfodzJEDjRm;phB5UfuBTg*`VrF3QC} zL{^hhrPXa*sB?IO^6G5Ez6q;U2*J_Q<7;$>J-TlQm%5_PhL)(>57u_69qlK@O=a3h z-E|1m(ajfE5wfSlyZ@0h1gT_iW6Mk5z%PXkeU_Qqry>JWxn9ICUeR=pDHmhto$v(+ zEJGz&3zE7fV%6tF26dFu&b%!@`DIO^sh)E<1Qim`fUIMZ7DVeaiQ@4IJi?o&m8w6) zBdGQro5+FrAivr(WdE3}xOHw;qu!i|@HhEC|5TZeB#9M#((bPtNjr3;P=*Xk6fF=a zAkZBegFsd%>d07WRxbJFD$DytGf0|zn5Xt5cC*$(&>2iV+w4y@vwJmCqS^$3Ameus z2y?60y7`Wb-y6tu!GH0J`*#RhxO2}jwchnUM&8n~9*f5Bb~uYPfiYDsE>DtduPZe@ zH*@+v=iREafPk+fpK})@jb`V)3&FCp5J%bCK?p)iWysQ`9D*-){@<(I(pk8tL_2m@ zDXs3t%4Jsl&+5NRJA*N8=;+J+vvUeOgk`W1pSg}lT4*4cOrvBwXsAYJ3bGp^Fwa7Dd(qAvdHv$W z_k!XfDDaoyB1Bb+oRY6>sh~8G{zge0Vq?AHrfGxChYsk()eLfn5KoaSvdAm0#RwMR z_x2<4=FL%dh1zwC@onW0d{#v|`RKofpweI&X+U&Oscx^tp> ziha^b0mv*}N?-cEfjFcp(mB6h7#$^asbAI;ZL+$T4X7$sVqpFaokDa~q9AwC|>4~z5_$k5D@G6UF3Fbh#$NG;pc?pR^O;QAG52WJ-b!q zk$Lkr&uM>ddMP$dIJiCzh~U@mttmgAG}YW7*u`GmyHCRbUmL0_A`;plV2Lm;fzPsW zcP{xs70LFUkSyz7Ay}-0D2X6~)1~Nwx)zXm2!aD-q}32Lv2IVwsFV;pslStv(h|^- zdeeq?Fj31Oh`5>Vyle_Oj{-`-lOW(KTFLxVTv1a@*t(doL`+6}{_vs!rS!ceAO$rG zGLpFjf%8x&YlR$?EHV!egO!4vl>)b=B4p}hzhriWZLp48Ji@I&Fs@|Tp~Dd!(%*yN zn}j&cJqqy@p2fj5d^?noEUoU@U167e?zq!g`is!7to~8|U~BKhrSOyX zf9_<@d%sq`F|f!Y_Z7D~IUC=tB#OD#$n0t?<-3RbLadQ{XU(`H1SMtB5Y)|}i+i|z zNAixK(mz0O8ZA&ZUEoi+b1#nv-G9Z6Y#&HmKJ!REX6f+r*1&=D!(;p1RZl4h_ePv| zC&yIM@9BcKsabZfTZ@A|PP|ymKAW7~ay9<;HH$OTmss}I>NPBVY%@0aGfBe>)lomh zC)1yfeuTYg@(N5z39Qv}lJ}cT+e>H4V&c>Hl{L1k-FSEGrvUI{#kCdcx5^S2O3;}~ UDdpUuD5~Qc-Td4BDSkNeE1s?Mvj6}9 literal 0 HcmV?d00001 diff --git a/test_recorded_images/39.jpg b/test_recorded_images/39.jpg new file mode 100644 index 0000000000000000000000000000000000000000..db36935a21116aab476a2b0fef49a32ebfdf1cb8 GIT binary patch literal 1969 zcmcgsYg7|w8vYOxE};TN5pXq#AP8QNOIa>5$8u}D&{DZ57N%4oTy$B)3*7~#fJp;4qv3wtJ&EQNY9m026uvI10kSDidQE_f^I)Gd1oEGc!{&CWFa*dzo8WFwHH^ znM@0og{74-=sRncm9_B!{t8$YAP&TtnAic>1=ut=<1Hr5@SiYQWopJ?n$z#H=z=C& zn$y&jW@6AZbaf$}2WEDRcQ@_Y!?cf0HFwQj<6C^8%3|~T_dC{p+=sjQeRi_M(#m0- zqm#4y77x#@Uj6~^1^zxLI6NXUD*6M?-h*-R35kaeCmlVOmd?${%*s1;`pnt<&;L|< z?k{D$FVFM86<+-7rOQ{Yif&Zjy!AuP?H_+?c+l9?-176o*2kS)-A|-Xd!D`M9~gW& zG&~|#PO7HS0K;~ z&QpEroDoT7+s~s%TGwg(@V1SCV|t(Lq8xIYf~bZ-xd~U4hl+`)lYuAn&i~Twy54?P zCjNy}Lv<*uZW02m!yAlSZx{J}WUX8P4rPtMqdmC2`>J56Yu_ItE-2gf*LJBK*G`HX zFKam3OAx4Hn$GGG>S?=g|07oj(y5*Y%`XB%E(#p_EOXtbI3ek%5Bb_Bh8edC#myI; z2pt5L5fZ!^Nq;9=@Ap{_eH3A5k;~r#^QN%$9diT(m69F7c}FD8h{kUcBMv8VNnfs} zL-ipMO}FpZNDa(~2G$;@`o}!PEpxMK)y5Qrw;`zab44+dDwgvo`>)qi_Si_N6d9Jt zn<0=xpgk}KfwW%Kp0m=VSPCpuTv3qdnF*NdwbJ?`ODmDc95X#94&t4JLZTkYodB-QSc zLjCl5LEl&0s(K3ucv`9#UEmnaF4_jcva5i=*qT8IB7{<8X;KEkx1Rs^Dz9uCVuwUC zc3aU=(~Vz~TJ=A_|6|5+oMp?zUhJNolM~?-s~EpCnb>V(Lk97bvf_Z`Tups|-8U9)_SKNJ5AZr4Y%Kt+-Uunsoe5K^|b^J>te`gYAb7*hEDRwM9T2lgaa_FFnc; zJUa00N8-z!qwR{Y?-moAuR(CWnsV}6{0@Q}mXk8lt`~x?LD_2R8PeDl=5kMjenEN1 z?R#48mmvfoSGbhD^iuL|aX*&4%E& zhvrl`1kT9+E)hqh%qZzu-cVX9UglB(14Gjgkn4C|lsi7e3v)(z1>uD?SL;v5Zf$7G zZ&7Z~y?&GHw7W1{h)&R~%i5O+o**GFM3Z6J9hgp4i%ryF#_1~5N|jN0fW|~XARb=ezXpPuwW@=HAGLW*OSY1N`R*=-pV=F z9NeCM-IlvQMPp8qi8I|r`80G94U|NrLV(I!sNzgi)EFDNCN?q!my%z#o;6^!zEymR ze@7>!SW6JN4t3hBP=k^M)?RY(2H*1r-)pH1nM&)I%&xEv)`<)8XeEN9l4XZ>M{H=Z z4ubEK64iAyV&-hhw!x;k^_<_D7|rvivNK&8GU{U8=EoB*^3p(0*_n>x->eQ!NL%~o zPWHU-E5#dw4OQm7;#DtW6FU`TIckl}>Jwi^hE92$%8g)Vi*S+P0ql>kD@5xs8frO;qTbj9ZWv>JCD!%aXxK;Fs{)0_Qj-e}_ V_pk}!$F$yAWWihM=nmk>zX2B(?s5PC literal 0 HcmV?d00001 diff --git a/test_recorded_images/4.jpg b/test_recorded_images/4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5a37bef70c7a2159e665bb45ea56a80def866d96 GIT binary patch literal 1863 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 literal 0 HcmV?d00001 diff --git a/test_recorded_images/42.jpg b/test_recorded_images/42.jpg new file mode 100644 index 0000000000000000000000000000000000000000..45cd7290d2c79bdf5b4bb815f1a38a22f2a9f817 GIT binary patch literal 1951 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 h5|z>+I)iFP)rWX@;pj2XT@Za1)-~<2w literal 0 HcmV?d00001 diff --git a/test_recorded_images/45.jpg b/test_recorded_images/45.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc00964485eee29a3c4f7e5a2a141d49e7651e86 GIT binary patch literal 2034 zcmcgreK?#~7QbT5htc(w_)3^mganZU(^;b46<uY6 zXVMvlIw5yPOhY5x0sajz=^zqB>gkyR*acW*aDz87NrYcTZ;L*~fJ!6pGD(MK6B1Kj zpF}bsVMy;x(hex524-&`^rMGJZs^!{VnFTS@&4uO3_}Y`D{GtG zj!t{_I(xF;;r!Oi+dm*MDELT7=*h^aQ_(S}W6zzxkibh!x|sIyCs)!lu6~+xg;mve@BO8w_UmsNA2c<$v_5>)_N23``>C|2w{LLh#qdufqhoUA zlxq6#GqZF5c%@ldUU{uu#n#rL9ME;NApnnrAlG`c5uF?LNrT|VgcJhvVElk=u?T{o z4wVRZ`~|^;>$|icZRUQAU?;t~xSL`u=M3rFNmvAM$IHkuOq=C`hx)M{XJX?(a#jlNs=%rtP`<5J6!?g+pv#;~8#e!3K3LwKE)#tp zQbTko4DVtBjm2w}CpHcIb6~w(0Aen_d`ok3U-xanYFF5Y0foxPN9(&(R@c6VUM&d>CJi`3*?SwfxmLo+*CGr*s z|!w>`%Ns-kl83bSM`M-NPCmUmKl7)#{ zMMq7yx=d;~^t|Eg#1GU=6Dm6R?);)0^Cy_u>bj}uZewHID^DrQW}i)65VJk5w4E(_ z9&c1K9(IXlEl*uxuW2AKy1fyO4p1~af<6PmR3b^+(ajoU?s~=p2q=JW;Sw3v zQ{a(U1VC!hYVztgjrcKTuEzdwPI#EWp7Q z_(NcW{O=5rSlpbF>}A`W9MKw&V80ldg#fqA>mqimNAi4aki2XDnKie?pG53!e4Np$ z+?QH@muLNMW^$2w7PoME;vJk`BR*<|jmbN`e;#%MCv*CCjd#*n!w3Y(%nXB`>#@vDoS^R^SQCl(i< z_$4K$SSL9ak2+V?PB%CJ+KG!UWyuAH^7pw-X57o~3){+%D$MSn*!j_#-T8a!URps= zSQ-w2cn)1T$Q_9K4@i+E>7}1${v55fJmKeK=6b82S)B3nj@%Po6w_P5p`q4?P|*PExy^LrgCLY%(;Zy+K9w?+iUsipYMw)9PuY?ews!LM7E63kTy>_<9{ z*NI`t3NsWRuHx^h;ybVABGVU!B=hU6O{3_QC~h%V9fQb4ldX%km6+j(k|S_smkxgT z+Oqx3evj3|fvxoL*S1$U$3wBpy8A9a`Y@`9=jjzztq(DQN@f)^ZzR)}U2^(eYlXq~ zA13ZE*X_8^=&^F(_i1jRhMtH`(h%;dv3O9MR7k(qCVFqEy0v(>nOUC&=cDMvlXqqv hZl=m!NpW8nZ6Nu73TOm_y`KmYOZ!ML-4w&Ie*ub82&n)7 literal 0 HcmV?d00001 diff --git a/test_recorded_images/46.jpg b/test_recorded_images/46.jpg new file mode 100644 index 0000000000000000000000000000000000000000..01774a3c288b90afd228681a71cbe81d3f0d462c GIT binary patch literal 1949 zcmcgreN+=y7JqytKwtv}B4{xRDt;7Hkg_0UPRmCcQCwDP6e~HX5G=JRVhh~^%mQ7~ z#TRuNZ)f!m_V#x63|))(p8(4dB!MIw8+QOZ0G9@LSjD6({Ksr;?d%;GO!{9IozUb) z*R->vD>=|*=UfH<&O@>EeD$_5^Gq~_Vm81V#4eefk?!`BSoH$$Lw(kjjJ?xL+5z#TRalE(r`wk_&b69ZXX!6NZY3ZVj)9+=U`{?7G+)w^e z{OR9HB%ggQy(s_sAEjmgyrihEx%}PtwO6iQYrLguYHs=QcI$n0N9O}g*TYAB{Z9s- z4h{|L4CBU$Uni%g|MlE7H^1=v;u2wAhC1MAr40dO5(FhamPT}XC^8#@Pe(Nnc<{(w z+F3aSaqUJWx#c&6P%Qf|erPEOi+Ji2{v74>8;GOX@>s(&;<*)scL(zreak@$x9e4;NzQk6OhQpJH-vV$G&a4^rJr z^^;u{dA(nVs_GpfkeH|*;R4?(cEM{9nEhk~%AFa2AV#i1md3RZT-^G9&)S~JCW5e; z(JT7)+D^P&hlD4&qUZy>048rPEUJrHyZX#YSxLR1}58*VCuf2DRL z#dn<#$&dq(C11*1y4FY@FqD}5-YQOrmu+e=FOs)4^?i+~;V@=l{T-b^Of{5OCIpXf zGpT3@)*}DAKoXHMZJ=k_x42ko7Ez&32B#n(*GM|3&G?`sYAqtki_WjTRR2-pw#GZT zEr!6XipwIOH}W&(_!P+rxF5lj)a|)memr%esZqL(yRzr?$t3WNrKXaXd>aC`0vD3R z3ofxkNWEP{aYM&2v*{^-6Of7C|tjIYRTE48dG17dO{C zK%o7qftIETf(a>Nm``Crp!7WnfdkFQLr+vad3Oy2Q4t!-d61si?GMW6kPJ^-{7!tT zIifAS!cDY4Wrj(Tg6YnJTpGH721+JUArR_XsKV1ih3arcSxG<}eq%{$98fL9v#xBs z_~_WpmSA&LSFSO#HK=eLEty2W-n6% z*aB-GIZ!R#S}onaRDw*T^cO7VEP1BeT}3?x5xrPR}-$LuqLs^whs%-W?FDa!-{+ vXV(o~_V~cHY@L6OxA)joKp!SR4JKjZPK)Oe1m|Bx=RymjtcS8L6b}Czf4J)v literal 0 HcmV?d00001 diff --git a/test_recorded_images/47.jpg b/test_recorded_images/47.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ad1493fe537f79a1ab846f6bc46084652c260da GIT binary patch literal 1949 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 literal 0 HcmV?d00001 diff --git a/test_recorded_images/49.jpg b/test_recorded_images/49.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b5a99c6396b0127fe5f601cd09127ba378299a22 GIT binary patch literal 1948 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 dDBxT1HQ5JN7J+5Ejl;MA`@0+U{02E3z3Kn} literal 0 HcmV?d00001 diff --git a/test_recorded_images/50.jpg b/test_recorded_images/50.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f44d72fa1ce4e2ca75119251aaf9b39020bda9b GIT binary patch literal 1988 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 literal 0 HcmV?d00001 diff --git a/test_recorded_images/52.jpg b/test_recorded_images/52.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c7ce043b0f1104058338e8feeafa13752c4a9a4 GIT binary patch literal 1955 zcmcgrjaL&_7Jo>>w*~peQes8XB7&e8MatA7!CIACR1~*lMIZvFrYi{e(M&}e1YIMt zRuCnY6xm{JR76|_A_R%(;Y36YAB7OUf)vUGFigT^-ac&qggtxb%sVsZ-uJt|`@8qT z4%i1Aws1b<05dZH%+Ld1HwXvw%;s$FoHu6-^SP7BV3;#3m=+fAUQ25$3rlND3kxe- zD{GrMLtl2bHg7m zl!=Mbpy+RrA21d$9X|}*XyLSDzvbe8I0v09_|eMy)7uR$U$zlTR>vRCwzhF~bN5)d z)Mwf9k9^kzuVt@W9}>PPf)lyop<(UFn^E25)bv~Z3~4aJE?_k$8wRMI5C}a?ckq#p&@>2gdK3^iMN+Gjj6+NsOppQ}a-?Sd0J0Q5F%tMqDlf^`fxXSXMn1+Qak8hui zenRx#u9}TXFBPb3q$OvMX3?JM+F-4KVG`mgEOPrAKDq5LO7Re+bR)J9JZ5J?;8mYu zkd3PF-+E>Q{OzgNOcHFr_^g_!4gDMfyV==QSz6jbHtvHGWzrwjh0`DF&*F-whPt#F z!>=o7cb>il0?FTXO4=!tMQsy2q&x8%wp`RvDwi8`n=qTyV`XH1YSB37?D;~E9L_$x zWbu(HPGG69)|+N2W`pszB|4>vtb$-LAJb5HRgB3o3Q4CvgVCEM|F4jrf5G}5Kv0z- z!7apYjeO4)Q9;e+KUO{R`@{o+%`?)PRE<69Z`ml#<2r|8#4sy2jPdG-;!f?$)~+`h zQGq!@`@UXz*OQm5c&^eas36|>dI&Z-Jra=P7t%x+8;n3Fem z1T6MzE!zsrnxlH8y_L^&Y~lM&c{cOc`-fgoXuBu1Ua~EyrQgRwFzvq)g7XkGi^yG4 z2tFNT8SE*<@_+72j@BHPWg+^|?go={~& zpjGTaQX@4cBUpq%%7j39?l$U1^`8Sf6=w^9_=5w81zM>VXIws9>xOncL_yoAAh_V$ zdCHF(X?W&3>wXx{ zEXej1W-J;1!X@(K?|}U$%%J?`W%<4{LToUxUG}??WwMKz-o-7&2(HZFTJMgl^fw{6 z78^5s(|JdP^NyI>KnT43uOi^*5RAmj$|@-xB5s1 zsJ^!PMb|e0zxplOn{+O0XhCr}D?Z}b(wSWRK*H_fX?0$2*zuE2?v8xB*vi!dLv|4@ zi+CREq<%MIm%iK`+gd(0o+BJ(r=9z5)v|IyEd=s@SpwI%{1)C<_$AUbg*x%BGE^Mw F{4di&?B@Ug literal 0 HcmV?d00001 diff --git a/test_recorded_images/53.jpg b/test_recorded_images/53.jpg new file mode 100644 index 0000000000000000000000000000000000000000..37e7ea0aae45a213e029fdfaa30f5bb99368885b GIT binary patch literal 1962 zcmcgs3s)1@8a+S=;bB3ZV$s}+BEEP^shG>u3X$3>iy{T3np;tMEiXlohhnA$41(04 z)QVWiHEE?vX;eV00uh1)WpM*iZUU4?00~+s2?3mt$((y=`xCnQ&78Al*7?rf`|SC? zfl4?6>~^!?X9E)x08G#Y-~iYOOih+zX*OL7n%UB9PNSL8=;n0#@5929LAS89pwk)F z3`?t}KubQ^wOEtt==a6N8w~gN?lwDp)U8?TfA~bMrIoYG3fGnE zJl1<|*tj*|?Z9`o1?>z8W$y}me|O}*sE?y#_8*8la`aeyLSj-{`pJyUtn5>H`Db|r z=L(B1m40>k>nmkf%Y~wEzq?ua{jJ;gYHI85*FX5_VT-i&Nt>+w>9glOKllDmq3r8d zjgF1Km{3o?e5IY$&CM^oCiIK2A260|!vMJt0-me!9zLmLr9qHCD1*RZ7wIFPE`@;I zJSHGLe#40JMfZizjJ$M=hz#P8Uc-HPu_#wcIfrlt@PVN>wQNkaVm3~f!=LJ%rMf3l z`Xm*P9t^}jbeZzkJX#$%Xz)qqrjVP52@wRUw=~1&SptH6BJj9j<&4hvdQ+xc&=})K zN#DjaT}@jksje#*&yasoQDKiA%-D|aSBT)mvcoC)|@tSC(eK@ji_&i31iTX?6vo{)uL7H+WJ#c0_JVBG-(l zj__Wyxl{NdFlh@P6c63*&<66}Y%R1}w#|!mNv0l{Rj-!pMxXTT0SM;2c0f=9K^vcl z5<~FbI8$#+B9(vnT4JQ?w5R};SjHP~;4cJ(B9bG3Ky!%cKwOa?aw8I`RoZ0>6~`KT zLvB8s9v#lFYsHZ?^aN|42XLotig$ zLDYE4g$zz^#&u&q;3L(zehr_=O)@V#3KWBGfS=y1^F$cdzRZaJnFvJS-93CbdYe5rXzQjg*qq zr5H`0O9B#vMV`Weye~c>PYvAp5t}E;?;atPl`6(NpIUp0h1!pTr@* OUeC_c7 literal 0 HcmV?d00001 diff --git a/test_recorded_images/54.jpg b/test_recorded_images/54.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17a1b92a20b450ace73d9d5fb019a55d136cdeb1 GIT binary patch literal 1975 zcmcgsi&qm@9==EtURsc+C^{=3QhCU;6lIABM0|2AQb1147OgyTTGsLuDYFX*0+t}w zf>22%1zN3*3W6&_gdh<)oIokdYas+E0T)UF7$#&gcW>JL6ZY(H=H4@N?(crzcfa}l z29CffV0Mgklm+zk0MJ7hfa4$-Y|_((Zr-E|n!awP(`foM2A#q9eHa)SG7O9i7z{%b zLnC8dpr_3y#+!97@C7h21ZTh*J-w{}b^#25(|^ZA41a{)CVd*6VSx6UpoAx8h*Mu5 zG0_nX%Kiea1KL))`EJi3hQ;ZR4eT#jdj0*zT|^13b&9%Pc8g#2y#9Icm!W?SkBpAV zre|hdyjYYgqO3#M?u(aiPpG)n^^-0V2sp_j@zZ{! z4|a_yy9L2TQ#%Mc=~R(64+6`{1_%Pn)DS3%_KXb(4lYxe`@V)3*hu`0gxq6}Qb)9v zzSv@4k&rSE-$LZQKOwoHt!!~46d}oU%KjvMRDxL=%hhVctaWMJgUoK|WSZ}AgxM`}c(jlwRbF(<2*DCSfyv96chw9RM5 z;??$Pt1Qo&g69qtCf4}k1CC0GmS}`vwwNg+@x~~vc{s98TEe8l`2VkzAAV#`J%gYz zosTnkHl4|KF5zC?b$1(IxE`{FAZ%UG!jYL0?gpKLBDQ4!Q!$4X2GWMo#E+l<(l@q{ z9`2d%75k}MlU;nGxPMqKCcWa9{2>Ujc*!Fisv#)iQ?}l!Zy=~OnwF4T`yl8VK=$6& zoWcia%6Q6f4ua_fRQ)Hk4b1u6OymYF1y}muBBz`|-da#V3Dq26PLIk8B3wA?JZ#{j`*Sei3&KVai#{%h}_P^9DU-! z>HYSueYGcmUU&F}VDetC(yw4gSCR1+fA@fLv3z_*zDsxvebTFEAy{({f}jk7ZY~ii zfZ*^frZy#!%K!OVVub7pzYvvJ`aAF7zw(IT2sRG_#W~D^s1TjABNC{c$}Oszi)}+8 z^{Ld+6XU}EOL;4$ z{I)C`GLX}Oug?64Pd&iZ_FN)+I2QuBI2yT#4!RPGDbxZw1d`H6$ml13)Z*$n69{-a z&m#iVEj^aFXzsZUYU2Z9%6J%pa%Tt%`!e@a*=bzT3i;!B8UoWQ1)C)PjS((vD(wDt zHfhc5s2ID|RzC7ZU6mSi$MecVY*oqTTd6e&cBOrAx57a5AaEw+=x1|7zKmv}_ft-4 z^wRpbhtiw1J>@J`M`^v#E1|a7xwg1X##P&KUX9X}iIZ6>9M$=?1+nCuu+jYjs70t#~a+-)c>%0+)?_g4Y7V z6dn3($*afb=m%*mLE3cxsh1fH0L;u zC1t3xg1x_JmY-;jX$WeXi96_=T%9mmY9t6jHIS^@hx(*WiOe^O4X2I@e3XuXyYjkh z%7{~{H}Vt5E37S~hadGh#;9Wkj??1~{4H$#UL+^vS#fVnQ`?<~WfQF5F7-2LYl2}O cksY;I0zs&?DQTX>Cck8Jze4`#ZZ;hK4?pVk*Z=?k literal 0 HcmV?d00001 diff --git a/test_recorded_images/55.jpg b/test_recorded_images/55.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f788ab1cbf7407daeb4adb9a5f977d87d2fe351d GIT binary patch literal 1982 zcmcgs3tJOc8a_w}R||4S&{-}57DPZPRkKd55-wIL3y4ZJD^L-5Dz#iy%&dSQh{j8; zh)OD{vTA9nz``mJAzXE7xJU_5E&(LyLP-E&LMC(eVD~5Nv)?>(o|)%-^SVH0M5H~h8x3sps=<0se^J}lPuU|Gg zHvW1-KKbUYa&~V1-NGWNT7vyRZ`n2+P+<_{*l3;*lTua^1lfZv5SaN>o|5Tn5U}gV z_>}YSI9ashxbU?mCmAP0w{j?t;l8X$lq;q!cX0-YfgxKZ8<$znM$cvNrg~=S&WXf6 zQSr0tfyk#;Q=1ge*7^>rJrlTzl>0C#fIw!i7{0*blk9JNzf!NBne)0+mnPxY?)Rp} zAK{9Qx(&2gQ@9bA9U|gfC`ZvUd}2RWG7iB@<8qIwlQ#z!c(?8kxk(^MNR-Bo`cj** z^SJCf1V@eSAZXB`^E6oym=Bdgu>Gr7FqR8#1K zO||EVXw%@8WY))nk}I0RXH{eLDXRKS`*B(d!OxOBB>BrYzM_p^u6q%eVW{$`Zgps@ zV(4+XIykwQJ6t8aRd6z$wo8`#$hizn4iS%$dp9SNd;Tja3WE3nq!xlE-!ur;*2Swt zZ+nT~1{b-BdlSCb2=F8Pf?-7sYc~W&YPDy&oHh|nJ0qerdVTFq`p*jmM9T|RZPKFZ zCpX$UcA*Ud!C#dU+AIyD_HdukeMFV7m?te3i@mb|i7j zA!Uy3Rh(1fNMkK(AEMJqDbbMS5RB*JGKwgV(3l1z>xM7jbb#RhmGa<6eB>zv<*5RK z$+v1qv~vsgZoYT7{JHxlHV_0X3ab)i#-xXCgD{U{&cYQFSnhU4PfE*^npf@pZ&HK3 zvb`g}+E8H^8`sj&D{rB^W2d)3u*6PziM)kX(9uxgI)-(x~7oF;GfPYus<2bjFB+Tc8uADC5QN#heXtPLEz|d2Let9 z1d~ysl82NM6`+BjwNfFbMU{z~6ylMh8KVnjsDZpiS2Ksb#~+fOQl?FSK} zYl$#Dnr0u`MvLx3(9uNrg{#7mU0Iq3v>~^%ANyMw*DQTjeBg}pOvvfiPv-Dsr^v6f zXF__TljnuG%Lu~HyJ~Rt+Q54Qfn^!HmE#c?kLUdEMi}+i#Cdd9yV+h2%DQdJ^pBU< zxy13cD@gYNneGLa|AT;EAUJ*~EigyQuC@)beto9#PTwzHXTSJ0FU8`!^0?F6j@UoF k_}kd`M*43!LR>)#`>g1EcZ_s;B~q;xVeiEw{UX@+ANZH^ssI20 literal 0 HcmV?d00001 diff --git a/test_recorded_images/56.jpg b/test_recorded_images/56.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6adbe1228d973e9eea728301e512962b14f65cda GIT binary patch literal 1944 zcmcgsZB!Fi8oo#pz6AyOu;{FyNR51psgg2UC5o+ZETU9Tja4fG+s#@&RW@@31VPrQ ztP5gGDp6Ur8Wj{*J|YB(;^9O@B|sqrC_yVr5x2^Sxgkzl zTg1dfG${KoXdW=;G3PG{ThDUe_Klt2VUO_RXD`|Ne|D#3!IxdSr4jqS&vS6}^z!yu zxGZ3K;KwUgMXu(2vS#gujWN7Un`5^mY){;=GwG{c`wx73F!@kQYI;UyR(8&jqxl6V z3X4t_mz*p6+xfqjS6ry9mR!DawdNn!uHUV#yLZ3-!9O3i%G(~dE1o>M2;4VOp~{Ie z2zV_cVk+QYI9X}(pZ&9?FaswO*7B)fb#MM|lq;t_H}d<5{=tv*JY3^#*guskdiTme zcZ~^pWmOFi`gcF{dKaNlMTV* z=2WBXZ4dFwz2@Eo3bOqb0b8B5HS9=Eo!J)TeNIv*iDka_wh)=ph8P zSrURJ_G%UQvg5(ex@WUyVUw3zR~#dTv?Q8eRKrs8hn%g(+x zS@B^7;k&;Js`E`wQ9SR_DyZ<}i8T;xbbl-+{VzgLETMfOW`BU7+F@8p&Fh4qtqa+E z!5l|)G4#o_{TKwphfwu@VX48#^Ky_IjC4Z3ijW5gyT#M%xnDt$w?;-*;+ir%MQQp& z)k+9jeAU!e43$Ei*5VfLNerD9&;cUyfU+;0KDqo9uG_>x{j-xBWe%jf-N?Mw6rnA7 zb6bet%FgO9fK7Y+fOPQsGd-v9qqbs4mo>rMa|&(0LAzMC1^vIR95HO2L$z{(M&7r$`n@-#;IGhwMy85I$;uh;b$l-j$ zX-U&jFDg2%g_s)onHaiB82vs1u)B@zs(rpm9R_gc^`5Q*E`Sj)+ z3;C2M-csIozUiFmt+6s={f}YCZevq=zGQ)M1i_jiIGd&^vJk0i6Z48ND@WA&+BEn4 z<+t}~_KO*8;`0p={Yi11L1ni29vvO4>kpUaMZJ#k*cRiFIO$A0c~(R8OyeeR>G*XS zml%=}hM?R~2&5C}KwMWR?c5buT@qL=&Dl@$zK)`0mmqlln21UIZ`7$>R@eo{0trK|4^_0PyMB%+S|iTc3Zk+`);_z^^v(>lE=*#Uc`%A??2ES i*Lp1-mc`;4J^yZq#UlyV#a<%}k-}(X&WD?Tz5fO@)#wud literal 0 HcmV?d00001 diff --git a/test_recorded_images/57.jpg b/test_recorded_images/57.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9c62d988af8036544ab07c2a186fbd44a23db054 GIT binary patch literal 1933 zcmcgseNSaohoLt?ksN{`x>V$5%KRwh7$7F;N>OCX7V)Xj?g?B@8CGN1T3056Vas4KS*#b2or68g&cTkwvUjp~ zaI_kFb9Qocwtm3dz{wuOfEXK_Spc>G3?*m2$cYeMn#~Mb29srnVx5pfjVr>mwM9rw z1cSUkL;HX+i#dBi$U2tW_7ClRlifoL&(;Np!4^J=exr_W4 z2fV%{Y{g2>8>?2Y-w?^&xM}m2=$P0YaXa7JwJ%}+fy9GJ{FKzR^o-2IM{@Iy<`*0* zEGjAe^7L0{%FdQoO24~Mb@BU4KU}ZAQS)={&0lUcD_UCHly}K>!SCJbo?h+H z@W{ha-J{1(4C51%&!?tIqY3r`d#h|Xpkg4%_qJRo9;w4qAjs=iLg2QMTBaH+g@D^M zETR1W#L04#-_$3T{8XHbUd^L|G(EZT$X7voY~b|~eFLu=xVYA9eBVU2_}PPTx^q<6 zBd@5t*%yDy^VxEJ-F!~Jd6_^Yqyjah6awu6z2vCb~ll^j57mWoixp*5>Cl0HqMYEBs+ETUx zd)84Xr)NjaBy->BSDmty)zuEuN2r^RJ3gk>5L{IiBFg)dB>HwqwcQuE7DJWq?J`H- z(GOg!Hb`x%4AGcngB+bSc4- zcs2`t*ioTv7tUAT4t&!af=$!1T7lMu46+*&21-#G{hrL_0*sjnfZbQn@mvpOJX=|u9LHE$z2 z8HPmKeiVYCgQ)x8v0TI-4p;Z6JvSmx^F_Vu3{4go^+0J7^O8sa7v&pun>HWiFrYkN)k;GfrcHDOHUeo z?ga@CO$wrF_$7T++C!}5QBGyf;kB28iUKN&mQ3g4Bm2ALPfeJ`Ic_qRSApw!a-&D1 z7tuX+1%hvP#f`RbJUt$k4`dYIa^G9bjVX3bR-2+xY(S+fb05v!y@r;bhu~f-5gGe$ zT=<=l?%N~hWGS%m(8rqR78g37ZCWBzVPvp|I?i*(pPF}|@TKgD9acsGmj}F1F=w_x zAbUhihVVLLMX^NF2k2)*zL#foBT1 TN(`31i_VHqWn1gA-mvFyGacUh literal 0 HcmV?d00001 diff --git a/test_recorded_images/58.jpg b/test_recorded_images/58.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a00c012a26e4f2288d6e8208224a2ce6fffcbc36 GIT binary patch literal 1937 zcmcgs`&Sd!8a<5nZfEsS=+k^;A$Yf4WZ2y4%aM%52&RH|-d}r@{ z_I%$!6?_JqwsN;{0fPYm16=?PfK6Zy!y49kjy0Gz)|tg*+A!HHHv9G9*x9lu7mwt>kGUG9BjdMu${qh2CyAq2%PmA6EXZ5j5#(;7Mp|iI-rDFC&X!E zgP2%|24(*ntplbrYrz}Ak!+Xvy&Rvzt|7Pko!b{eFkyLFdDtdwzNHv{%*F zuN@kGJ~FBs8-HP#G`^aeo*_-Mupii3ZNmYz9Ri`J zc7@RLw{ZRA=GC;^QXYhBKOy)lDBl(g*U?7{bXCZj!cNz;^dG#KqN*PvC%NL+j zm8Cosd)ZaoLNAD$M;5$2s61;aZ>Srlk5YHXyFQ~;5d5SpMv@Qk#rjUMjPnJq#n8!< zd&~(B^y*tOb6jSXKvO5JEX~cKy)t#7IswxnBvLUlc3nET?Jr5m5Tp(uwGiA7%Z6Y{ zbE>K3MKAH|;EW(WHtk!B1m7zz)#w`|-iKhW*}Nu4M?1Al_#vWf`pu?I^t;oggyNy8 zDPzWTGk{*0GTjM*AEBm+5Z(qf)#1g;;&iZ(Ex98uhE{H3dZ zJS#4^Fl6_qt82Vc_=?B9It3MyG7%0zl*@fF>01dwv4r+qJN-2T)pkQl%DD@I_HJbF zMRP3C%`~LYwxbXX9YWRrf#oVbmY;*%U}g}8b%fkc&?9~o8SxPW`Qa^O1+G1h^Odtp zt5!kK>ZPH!VW<>pbQY&LcjDRUblOiu?pO9_&?i@%!u6ZOQ2!)GykqvKdz{GpHom}y zyb&Mdv#P851HkBr87S$mVcKj?75 z~O{h7qh8g0pGbA`6kKnPpuTq;^NU#z(sy zlVg)19>x!#eSrB6j) z`Kj{6!tKU}(e-;R&9+}M!VEuG7re)2adc9!^8m-t^- zFGL#4Vj+-@5wC)I-8%$1$TI6&BZ=}ej0kVfZc|s!JUTEc7>l{1wNp!Oc8rhn=D!AT`!&z|4(a;Y z;t$D&A&v96Y(O0~y`_5G`D4kq;mIQ-8yk;5UJ@`BL}PAd9|*dm(Z7{hQ3io;;_wI( JV7(Jz-yaTg-BADl literal 0 HcmV?d00001 diff --git a/test_recorded_images/59.jpg b/test_recorded_images/59.jpg new file mode 100644 index 0000000000000000000000000000000000000000..546af9664e0e11bf3f5d19dc95023b736d6429c6 GIT binary patch literal 1919 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 literal 0 HcmV?d00001 diff --git a/test_recorded_images/61.jpg b/test_recorded_images/61.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06dc81853011a47eb698f8b7744fd1eb492b07d8 GIT binary patch literal 1918 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 W(84f`T=7z7UMj zdtpBu1&-S}+c?0&0sss205}9Tg9R4zF+VPt4~FIZ$Yd}q87wA?_2IR$v1VD>Sg}~v zcGfnw^MStX?QHGmf8ax4XAR;(yoJSL0J{K&z?mN~5yKy0vA~kSWLcrLb||665ph~t zA|@uHLD|RAJYXzlF8MellI0Y;&&untbLh8Km#n=v-R^Mti$deGX8(~Q8(UX5caNnj zd{_E?vTE(RPuZV^t>3&QinBF(+xEElgk8H6_avnr`08NVq4bQb?4vokdB^gLOHP!Q zl~)MPp8Lo7@2YDq)HaBIynLnc>b2{4nwndFX}$Z;d!5p*?jG5r$4`Fk`|bI^l>GyP z>ap<`FDE9aUcJ`p^t12g-jfC+90b<$w&8$^hoIEMe219o56^<2WLO4)(^e{2K79@X zPRF>A@_mbwwMOr`Z_K6HI2pH|O9iS1ijz^Uly=?19U_KCKGJe&k4Rip?4^~W03$#5abIl}(hv~)%vaA!&xYky=9>Gh<8(fC_f_v->3#@)mRBIjU!@B*kA+QEf5+7rs(gQ+ zDejSG2o0ax>Wk!3zPdriiB9<|Q%6I@L*>ju!pDQm*}kkKTiz zDMv)Ggl?TYPyd+Ep39e-9GXs{WRQ;T~c=u#ki zFPL@`3Whd~ww{1s>=5eyFU*bjR8bysgONpO*Ah}+exGnQGJFpNMPU-M7FVCc)8)oL z)vt!2!&61=z)&kRPnsQLT#3=sJleOCJRl#;qRUsF#5G&l==|&s-(d2i`y9!l&UC&d zc{4W1YjtnK7r>$?W>`FO{i&8+`cYSf?ZU9Y@UybXA>HJ1$#%4*Cz2qT4UB}~33!0s>|QDf-d%*Y@C~fwmJjOAaSSR9<=1x8@e>K+xf0 z-Dy!39EyX1C{1Zb^J zQ`>UKW}H=a7dIJWLf@*tjHY@XdJGDjms>^3Q(EexoD*j3iAPTx3FRzqbQe!umxL3e z5<(YH7>u~5(fzxzS=^g6uc<+tmr8T?ZlEQXkkoD>D#4I|DlIl&qwV;LLF{ig`A&H{ z>7L`hGqD9P@96PtpX6^!W@448*|XxZ4+w&{5sQWjZP^R27Vg#Z%4Y|rXS@o06xrps sVxM{5KBBvnvT@46#aNBp7MQDusfG@;XFJe!RdqwF`(R9iz#k6$2Ro?ae*gdg literal 0 HcmV?d00001 diff --git a/test_recorded_images/64.jpg b/test_recorded_images/64.jpg new file mode 100644 index 0000000000000000000000000000000000000000..caf4a7bad77b3b0807813d25cd55747eab231794 GIT binary patch literal 1921 zcmcgsi&qm@9==Eto(js_BC`S_73HNgRar)>MCz&>7V!bAsbWRobW;U+2+eE(dFhJi zS`aF!q>7JfD&XQO5Fto>92!#U5?~<&l%SQ82f`$o%-tK?KcT0;Idjj zd!Yi30_Uxqk2%1~3IHqg05}9Tfq7Pzu#EF8!LYWBOa{Z6!D6yl?_L`_Tb7NT4U1*# zU~6Y@3H0UYVDD)8fe(R$E!YWmT3IawunS-aocRtDG5i`<^Q;+6mJM3#fD-OHBTj2; z#Kc52DEkXE4;TxXi}R654$;cZe7oc~8s1Ri3(JeSXE8=Q>(G z!5a|QJ-9cNbl>C6YRv;5_OK~5ozJ6IDoG&(s-+s`sYn6IImZ6Xw0K${cBwsECTQCe zPD?((HNEYtXo!)cfctyiQOp!7!qn0f~sS0y- z1oozUT=ZVv68sg6+d8RlXl4I_7~;gQ>alXMV*v>~Jxf=BFZ2z=Vp z4C2@Q#Q%op_`DtI-WSv(bhh_dPT+cwdEo;^)SpBmaS z<_x!kXwQ_{ClClf(aLC-Y>e8@e?SiqEo@1JqD~?)mUQ9v=_l&R^7QH{&grw~y^1(V zM6K^}JtwTLxYduwq^1Z$?yr@Z$tDP1l;bLjXxeRF6pO4=p2F!E;UAT9{X2a0J_Jo! zLV_jm=;V0^#fEoZx!m+{8}P}39OMQggV3%aBmw+B!OX_Uy$}?v6_Yi%>O7t*GybV= zB?KMbN@_cXTA^8Oc8+x?M$ho*fC}=EY%qf^U49DJY+Z{2@v4^13sJ9(?<=$@#GtB?Cu-)0>OIa;VY zBWye2K}Dr^5c=`&h|ybw!MB3U?=OHrE!~4$M1|_2F^xgQgg|!Y4l?@guf3?>?*M^d zNirfpr{#$&A(?3PK*xBUl(z4O;9MXCB|SMIbpG)Q$_@GB9|wU`jfP8+KVxJNmyWr) zm`l0i9aV!D+RiCn8)`B)UJA?m9@A^NLN~)Wf;B-2m>PfWF*NbwJ zY0kd&wD>Yo^@xa0FeIR&3eDGP2flm|`^PQ5OO8&m_ltn(xV)E*dOXuV>GPuLxc=nK z8BxhQgz{ga77XRvv*%yS->2o3&J0XV`{wz}GfQvB^?Khqrn|gpRf)Y)3a!bod@;hL2%&zMvT`x literal 0 HcmV?d00001 diff --git a/test_recorded_images/65.jpg b/test_recorded_images/65.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f4cb6c6a1e6a76f2368f345dbd136c6b5bd0b7a8 GIT binary patch literal 1939 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 literal 0 HcmV?d00001 diff --git a/test_recorded_images/67.jpg b/test_recorded_images/67.jpg new file mode 100644 index 0000000000000000000000000000000000000000..25cd19815a09980a95016d62effb033198cd486f GIT binary patch literal 2001 zcmcgsYgALm79J!CFD=L$i{>hd)F=o@@ew^zAwF)EMG-+=HB~7P(%wjUiZo}*Q$Xcm zy&@EHOBAnKjS5`6ydngN;GzMM5}*(Q6i}f}0P%#JoVi2WpZ(c&_pCE(X3d`cefv9m z4^+ZoV0D1Ap974H05C!WzyYuaEHPTN#d*o1(To>oI*n#bW6&9l-#!yFQ-+C|34>v3 zVQOZ+XlS+6!hGrC20j56rrI6AFZ z=epkQgAH4JKJ?wXZTlYo0M6ch`ws*k4mlDUcJ$ck@XsS6qj=G=aq$U>NoSMO(lau% zE@bBvUis$gKd%*CFD@6~xLI-Q-?#5Ps;sL1PtD{1);7ypp0>)LwY9(Ke%bS5ud=US zJu*7>^Z3N%tJm6@*}1p#?+D!j><6ZcvSENc3_+%o;SoNmWXD2~J}8I4W-qx}F?|IB zPSdD}bo~V*iWgkw&lob}Fd}$6mvmS4r5#7UGRoecJAe-iy|3k9YR8$=vnhE~Ju_6- zxS&s3R`+<|c&)>fx2A5D@1TA&Unn3qst7Rz>eU)mE?Y!!zViK2zv9Q8Gi32d4fM=dCAQq>JGN{X)eU1kWui-KWl8ADquCsTg7@Am9s>kt4q3 z7Ul&^eHDTTOJ@k0=~T8M4FcPtTM+EZ*Fm5q8WR^F*zqgHbl-662~!z4svy@{BUh!N z$cH)Aku9aH1D6qLTL%>dhN8NfQ7V~y{Ho(0loEmmiflyrbDl`kCaN^KgsGV*^HbgW z;Afhlhn4!kxH6%tMpAO|Y!c-hH{mlOq!}{tXeM!Ji-0)z2c=UGL=Pag5IprwgkV); zv`+fE7yoJSoltOy|1X0WJ1M%T($us64#85resj_UWhI?zv2Mv3uo%0uQdAqJ5 z_MPrNi*k&dZ-YSmnN~sBBr?f^!aAxCukn@TDa&NCg{&6LoS$4yHyVhzI2BH#zu^dcI;+3HW>p&!(Di@>niT__Nx4*}RYaysi z5aSGyL$kn{73kG^^SjC?8+SWFu%OBOh?C5`$ z5a^lib^OasRnCz-d1vp0ob-yE-Uflc%~KKKQUXD?m~!%-{}zIBvk?WkyaR%kE+p@D z{UN-Irj4Xb#~~PrLe>AV;TATTnuOG##p2p6xXe}9Et>OVAB7-wo0KTV)K@T`V&QLP z8zE?NR*?sps1&Lu3|4{m`0!-`<(fx?EBa%p3+r<+&0b&BKcVa$dN-=uib!qd35|(+ zK^|*1c9ee%j9LQ+B|~?fYkf1{Z^<@aw#}VgD4!UZnOG$~fPQJlF$m_|{UFGPpf!&O zkwEa#7*l6SB9?#o8829UPMn2GEaAQP@SjCQZ!lK`f#w9$hPWm>;Y>tPE49n!%OV&?pOxUixif7&4_Zi_HF=;cG z#SO_0_K0Eq7K70??t;r)&dQ%~okcS}^QKB;eOpQ)Lhd^=pAriX!_gb7iVF7_? z za7lZt>01BQhC=0QU2&XWspq)|%vmj0Y^NJVVf7Fc@YPucJX*CtzbTCF3a||dusbJX z&Un32y){@;nXH8k5(Sg+P?5RZrPv$&5eParv1X6txRvL)-5qj70j?c_Kr)HXd2+i# zgh?nNA)gnL8#qQ^0<0~f1_V?UZA8d6S^Kds*JGF~~jlcjEVD=!7FWYFd$y&@tdbSf8u0DDW)I+{yf;^uu5w5Yyq5Eu6S4=uv}EdT%j literal 0 HcmV?d00001 diff --git a/test_recorded_images/68.jpg b/test_recorded_images/68.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3765d64587d7f637dac308a783da88c6b1f912e3 GIT binary patch literal 2008 zcmcgs3s+ND7CuPATS49+5(^3x6a*9sGTvGgsZ(Sz_&}MGDr$sOse*uy=B@&Q1PY?V zfKW*#3M~|)0%GM6AxKacjYui4LI@}U3N;}JH{|A?IoSCLvu2-l&pLOVeZOz-Z|{9! zKO6;SdqO@90XjMW=%5AQ5C{e$Xt)2Y_ z7gx6r-M4J@^ZzIyFnH&#klmr5?up#D|G>ehLx*FJ9Y4W385f_JbS^n1_56kOjLVr> zSF*X+uK%m>-$lhYO3L}S?^IO&@MG13+PeCO4Uc|)+$L&&+9B?I_WV`Puf4zZ^$!fn z#>QX2nUGITO)KYA^Y0cG3H1^j1P05pVSwBRL8hJd0Y2Fuln6n_uowc1-Q;G;>~#o2 zTE}^$%byrgvgEw*l{Pa8BO(Ktq^EQsJsSCnDC?cfA$(|LjWPt2+0MnPF6Gbk&QaYH z2?N5i#z#ZZk8Ngr6^)Mm!7Ecp<;EV#GrN0Xw0eHRexl zVO+svg%F%Db%3CaPGxJ;A+Q{&gkbwsH3UkcC1nYMZEq=tr+eiSMn7v@LT)feuKn8L zt&EwjY$0VHzLH4)XjoF9EpBWWr!J6>rn*j3{Se%fWTTLe$MF=;c(wZ9VloEG{AiCR zvQsf~zg82TRK}4u2ugF$r&10{@~v_XO`D0wGl;!g5{R(>hIABy_#qT61W)}_AaHDn zR|}{6@ZX0QISG5&-)s5U5nirT(G>J|2uw7Z&8c$AOgQU;h*GEzn}eypE#%_j=j!If zMfF_|%9ge83Y;vX;V$D{(d%aSkC2Apf&BbISUVBh$9*(4w=3rDP|NrIk<4@S=V+d-K z`M4g>rY*t2BiyIs&aK)f8$Y&#AaqgCz?PX3p89QqY^G%prkG%4ZKw5~6F+GBwQF!H zIovzLC;HT;ItNyq_+_75O!}~910dLG@svk6mqL)ur|f(ezJs9La7;q3?t-Ab8_9b^ zvls8CDOr@k1O#IzQTKnQt;8nNQjr?8L|nNA7rAhHc=J1g4ndF>AS6mK*>x;Vvb3&j zBLuAuQZkHzTA@y^H4C@KNAnUWmwe)wWH6Ds;+lggcKf6GIT*A}<3{zE5ov9499^O& z!pmu6SNUf^rz3n=FjDnG>7Ti#J=!Oqx;OkzDZIv3KtTYl#gI(6b5tZR=Mpn-32(U#`hG6SY0RqO-^MuHG@PGwE}A z{N@Wbi@Xrjpmjd7ruGU|iini~XJU8!EwrE~eD71C#Y1O%of3MNVX!5}=CRA{w5 zleETKiv|muuk}x>OOkfn^uBnHp;9vWR_bvCtAU_^Ez8p4@zN#w9Zr1rF3X5rRu@H# zIiD%%JFO{|>9OQ4kT3`@DVf7G!T!)3fZ*jO57hy#TRGRQdc+n16zzpTFp1B5GrRY5 zQc*%26#il22n5W*2I`wQW=UPdGH#4QOy)jL(c-}n+~QK)YL%EWUWCA@Ph`48^$O>W z_mI8iT=$NG>iED_HSD`_HevMP!nSaBV61m%u3Z%C(K>tHQ%9HInvRdHkyxeXO|e>p zH!B)%tP2(WJe~Z#k?>c)&FR3I(`AKTAU9;f&PhFAkl8;LG|~ zb;jpsd*ok~el9=oWyPzrd|JUTzW;pNp5vA2XFvZH>DpKS?d~wYs^h%qdwGLL{3d?C z6`Mj&o>?akaLx1JmDijsia5mfE2@2HzUGJFUjo6Cvce@5sux#VfKQgUqN<0XA6`MV Na_+sfS2}b|` literal 0 HcmV?d00001 diff --git a/test_recorded_images/69.jpg b/test_recorded_images/69.jpg new file mode 100644 index 0000000000000000000000000000000000000000..033c04215fb6e2ede4a7534b4e4fdd3fecf4b725 GIT binary patch literal 1980 zcmcgr3s)1@7CuN4o)#43VbQq-L@LTlk)o8jREUpT&_Ne~BVZp`qq7>T>zdVI=&r6z21A#@VzO9o9z6qnmY#tgi=}U* zZ(z6@=*`&3(0KI&J_JVk;3zn%qq7dc4uBzW<{M1J@O$X2(Pc1MdgxyxlyJ`!aq8+K zCMKdm*)U;Bw{62my$buCCqK_HFto6=vfjAG zVXNc2+je>E_I%H4&ptnY_WlD04+R|!4mlQjJS;Nm)amFmF|i4WNy#ax=hHH?E@tOk z%FQb&{if{O@`@{!)%+i7Zq)wk=8yHlhI{{Ry#I4kySU>~r=;uglVAFt_5XKZaA;UQ zG5P$()bz~DSIPy|;_IblQoRC)f&Qv(IG~O~kZrB4CuRn{6ClVMl|W#&pK_JXl|sO7 zo8(ar|HsM76}zR+wAqO`8MKE(Im?DJ!%?o7w(#SO5F=x6E7`c*Y9Uf}p=h>$f$p7( z9}-nPxIYr!WI4N2@nEy(sKzyp8&7SQk$ec`?vjq@tE?^;u&yp~XR zTD%)qJZ;@Ui?tOlxcp-xW-DbUT7{1v=1QMK&}|}go;`nMbgAg-jWH)F1aa|$(G#B3 zF6-Uu z;;L%xcI|85Pzfn`BsoZN(T)@v8!a?HJP#T1s~!{|?v)Hgrt8Ge}@ z;Fjec{^^beo9GzH(}8IT-e{x9IDA9D)ol5m|}LOYs=#%HOKC zL(pa;qYh)J6&j|srU4ejcws#4P((&ahZE>aTk~_vNKL@o~@>_2aFL>lY5QhhWA_6lb%f%5k6U)K z8&BpYWLft*lZ&rKy?!m&L~enAnM?A2u=u6bHEgKmVqMm`P@ke3U41)mv!YziWiAx* zThc5kpSU(cHTe@UUPq{Hi^vND84yfMLXnH8&;@@?p%yS9kQUxWM&J9r7gZ5P5b!od zA_6omkIf13RI?=-<2@4EZ~%f5M+kCyQeEf^Nk!BK)+}K`!^FaR%>0)fb z{iW=+)`ZS>TG=L$Vx)_V%I6s4ziL7tc)G($6_V#zo#%LK%nAXNAAvwHLoB*+dV{&C zs30zqA4Z;lfHT}ke-*>2YzSP%jZjFaf~FKLu@8dld34?_m4r50hQM|}Y_dZ4ix!Oz zQT+(DE?s6ilfqqFub7Q67H0mlp{e9xQde#He}4YD$!{jK_DPy6n9Qu~surY1((I4- z(xU4~)FZ+_SRIUN%GBPZjkvwT*q3!&v(yFg@h=?a1JhsBtMEko@Xxa50|z1#7X>*; z|DucT46j}*yI6PD$2L{d84}hVuQ_$Q?E7%(S>9g8@cbU(sokYzR`!MGDqm1UjDqg& zDDhQvAMbZrEZ%5!+auq;@mj0TCxM$Df<>>XyJv2NZFv?F)>AV(mzDj>GokQH*R3_& dW(dR+qA1Ra;~iqW^dsa=EOh~u`R0a0zX3!907U=* literal 0 HcmV?d00001 diff --git a/test_recorded_images/7.jpg b/test_recorded_images/7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..38ea49bbba8a1e556d466f0e7db448eaddd18706 GIT binary patch literal 1916 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 O)>(uZoHN`aIPxFQZTfZq literal 0 HcmV?d00001 diff --git a/test_recorded_images/71.jpg b/test_recorded_images/71.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44671ddb6a0e439d89e28cc246064c3ecc43fcc4 GIT binary patch literal 1982 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 F{SWwk2K@j4 literal 0 HcmV?d00001 diff --git a/test_recorded_images/73.jpg b/test_recorded_images/73.jpg new file mode 100644 index 0000000000000000000000000000000000000000..afcee572ffe8b4427626b2e88ef41271582c5d85 GIT binary patch literal 2007 zcmcgr3tJOc8a_b6-GYK33T6dGDhP5bVkuLVTWN)dMFC+;Rz(q5MdcDin^^(5*9fi) zLM1DyXsa|T(pV7?f<*9PBT$wQ7D9k>6KcYBLMC(e(C$yzXTO;_&&+eadEfVY&-XzI z908`m0iOi`EiC}F&;{TiI0&@0)?#hdUJIJe+DfOx_Ey`vuqAO)N3DG0Ke+ zeuOFBHtnW_nsOIR{w1EUleBAIgHM*S#p4jXF{yK&y?ASAnNwLa>?npHDOnOf>P31m z@-g{M2u_(;L(od63N+aem=E8B!1uZe0wvMJT7}@__Y}i<*S(hvN&J|Y+_3?rN;Ku3 zjM=V&W@KWt}?dImxDJa`8k45#o_d9Qv=M;}9ecBDD~_@?t@-wJA~6 zJkyW=duWB79Fp`84G%lUEtV->_#ki-# z1TEGw@(=^H!qZ8OX{ZH0axIy%=MZsXX$qCUvj|fJdZGD=^!ZrrK=qmuS*;0d9ileO z#n!2-`U{}d9y-Jy{{D^9D|bs#4^l?GGVMWahkGGu3N4;)!64( z(>XUP%c*ZqFZm{JX^C$`?0|q?K=8h`=xN#$J>)lquo#O3}h2qr~Q$VF7>ygx&s;?p4zUwe#?QiTr|M3m7A1h)M`lU1s(dC@4C z>_e#4g}YXAvGJ3=&F@wj8so^tBg~sjMHD9GjtJ&#?huCkaxadPXIanLCCjE57x$F| z{sR4wC7X1w&|u<1qghMz&RGFVUKGR0--;=3S3T;Ko%ykc#F9PqS+^T(CL@x|61;Uv z{V!B~Qm?S#7Ssrcqz5xB>8F14&S{rCveM7+&cy|u1An<9wtalRx^`;wueI{8(%-a6 z=?hZXbpQFGqkj^8-F;|_UZB<3w!dOmUGmd3;jf~X-WSw&^u!DunEAZuC%Y@Q5hap3 z(|qmw9X<{qUAwaSOaGG(rLq5%1fAuv_D<<&XGXpglfI72{%9(T^e6*Q7b<`+>RdAx I-F!IkAG;d|1^@s6 literal 0 HcmV?d00001 diff --git a/test_recorded_images/74.jpg b/test_recorded_images/74.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d28dae37441feb1b2f52dbd8cd57df5ce5d65cd3 GIT binary patch literal 1985 zcmcgr30D(Y7Jf()!eWDfEDF{LiYS|GomP=jk*G{dhQWoFGo%$2Ax9aT)umI@fI*NE zfpI|WCL?hf+g4PdQ4t~piRj@(pfhX@A%K7gW5QY?m3s5A=O@gW`%b-6@4Q>z_ua4V zgPGe)l z#6&bG`&)Dm7|WQ}t9`e#Y$6VuxSY22`>x;y+jYmIhUI^3)2#77@=b=RnVr3Z)h9G2nhU~^TnpkAv;64yLRshi`=*Wz`>}m4#gflc0BGxd_q!kN@`mAnX{Q$7ev_? zb8-ud{&w~6#U7%jk2bf&GJ_*uiHC*QU0s5tGh=% zI5hljWOVHPxOQrKW_E6#)Gfdsz+SWs2h=_YM2?2X#8_8Q5(HU&atLg8Q5zMLMG$Zs zhQyTHzj3m3!FBG>22nCjMsDU)-m31*Xp}3X?RN5eiQfK|S}v}3n2Mb~pFg3TqT5Ci zyQO8dPkN)D*-!XuYFBak^cw}jM9Nb|N+3|L)~GH8iAnA^oRj($AE$kPs83Uf>!SQ< z+2^?CZM_#QGnDw?>OT?j>nK<0B79xvsvP;0GGYL}rT z5SwVtk%ah^)^Jm~ijSm^Z|(?@A5>7*MXN~71;h0t5)@(B5BU0u?= z?tusG5I5HXf#hqgg0@M+sJ+5kx|^us$nv|&WU__qCfrPLww%lrluUB-t`s?DaifXr zE-BMo-!jp2R~nP+1BtdZT7`kEgkU%qS5rjgL4!39S*N;$)4L`Auavt#;RDYgs7#d* zEU|rKqLT;Duld%E$`_v793j{}Ur{4aTaw-;jTJe3+aO#sf@KFYlqvGZ&wpv{d7sMj z&GL&r=~d+v7cYO?IVz|8;wCpiu+!$Hm~_1kL5_rW^q>14f^ySA1+}adf~GcP?=^im z(ZPteZVrE_J+>y$fh zzn&aaWmPw)7JPqncDBNqTnhm+hm_p3Yp>sUsJrgM{jAeb!TGmeb@)GE9rZb#Idxf5 zch;T?7BmpkLq8D%_X(X#K6$<~1Ax7`t9fIuEbRYVBNsIW>xK}l9)bdaI@>@bs1}&Fgb8h-wh^Jr&&jYU zzxS$HgC#BUSlCdZz(^kzb%}3*f6yO*;H{U(^nqOW@?7_O{SFAAI2?kCF=ED--?m?v zjtUYY`G?5E5b%3y=;oK!iYWBbUy-H!Y{l=OJ+Elvys&O6iPw z7^Ot0<+&T?MfmWs4(W#l%wTbFWzQ{*zF=Iq z`t3)`_12hOzeQ!W^kHFa(*2O2`jb;zPK6ej+cN#O9Rme_Ny<}tS&w^o9dDmYZ460S l`Bc8m!KPgrL#Va<$36zzC|tAWE-@7-4E|&a0w!She*jck_UZrt literal 0 HcmV?d00001 diff --git a/test_recorded_images/75.jpg b/test_recorded_images/75.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9fdd1ff3998e7f1f33779a4a739dea6ae8226bfd GIT binary patch literal 1945 zcmcgr3tJOc8a_xa+!Pe#V$rdnKt;JJQZ4J0sz_;thvKccHLIcsY&UB`E=n_7z#x|e zg|#3SQc00kt5FegOj%oHq~G+KR)q=5jbz zwpP|Q=0I9$KXYaoK2R@BE8h`9~!imJBl+;sc=^2@)b8^oL z^UmcLl$QPN;@9OBmnv(--_>5N`~HV(ck1sp+-to5_Xq8=j?OOmqwdE)_dV_Z*MM?x zNHaD*@yq1Yv*#~#v--K$^9!WG2#0``*)|+ddms?H(RYYv%Fq-Da#eB&9CuLxikUJ9 z!rR70l-GZ7veM`||7Tj5ij%Qhd6b`eFy|o3l`+mcc*Df-$XmK_T;n=>RG(Ec-9O9p zPVxt()lK(@4?b|2-l%O_6{0c)Bn$Y|dNnDAK=Za%T^K4N!@mgm+_d7AKCr4aT_I{Y z5X8tf!8yFc~;g4%RBNDwSPpKK6KO|60K=6}&z29`^CDnY%<*OsU3J8+<%7n2H zY7=%2*Ib0)xV<|B?QABW&Vj&bqz-~@=M50($kuct1n<3KFu!$m4>4uJxPn@{45cdR ziePNICtu1ei(X9TysJ`Npevdh$C=aA{pUS@Vw4cvQskqOk0pw<-J*K#UvUkFlppCc z#Xi!G+^#o8r&bHpjgrennHh|G>QwNQfJF<5B#eyO#3y(Ex1=KwBn_i#A?OTAhhSA} zl0o`nfcUp+LBNkn{+1TwhebtdZFA^H5ZIYa0U1+_gLK9V5v4Qlv}|X7H(x}^9~)Xy z77RCi8P|mQZV1GG&?y+lbd1_9XkrG5#t>PFvRWoH=5^pU$){_`g5-*s@S^i&Zn@zH ziOU|R^x=Wk!e&nflbeEx-ZeS}P1Zv&QGjbGqJBTUEE-v-F2tD#@&7C3had6L2N2Y! zi3yI#rJe8Y8y(bDd!_#2`uE)+h**#`CTr|TKW@7upXU^cYbUY1ZLI!N@;l8>dxoB; zMF-{v9sGR5UH61U`ICVuITe&Jvju`3j-4XX^D+eaV#aOb{5KHPSdS^Fr9BXI^dfsN znWBhZmM(#@nuK8N1nT~e={o#bb_Q~Tl|tw?5i&19pJ*;D^iv43w@ArKTvLW8DvYbE z*F(_euBLWls1@!`(GJnh#Aq>}@hTzX6+DX1DV~PD6k}N z#Q1xx@2UA1Sae0JBqP^;(uD}$>d3cQyu~lHR6aF4JGDw0iGJzXI0)wa!XP*gL01X6 zR|3HY6PUrCLRJ3H?-FA*XT*7^#nP56A$}2&1F<|21lmKGBUvsxi;@imRhTnQof5;XB z(aNKU08LA`6Cs;yc0psjRnFK9Kv3!fL0(UWKa+K;gj$aLSrY?+eWjL1kuNdQm&Zh0 zU%{iC@wW1zi!G(f7lz8zu&Tf_w=lhqCthwCN3bRcE+lL6Xd+2%WY-FkdUra->|B0E zhRp^&SHGt18KJLnokW3={%Wd_XNSKu?StUS24DTY0-u@!pX(#82%tO)0?9LCE|Ax| zSCD}O2~hcQlDY&keGqwv5cnrwwjZD9E z&NhlTFg#IZi`aweuw+!(Y#U7fLx4B+ufDfAh%Wxj%SYAuPwv+%e_zy<$>n;kE}FX* xxAy72xSrbSnOxzEkd)%T1bEj9njw&lN#l7&pIgLe*(XSN5|#Bv1Cjv;e+9n><@o>r literal 0 HcmV?d00001 diff --git a/test_recorded_images/76.jpg b/test_recorded_images/76.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fc8954d0c67bab0238cdefa13f04176246442b38 GIT binary patch literal 1919 zcmcgri&qm@8ox*qo)#43VUcM;kphA|6tUE)Rim}lEX7yltf|lN*e+{9z{h4z0l^?^ zL~6mFBEHSihm+{t~P3mhB(a6k*dVXy@(aa)F0S@KZ|-ic?)C$01#Zq@57^`2umr#kfFW@9Zw1@>#x%tBEnBy7x9@m=XY!uC`}QCB_~6lF$4>}S)6%oDPvzw1ojy}g zc)qCkf~e$5`4?Betf;&usg`|HQ(O1#cQ^0XH$3>E@!>xnwJSS1yHwphPk!qEdElRe znjx)zY<%LENyGCOFHJM%*}3@z(qe^L;B2=I2h<)2iu~#O#B)tz76gSODhRx`Q)|`J zV z+I%2}QLe|0Pg~Y7O1d%%*Z+}7TTKNk?C_adp?U&>A3f?Lr%qoRnHOKL9Sv7Qkddho zjKx!N*acjF6@n8U0T8sa84+Cof%j+~1e-2fATW_FxmF0?{*}QZ!|GZwjbL0&ty+pw zHFV`VY^qnJV3zV0lLZ?_)Ma#KQ{y;uhI;s-_s@(5g74KLRPymOsj){|@ANlZk0Iqp z`fbVG#?gEAHePm>P}eBGUV1u@3CK3AGYDC95s{9OyW=v+UH>iV2n6ZFs9Fd*<8vVh zY)Q8$UJerf8d(r#?#}o-EyE8>OLfM_i621VZnLe;GccZt=@3Me%e>XRg?VSblu$jf zG-oYX?uIjdg83c@WS^MSj8`s3?GiRILqub|Qmm;`Dy_vGxNF9lYO*Awa++Iux!k{y zn?hU-r!kCm#*E9qO(o|0e4Js-|Fr5IwRl$ybo8AYh9~**88vwX8ij)O`L<;mHG=#I@c1v3EJgqD~gf zT#_}P@ufCpv=Qd<+r+awge6E!o*T@Ez@R#STtq@=wqZt#oDG5c(miDKgWr46e8>#~ z>58L>08LAeH=&$-?2E>Dql$4Igy2dj1jW61QOvnhVrm)kXJrxu9ugy;B41%-IG@>Z zYdN3t!P_ddSDUYBURosCo4<}e`#okh@ny>_;|SIUL0N{rm?qM7R(6dry>FX$(za!1 zmDo(o3*8*;!4!pC!{lm=jM7mT`R@2D+dc@Mt_e5qD+#SG3B5JyhX5*eLm+=n%trJ3 z_6qZmAR#LMAbA)9zP6G1JdH1DNV4M|GODQ3N4Yey1%ewTOvx>?ig8JQ@bQbD4@&oIUpN%*ZFEZ(T)6$+zF>ua+6%W?yoWXeB@0yl&mz1ov7 z_3qfiCw2vQMALC%ce1wk_PHd%&Ed|KvG0t05nCPg#{DI6slydFT7#cTXk>nIr?6Ww WoAe1%7g7U3_W)_JOR~EKhyDYL+}#8K literal 0 HcmV?d00001 diff --git a/test_recorded_images/77.jpg b/test_recorded_images/77.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/78.jpg b/test_recorded_images/78.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/79.jpg b/test_recorded_images/79.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/8.jpg b/test_recorded_images/8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2391d8db57cbec18a0a97d7991b48591e2b0a446 GIT binary patch literal 1912 zcmcgrYgiLk8a~_-AhwFbSDqG4P9MC=YhMw$6N1gevc85mcWA2Y+PazH<|Z-%Fey%`}Xq>9LzX+EIUV-d;G(KQy+g)c>2tz zWuKiZ7k_?U^0n-nKUG}%bEUjadF8vm)L;GnTH~!Ib#u$@);kZ{J31d~yBY`${A3v&`{!%hh{WCIg+wHN3e-}y(yKE?kd2U z_7GwU0IAgIBj;tCF7&4@L67$pv72+1u% zYn%B4f=7=Z+(f;YjE`yfh|&*5Dq1GSE#~E!h&VL%*%@OAlBF<+semt+Q32>cnHK5C z49yT2Ah7Kjf=lN!-)9aNs=zi1`+D+JAgiD$Uk9{B@K)!KX?$X{O7gvl-2)07br53~F$ zjFztIv)x|^YgL{Qh;7s}!E}mK?Bewh%!Ww`lx^*WAW5c0W`=bTe7*YrUbQyQmx#iw zLsyM$^__T?)?5Gd=J&ZD;VeG}+Vk%Cgn>w;SS9%NVScBtFBvN~=}I_<^Q|gQ^e1-? z%bsTWR1EGq!3;6vPjhB%5cpKir=s2NHX-F{fnYe7rfs*Q9vLe=eG3Bj0@St@ZC_Qa zS4_Vbe-MJwSd5S(CK+;EH@BjO=A`XyBe{o-KT&|t^?Bq4 z1n0#p9Fi@<30khCfKCMwUIoE(X_5jU$1_YB_Ha@HJ zfI#=vO^eGYad>sQ&K$J{+;Mp zbDSop+E2JU)5;`C{#a-6X&Sni2Ff6^AP^W@sFLFXxw>9C{%NYB_O)Rj1m`AHLaa2R z5v$-ITpyavk19!Bc9O9p*uT81EwGZiIE|Z$YsoL}6gp5^h*}9Hxjv<(SThiW^|kxX zQN7qSYbV)TCs|!5SvymXjAZMv@j14`hd;efP=nwCY&J*}jP}`YKyW#OZ@EDuE>7d$ z+YCW?R5d-+a|p(cV0G6>+P$R?2)fjGJB6u54%Z%xle>U>-z1$4IrV0a5<`#}=m_Nh z#3zG%?e)Zld0uX@tD4wjezGWgy6QgnO~sR^j^`IoJP5eYJN%`-NAvaqz`EPS_7nK( ze{8F@6?SUE^}?2W=dChsPgpDOS0_84JU(~E?Q%T-wSY`mXXnx`zQClsI2);CmG&{c KE$6L*1OEoiWY*OH literal 0 HcmV?d00001 diff --git a/test_recorded_images/80.jpg b/test_recorded_images/80.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/81.jpg b/test_recorded_images/81.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/82.jpg b/test_recorded_images/82.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af8c7319faaabc5ccb4022f828bddc53c24056c0 GIT binary patch literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY literal 0 HcmV?d00001 diff --git a/test_recorded_images/9.jpg b/test_recorded_images/9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2be5ffec9fbbae543da553e8263d253b6c4d260e GIT binary patch literal 1929 zcmcgsdt4J&7QQ@^@UlQbUadw^0Ywpc$nuccmPblex>P{L!YtJi1lugd2VEhvfJ<7m zO>L|$v5-Y{p~^OhfDc%*$RprNv%CbtLP){_*07xb!h}rb?!^6f|J>i6J9B?`e&^ip zJNG+hE*yi?!0Fxigm_?K0e}TP0Gt3Zz|z8O=GoG0)>h`3VQp@UOt$1|)-I3kzoey8xR8XS~9s8UAAymR8mbCX3!{PX{zR z(VSLRG!uiSp`(jvKd^RYyuNwQTTGXvOqO?^Yf$m!YMU)@-|blc{s6u;_`^?2Z0+3K zJv_a(`S|*6-w_hJH|!VT5izlG@tk)O-aV9@l6v^a(X`_yKFZ=|pUlZWedg@Bg3o?i zdg1qFg3rGw|3-A>+pE|9P$9libMw}pYU{qg-FUC5x#j+YhmRh2c6Im2d;6XY4h@ey z8yy>0sx{h~f6mU$KmSR;xU~FoWtA|jK_##;%Z30l8Gfv{FFi)bc2aJ!=ma(~^@ctkQF|;NUn&&p zMi!}oS>Cv;s`bIdu}AK@V7zr>*rYKqm(L@2s)!m0)SGeD#V838|7qCAMz5cj_Eff? zQ%L@jP)l{F>~0c5z1vHSD|L?hV_dyb2#(}Tt}7T9f%-13$9j#V z>6$J4YhegkVW;~YZ(lUydrcPu+7^xlMtDO29iGoCNh&PQJl5n zNi0EN8!N+GkgRnaWAKMO`Y57K{-z(p@@KHDfCU1ADp^28{xMk#q6^kw#L+Y^8N}6f zXx}3^bow4m)bL_dSp6w#Xwp}5f8oWfc4G!2*bv_TnW`Aclqdz1%a?CZF4%af92t`- zTOd$Epg%YXfm|wX=dCrXR>O)^*N4RONVZ~(s|_P}JH8Gq46ZexN>y#a!9 z-mf4K7S*uzi|xD*OjK_9f2kGv0|YJTLO-ru@om7VYQ5uQ@l;*Aw|F)(sb=feo=oSf zs@dMk!huWNYN-tb0zK7_E+?3a&EE-u!COdRY~2V1u_8ILs!>4jjo<%0YDcak5g^k| z)~PybyYcICyP>Cdzt28}+dDC_!F?|lltc_=UyR?;9PV~>B*O)2MR90)o=zGXeD+bg z=xL_I)rtKdvpkh~%b^B61P&F(L~OuX&!uc;A<$&gvK=thBJ(8$_aLy&$Mhjsrw@Nf zviw%mQ3y)HWrP?}i;$CwwM|vDCLM38$b)RWPtr7Ja(d4VoBoPN`3Q*<3S~a^x$i{; z=Y+lbNrJcwbh%<(x+TPx>kxcVLwN?TdQtG@{%dRo(brJxb0PTq zLlzYSffw?>b0iZP^J==6HYW;j9Xc&D=$|2Ys*JqMA)|9UuqAChHvMPJ+KsTN6$6dCB#2kxy3ut z649Pj>BK#dp<|Kc;rVWU0S(QkfzpUf2vFsHs`w--Zr)Zq9zE(lK`OR9MI-xqOcisV z6#N)`X+-AAQ9o$o6tPQx;Q0)uKJTdvsP?+K@S3)v*Y(?Vm$+|c)g{Hbru^)H_5Q6E z8(l`$Jf!otWl`9)3|rh)7zlxMfxaDo*(B{x^Se>*cSBlmoQhA6q-51}DZ8<_6oZyd z)(FAnT(!W2<*3#exA-{&ajr>m>(6(x7lWRwUYZ=KGXJ$5QU#mXts*a?4#*2*D!qM| z|57RqS?+gd%7X^DmPoVBW6OKcffRlU*70iya Date: Tue, 3 Sep 2019 19:56:07 +0200 Subject: [PATCH 25/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index c5c00c05af..6f64456323 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -365,8 +365,9 @@ def init_dataloader(self, batch_size): :param batch_size: (int) """ indices = np.random.permutation(len(self.observations)).astype(np.int64) - self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, batch_size, - start_process=False, sequential=self.sequential_preprocessing) + self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, + batch_size, start_process=False, + sequential=self.sequential_preprocessing) class DataLoader(object): From a08f4207015db0845d8f151857efb687c05e42e4 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Tue, 3 Sep 2019 20:21:59 +0200 Subject: [PATCH 26/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 58 ++++++++++++++++++------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 6f64456323..1748417c19 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -64,11 +64,13 @@ class ExpertDataset(Dataset): """ Dataset for using behavior cloning or GAIL. + The structure of the expert dataset is a dict, saved as an ".npz" archive. The dictionary contains the keys 'actions', 'episode_returns', 'rewards', 'obs' and 'episode_starts'. The corresponding values have data concatenated across episode: the first axis is the timestep, the remaining axes index into the data. In case of images, 'obs' contains the relative path to the images, to enable space saving from image compression. + :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. :param train_fraction: (float) the train validation split (0 to 1) @@ -155,13 +157,21 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, + self.train_loader = DataLoader(train_indices, + self.observations, + self.actions, self.mask, batch_size, - shuffle=self.randomize, start_process=False, + shuffle=self.randomize, + start_process=False, sequential=sequential_preprocessing) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, - self.mask, batch_size, - shuffle=self.randomize, start_process=False, + + self.val_loader = DataLoader(val_indices, + self.observations, + self.actions, + self.mask, + batch_size, + shuffle=self.randomize, + start_process=False, sequential=sequential_preprocessing) if self.verbose >= 1: @@ -173,8 +183,13 @@ def init_dataloader(self, batch_size): :param batch_size: (int) """ indices = np.random.permutation(len(self.observations)).astype(np.int64) - self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, batch_size, - shuffle=self.randomize, start_process=False, + self.dataloader = DataLoader(indices, + self.observations, + self.actions, + self.mask, + batch_size, + shuffle=self.randomize, + start_process=False, sequential=self.sequential_preprocessing) @@ -346,13 +361,22 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.sequential_preprocessing = sequential_preprocessing self.dataloader = None - self.train_loader = DataLoader(train_indices, self.observations, self.actions, - self.mask, use_batch_size, - start_process=False, sequential=sequential_preprocessing, + self.train_loader = DataLoader(train_indices, + self.observations, + self.actions, + self.mask, + use_batch_size, + start_process=False, + sequential=sequential_preprocessing, partial_minibatch=False) - self.val_loader = DataLoader(val_indices, self.observations, self.actions, - self.mask, use_batch_size, - start_process=False, sequential=sequential_preprocessing, + + self.val_loader = DataLoader(val_indices, + self.observations, + self.actions, + self.mask, + use_batch_size, + start_process=False, + sequential=sequential_preprocessing, partial_minibatch=False) if self.verbose >= 1: @@ -365,8 +389,12 @@ def init_dataloader(self, batch_size): :param batch_size: (int) """ indices = np.random.permutation(len(self.observations)).astype(np.int64) - self.dataloader = DataLoader(indices, self.observations, self.actions, self.mask, - batch_size, start_process=False, + self.dataloader = DataLoader(indices, + self.observations, + self.actions, + self.mask, + batch_size, + start_process=False, sequential=self.sequential_preprocessing) From eda5b8fee3c5063123d44ea06c60fa7dd9e33638 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Fri, 13 Sep 2019 20:30:01 +0200 Subject: [PATCH 27/34] -change --- stable_baselines/a2c/a2c.py | 4 +- stable_baselines/acer/acer_simple.py | 2 +- stable_baselines/common/base_class.py | 15 ++--- stable_baselines/gail/dataset/dataset.py | 54 ++++++++--------- stable_baselines/ppo2/ppo2.py | 4 +- test_recorded_images/0.jpg | Bin 1872 -> 1989 bytes test_recorded_images/1.jpg | Bin 1873 -> 1935 bytes test_recorded_images/10.jpg | Bin 1908 -> 1952 bytes test_recorded_images/11.jpg | Bin 1922 -> 1937 bytes test_recorded_images/12.jpg | Bin 1911 -> 1962 bytes test_recorded_images/13.jpg | Bin 1909 -> 1948 bytes test_recorded_images/14.jpg | Bin 1939 -> 1970 bytes test_recorded_images/15.jpg | Bin 1915 -> 1955 bytes test_recorded_images/16.jpg | Bin 1924 -> 0 bytes test_recorded_images/17.jpg | Bin 1907 -> 0 bytes test_recorded_images/18.jpg | Bin 1914 -> 0 bytes test_recorded_images/19.jpg | Bin 1936 -> 0 bytes test_recorded_images/2.jpg | Bin 1846 -> 1939 bytes test_recorded_images/20.jpg | Bin 1913 -> 0 bytes test_recorded_images/21.jpg | Bin 1933 -> 0 bytes test_recorded_images/22.jpg | Bin 1910 -> 0 bytes test_recorded_images/23.jpg | Bin 1907 -> 0 bytes test_recorded_images/24.jpg | Bin 1918 -> 0 bytes test_recorded_images/25.jpg | Bin 1900 -> 0 bytes test_recorded_images/26.jpg | Bin 1921 -> 0 bytes test_recorded_images/27.jpg | Bin 1911 -> 0 bytes test_recorded_images/28.jpg | Bin 1879 -> 0 bytes test_recorded_images/29.jpg | Bin 1905 -> 0 bytes test_recorded_images/3.jpg | Bin 1839 -> 1969 bytes test_recorded_images/30.jpg | Bin 1901 -> 0 bytes test_recorded_images/31.jpg | Bin 1920 -> 0 bytes test_recorded_images/32.jpg | Bin 1930 -> 0 bytes test_recorded_images/33.jpg | Bin 1919 -> 0 bytes test_recorded_images/34.jpg | Bin 1936 -> 0 bytes test_recorded_images/35.jpg | Bin 1902 -> 0 bytes test_recorded_images/36.jpg | Bin 1892 -> 0 bytes test_recorded_images/37.jpg | Bin 1949 -> 0 bytes test_recorded_images/38.jpg | Bin 1971 -> 0 bytes test_recorded_images/39.jpg | Bin 1969 -> 0 bytes test_recorded_images/4.jpg | Bin 1863 -> 1975 bytes test_recorded_images/40.jpg | Bin 2012 -> 0 bytes test_recorded_images/41.jpg | Bin 1948 -> 0 bytes test_recorded_images/42.jpg | Bin 1951 -> 0 bytes test_recorded_images/43.jpg | Bin 1943 -> 0 bytes test_recorded_images/44.jpg | Bin 1932 -> 0 bytes test_recorded_images/45.jpg | Bin 2034 -> 0 bytes test_recorded_images/46.jpg | Bin 1949 -> 0 bytes test_recorded_images/47.jpg | Bin 1949 -> 0 bytes test_recorded_images/48.jpg | Bin 1957 -> 0 bytes test_recorded_images/49.jpg | Bin 1948 -> 0 bytes test_recorded_images/5.jpg | Bin 1881 -> 1968 bytes test_recorded_images/50.jpg | Bin 1988 -> 0 bytes test_recorded_images/51.jpg | Bin 1938 -> 0 bytes test_recorded_images/52.jpg | Bin 1955 -> 0 bytes test_recorded_images/53.jpg | Bin 1962 -> 0 bytes test_recorded_images/54.jpg | Bin 1975 -> 0 bytes test_recorded_images/55.jpg | Bin 1982 -> 0 bytes test_recorded_images/56.jpg | Bin 1944 -> 0 bytes test_recorded_images/57.jpg | Bin 1933 -> 0 bytes test_recorded_images/58.jpg | Bin 1937 -> 0 bytes test_recorded_images/59.jpg | Bin 1919 -> 0 bytes test_recorded_images/6.jpg | Bin 1901 -> 1951 bytes test_recorded_images/60.jpg | Bin 1930 -> 0 bytes test_recorded_images/61.jpg | Bin 1918 -> 0 bytes test_recorded_images/62.jpg | Bin 1927 -> 0 bytes test_recorded_images/63.jpg | Bin 1942 -> 0 bytes test_recorded_images/64.jpg | Bin 1921 -> 0 bytes test_recorded_images/65.jpg | Bin 1939 -> 0 bytes test_recorded_images/66.jpg | Bin 1983 -> 0 bytes test_recorded_images/67.jpg | Bin 2001 -> 0 bytes test_recorded_images/68.jpg | Bin 2008 -> 0 bytes test_recorded_images/69.jpg | Bin 1980 -> 0 bytes test_recorded_images/7.jpg | Bin 1916 -> 1970 bytes test_recorded_images/70.jpg | Bin 1977 -> 0 bytes test_recorded_images/71.jpg | Bin 1982 -> 0 bytes test_recorded_images/72.jpg | Bin 2003 -> 0 bytes test_recorded_images/73.jpg | Bin 2007 -> 0 bytes test_recorded_images/74.jpg | Bin 1985 -> 0 bytes test_recorded_images/75.jpg | Bin 1945 -> 0 bytes test_recorded_images/76.jpg | Bin 1919 -> 0 bytes test_recorded_images/77.jpg | Bin 1902 -> 0 bytes test_recorded_images/78.jpg | Bin 1902 -> 0 bytes test_recorded_images/79.jpg | Bin 1902 -> 0 bytes test_recorded_images/8.jpg | Bin 1912 -> 1958 bytes test_recorded_images/80.jpg | Bin 1902 -> 0 bytes test_recorded_images/81.jpg | Bin 1902 -> 0 bytes test_recorded_images/82.jpg | Bin 1902 -> 0 bytes test_recorded_images/9.jpg | Bin 1929 -> 1966 bytes tests/test_gail.py | 71 +++++++++-------------- 89 files changed, 66 insertions(+), 84 deletions(-) delete mode 100644 test_recorded_images/16.jpg delete mode 100644 test_recorded_images/17.jpg delete mode 100644 test_recorded_images/18.jpg delete mode 100644 test_recorded_images/19.jpg delete mode 100644 test_recorded_images/20.jpg delete mode 100644 test_recorded_images/21.jpg delete mode 100644 test_recorded_images/22.jpg delete mode 100644 test_recorded_images/23.jpg delete mode 100644 test_recorded_images/24.jpg delete mode 100644 test_recorded_images/25.jpg delete mode 100644 test_recorded_images/26.jpg delete mode 100644 test_recorded_images/27.jpg delete mode 100644 test_recorded_images/28.jpg delete mode 100644 test_recorded_images/29.jpg delete mode 100644 test_recorded_images/30.jpg delete mode 100644 test_recorded_images/31.jpg delete mode 100644 test_recorded_images/32.jpg delete mode 100644 test_recorded_images/33.jpg delete mode 100644 test_recorded_images/34.jpg delete mode 100644 test_recorded_images/35.jpg delete mode 100644 test_recorded_images/36.jpg delete mode 100644 test_recorded_images/37.jpg delete mode 100644 test_recorded_images/38.jpg delete mode 100644 test_recorded_images/39.jpg delete mode 100644 test_recorded_images/40.jpg delete mode 100644 test_recorded_images/41.jpg delete mode 100644 test_recorded_images/42.jpg delete mode 100644 test_recorded_images/43.jpg delete mode 100644 test_recorded_images/44.jpg delete mode 100644 test_recorded_images/45.jpg delete mode 100644 test_recorded_images/46.jpg delete mode 100644 test_recorded_images/47.jpg delete mode 100644 test_recorded_images/48.jpg delete mode 100644 test_recorded_images/49.jpg delete mode 100644 test_recorded_images/50.jpg delete mode 100644 test_recorded_images/51.jpg delete mode 100644 test_recorded_images/52.jpg delete mode 100644 test_recorded_images/53.jpg delete mode 100644 test_recorded_images/54.jpg delete mode 100644 test_recorded_images/55.jpg delete mode 100644 test_recorded_images/56.jpg delete mode 100644 test_recorded_images/57.jpg delete mode 100644 test_recorded_images/58.jpg delete mode 100644 test_recorded_images/59.jpg delete mode 100644 test_recorded_images/60.jpg delete mode 100644 test_recorded_images/61.jpg delete mode 100644 test_recorded_images/62.jpg delete mode 100644 test_recorded_images/63.jpg delete mode 100644 test_recorded_images/64.jpg delete mode 100644 test_recorded_images/65.jpg delete mode 100644 test_recorded_images/66.jpg delete mode 100644 test_recorded_images/67.jpg delete mode 100644 test_recorded_images/68.jpg delete mode 100644 test_recorded_images/69.jpg delete mode 100644 test_recorded_images/70.jpg delete mode 100644 test_recorded_images/71.jpg delete mode 100644 test_recorded_images/72.jpg delete mode 100644 test_recorded_images/73.jpg delete mode 100644 test_recorded_images/74.jpg delete mode 100644 test_recorded_images/75.jpg delete mode 100644 test_recorded_images/76.jpg delete mode 100644 test_recorded_images/77.jpg delete mode 100644 test_recorded_images/78.jpg delete mode 100644 test_recorded_images/79.jpg delete mode 100644 test_recorded_images/80.jpg delete mode 100644 test_recorded_images/81.jpg delete mode 100644 test_recorded_images/82.jpg diff --git a/stable_baselines/a2c/a2c.py b/stable_baselines/a2c/a2c.py index 65e7c3cc10..fa2da509ce 100644 --- a/stable_baselines/a2c/a2c.py +++ b/stable_baselines/a2c/a2c.py @@ -89,9 +89,7 @@ def _get_pretrain_placeholders(self): policy = self.train_model if self.initial_state is None: - states_ph = None - snew_ph = None - dones_ph = None + states_ph, snew_ph, dones_ph = None, None, None else: states_ph = policy.states_ph snew_ph = policy.snew diff --git a/stable_baselines/acer/acer_simple.py b/stable_baselines/acer/acer_simple.py index dc78c54359..ba150b9d58 100644 --- a/stable_baselines/acer/acer_simple.py +++ b/stable_baselines/acer/acer_simple.py @@ -153,7 +153,7 @@ def _get_pretrain_placeholders(self): policy = self.step_model action_ph = policy.pdtype.sample_placeholder([None]) - if self.initial_state is None: + if self.policy.recurrent: states_ph = None snew_ph = None dones_ph = None diff --git a/stable_baselines/common/base_class.py b/stable_baselines/common/base_class.py index 793f8f19aa..68fe41215b 100644 --- a/stable_baselines/common/base_class.py +++ b/stable_baselines/common/base_class.py @@ -245,9 +245,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, else: val_interval = int(n_epochs / 10) - use_lstm = self.initial_state is not None - - if use_lstm: + if self.policy.recurrent: if self.nminibatches is None: envs_per_batch = self.n_envs * self.n_steps else: @@ -282,7 +280,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, for epoch_idx in range(int(n_epochs)): train_loss = 0.0 - if use_lstm: + if self.policy.recurrent: state = self.initial_state[:envs_per_batch] # Full pass on the training set @@ -293,7 +291,7 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, actions_ph: expert_actions, } - if use_lstm: + if self.policy.recurrent: feed_dict.update({states_ph: state, dones_ph: expert_mask}) state, train_loss_, _ = self.sess.run([snew_ph, loss, optim_op], feed_dict) else: @@ -315,11 +313,10 @@ def pretrain(self, dataset, n_epochs=10, learning_rate=1e-4, actions_ph: expert_actions, } - if use_lstm: + if self.policy.recurrent: feed_dict.update({states_ph: state, dones_ph: expert_mask}) - val_loss_, = self.sess.run([loss], feed_dict) - else: - val_loss_, = self.sess.run([loss], feed_dict) + + val_loss_, = self.sess.run([loss], feed_dict) val_loss += val_loss_ diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 1748417c19..53bc478f4d 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -12,6 +12,15 @@ class Dataset(object): + def __init__(self, expert_path=None, traj_data=None): + + if traj_data is not None and expert_path is not None: + raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") + if traj_data is None and expert_path is None: + raise ValueError("Must specify one of 'traj_data' or 'expert_path'") + if traj_data is None: + self.traj_data = np.load(expert_path) + def __del__(self): del self.dataloader, self.train_loader, self.val_loader @@ -77,8 +86,7 @@ class ExpertDataset(Dataset): for pre-training using behavior cloning (BC). :param batch_size: (int) the minibatch size for behavior cloning :param traj_limitation: (int) the number of trajectory to use (if -1, load all) - :param randomize: (bool) if the dataset should be shuffled, this will be overwritten to False - if LSTM is True. + :param randomize: (bool) if the dataset should be shuffled. :param verbose: (int) Verbosity :param sequential_preprocessing: (bool) Do not use subprocess to preprocess the data (slower but use less memory for the CI) @@ -88,21 +96,18 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, randomize=True, verbose=1, sequential_preprocessing=False): - if traj_data is not None and expert_path is not None: - raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") - if traj_data is None and expert_path is None: - raise ValueError("Must specify one of 'traj_data' or 'expert_path'") - if traj_data is None: - traj_data = np.load(expert_path) + self.traj_data = traj_data + + super(ExpertDataset, self).__init__(expert_path=expert_path, traj_data=traj_data) if verbose > 0: - for key, val in traj_data.items(): + for key, val in self.traj_data.items(): print(key, val.shape) # Array of bool where episode_starts[i] = True for each new episode - episode_starts = traj_data['episode_starts'] + episode_starts = self.traj_data['episode_starts'] - traj_limit_idx = len(traj_data['obs']) + traj_limit_idx = len(self.traj_data['obs']) if traj_limitation > 0: n_episodes = 0 @@ -113,8 +118,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if n_episodes == (traj_limitation + 1): traj_limit_idx = idx - 1 - observations = traj_data['obs'][:traj_limit_idx] - actions = traj_data['actions'][:traj_limit_idx] + observations = self.traj_data['obs'][:traj_limit_idx] + actions = self.traj_data['actions'][:traj_limit_idx] mask = episode_starts[:traj_limit_idx] # obs, actions: shape (N * L, ) + S @@ -145,7 +150,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.actions = actions self.mask = mask - self.returns = traj_data['episode_returns'][:traj_limit_idx] + self.returns = self.traj_data['episode_returns'][:traj_limit_idx] self.avg_ret = sum(self.returns) / len(self.returns) self.std_ret = np.std(np.array(self.returns)) self.verbose = verbose @@ -225,24 +230,21 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, verbose=1, envs_per_batch=1, sequential_preprocessing=False): - if traj_data is not None and expert_path is not None: - raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") - if traj_data is None and expert_path is None: - raise ValueError("Must specify one of 'traj_data' or 'expert_path'") - if traj_data is None: - traj_data = np.load(expert_path) + self.traj_data = traj_data + + super(ExpertDatasetLSTM, self).__init__(expert_path=expert_path, traj_data=traj_data) if verbose > 0: - for key, val in traj_data.items(): + for key, val in self.traj_data.items(): print(key, val.shape) envs_per_batch = int(envs_per_batch) use_batch_size = batch_size * envs_per_batch # Array of bool where episode_starts[i] = True for each new episode - episode_starts = traj_data['episode_starts'] + episode_starts = self.traj_data['episode_starts'] - traj_limit_idx = len(traj_data['obs']) + traj_limit_idx = len(self.traj_data['obs']) if traj_limitation > 0: n_episodes = 0 @@ -253,8 +255,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if n_episodes == (traj_limitation + 1): traj_limit_idx = idx - 1 - observations = traj_data['obs'][:traj_limit_idx] - actions = traj_data['actions'][:traj_limit_idx] + observations = self.traj_data['obs'][:traj_limit_idx] + actions = self.traj_data['actions'][:traj_limit_idx] mask = episode_starts[:traj_limit_idx] start_index_list = [] @@ -347,7 +349,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.actions = actions self.mask = mask - self.returns = traj_data['episode_returns'][:traj_limit_idx] + self.returns = self.traj_data['episode_returns'][:traj_limit_idx] self.avg_ret = sum(self.returns) / len(self.returns) self.std_ret = np.std(np.array(self.returns)) self.verbose = verbose diff --git a/stable_baselines/ppo2/ppo2.py b/stable_baselines/ppo2/ppo2.py index 0d9a1aae89..a82a1db187 100644 --- a/stable_baselines/ppo2/ppo2.py +++ b/stable_baselines/ppo2/ppo2.py @@ -103,9 +103,7 @@ def _get_pretrain_placeholders(self): if self.initial_state is None: policy = self.act_model - states_ph = None - snew_ph = None - dones_ph = None + states_ph, snew_ph, dones_ph = None, None, None else: policy = self.train_model states_ph = policy.states_ph diff --git a/test_recorded_images/0.jpg b/test_recorded_images/0.jpg index 4ca1ed9aa5dd71f371dc77523751ed1eccc96e17..ae56eca0ca5c77e8567565cea86431f2f0e5e40e 100644 GIT binary patch delta 1161 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 delta 1197 zcmb7D`%hDM6#rs`g=aUkJOZH!c3{S9L|N4USBHqkp=liJM5H1vFkHf*C`3x{G8|MK zT!fJha4TXEEsu`ZoC@AS(Mkl7$5snyDY(*!wJmhr?c?6>?*4&=B`4>X^ZA_fIWLSc z<@3|D3z}i9M6#qF5GVwBd{eDxJY+Wn-$dw6qB#&e;B=R1dRgIbjPrRG^=S(B@D3gyiz1Z_f>aBT(ph1C85BbZjqDS%*9wTc@g z4uNnNdFgdLa#NUOx^Y_;BffE`W;S=sJ@)(kpWU|ghVyr32kOs`AX+Ed$0L1@(sa#b zggSVgVksSQ=oH&LNfLb!ysY{!2)Y5x#vx4#%2V#(>O`|SS z3wFVA{{Gt#e7z`qk7zI_DIoC4B7y~rsl1HRh>4G$cT3K!2PD1w^Yr|_hv%=Bd5eVg z$mSfEsrsPJ+t4_H0`J8Pu?%r!m}C*D`ptJObbOBeD+oSA&XKP=@hv4;g9mF{X6ly5 zB1L6*bit~nQ%a=CA^7km%f@i#(pQxZfhBq$1ho)6#Qs+d-59YU(f{r)lt?+XxI!I= zp!!_g8pp{LSQW&8gPr@reTd+>eP`@`&TlhX+xqK3=%*eAb!ax3owM7JnJhzxGp?Jy zt^G4(k4Y-tX*m44XDngpNyX{#!i4fWNk`m|&4w(==ugoN`a_VoM@f08AgJ38LFGhA z3?)2=Ihl07Y%T4He{O$*!Dr*-6E$KX+wY@XXK08*>`AWhmO!0jXwD4q_SzYq6>!pzz zMT=~fo4l3F8;pfuTl5bQ@Sj4UKaID_oMw8>Bm|EJObQAg$R{^V<8isI302!$tA@0g zEwIRFrz#;xVv#Hu&mXbBa@v<-@xAc$Rb)<-W;>(Lht}468BCn)t(e@_MXI|*R z@xCcMY0ej0)COZ{DSN6&+|7L&+*7!AEpxA)!L&>0iB*wTP<`t#tvvNG1XnuDYya|T Ii-78X0LO%ye*gdg diff --git a/test_recorded_images/10.jpg b/test_recorded_images/10.jpg index 196063e82d877bf8c3468333e05b581de09f7afd..0e63b7847660bb91171f3ee011eaede32b42ee14 100644 GIT binary patch delta 487 zcmV+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t6C`&Rz|&@C(TR*ER1iYTkz82FHk%QAHKi{4mpEz6&e%w9qjxyy0|I(i>(7%{2OWbr1Cjs$ delta 483 zcmV<90UZ9I5A+VOQ3YD({{Z|Khs6FR@Yjbv8b618Lw%>2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$e-wYi=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnrlc>e&we*XaETKHlA0AJd-{()&4Q2G3y+!Yq%gp`Ik!`{gy+>V*)6%{i zqKYV@iYvJIJ8keN+%}={cg4OV(`UE5iR_a_(jvJ>Kyt;)%7u9YpgdRVU;I8R_C@~y ZqKgOq2{kYNMz6=pD58oeqKYW5|Jep31ULWy diff --git a/test_recorded_images/11.jpg b/test_recorded_images/11.jpg index 178f841f79784ba8899a43528fa49b5d75431216..c565af030a6d2572452e004a6ec7e26c92e989bb 100644 GIT binary patch delta 461 zcmV;;0W$uA50MYBQ3XoK-|$t>+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptiF6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06q9ELD1RuTiYTkz82FHk%QAJ(w>{f6ZmuXFc3Mn_@VIuqzHVqe+yawTO4Hlr=@vS z6jiMf>MJc~()M=3Lv2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$e-wYi=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnrlc>e&we*XaETKHlA0AJd-{()&qh^i^M;Kk#3_`4+wyf7kY{{{Wy`SLUr0QAHF{SG+O* z03$A){{Uam{{ZM>zoM%A@&5pV{r>>SweZ9KzqN1u0@A-VXrhWJqKduYkNFvN@B03S z{{TZ3{S{Z`bXWWq5B8_{E&E4kegd`lP2B@jZNd}1M_rB6(!Ly` ziYTIrE4cVOZSW}EHlgu%#l9ocXSckG?2|>(BDqIEa>dKag?R&@JXh*p{5~u8MgIVz YiwFJ*H81`~ugA(LqKYV@iYTxD*=U3T>;M1& diff --git a/test_recorded_images/12.jpg b/test_recorded_images/12.jpg index 1a1f052b0945c6d10631c65b81ecb60c7553ec05..1556cd623d9ed410830eaf28a91255d98343b161 100644 GIT binary patch delta 380 zcmV-?0fYYc4yq5ZQ3XoK-|$t>+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$pthv6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKcE325OTm1}uN_tNsfI`&0ZD z{iC!$0b2Yf@#TiH`c2-V_seDGe&|TH;R)WOuEy!2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$E);*m=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnr)!Uior^T+-R_x}JQ*TWC`{?)(q3rhUeqKeb;H;g<-;~6Yw@g}48m(#S!H2XF% zq7=4;cEpEh8@8_*Y@7j;z^uxXSq5r$Re!-?{{U)#g5R`uhu|w;gx)-`)?Z1x)L!{) zywBYU7Th5_)OFb1JuBhLD58oeqPvfSw%-Dc!)hNFd|To@HhX)>p2;*_A}f@12P|B? ps8^6W1I2!&{{X|{zhqzfD6oIvlT!Zx+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t4(`&Rz|&@C(TR*ER1la>ZSfAXvT3kUmC{1*MAv_An_{3h|`hO+ui-lF%*W#)e9 zNVee#-lML@>FHk%QAHG2r1)P!{gbXdJ!e0RJ|cMD+f-;2-&@#ta@ts9lekA~g)F}0 z3gi5HYv3zC63uV$*H_fJ;87jG0kQ`?ipHy2CDc}0F3qLv?SzKv qH*=1FFejycy#D~h;=g2H`Y5n};FD7S0OV@?e4>gdqKYV@ivQV%GVzE2 delta 383 zcmbQk|CMh;AZyg~{|tY`+mHNH{cyeAPRhQ$#<_O+%=M*#nwxf4Y=5X*ICn|9q-|~X zX4Rj>rmQDYfB4xR@&62VR>%KwUH{K8N$c43{|v1CA5y<9%}?28wJ&Y1K)O%d z8}>hc!e1Pne27ig?(^|~+~5B*C|y6y|Lfn?{a?7f{#;$ub@|fQy=un~?^@Se{jfTF z_w4ryH?xAgUh6ixt8QZ`+fb_Nkx(tzq-`{L9h+l4b|W+vb!mNXvwxC$dH?HQ@_%{4 zzl6q5jsFl~e{24O?Qdll{@}X)(7a#Abo!;duj2cn^^Lzfxo+q1`zl*z?(g-Zs0*lH zW8LEiZ?_*+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t52`&Rz|&@C(TR*ER1iYTkz82FHk%QAHG1uYxVS8F%7~TYrdJrlDn{ zv46H)=~k&U>GC$+i0rD_eW2uw0#9sLq5lBFH~STT(Ng$@{{V!or~d#X*O~Z+EeZ{K z_8$w~+}vrYbs(^wMDi7mX(8NpGpdpmir|n50QWTA66z~0X43X{!b5c%xyL{l6Vkt4 gf8p_8vM>DPdseke{em+q}6j4PKQAL0M*=wEw-T(jq delta 474 zcmV<00VV#j50ekDQ3YD({{Z|Khs6FR@Yjbv8b618Lw%>2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$E);*m=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnr)!UipW^T+-R_x}JQ*TWC`{?)(q3rhUeqKcnO{>}c=xBl8Q{g2O2wf&bKZqh z^i^M;Kk#3_`4+wyf7kY{{{Wy`SLUr0QAHF{SG+O*03$A){{Uam{{ZM>zoM%As{a6j z!T!|$00qBj?GM0KzX`l~VXVHBcc{Jc*?FJ35-qqwcc|;Jx_Vc`lu<<#QAKwj2W`Fu z8-~<9J}&sT#CmM@_mMr4Xu3pKDCiDYxp`2pAan+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t52`&Rz|&@C(TR*ER1iYTkz82FHk%QAHF{TK)#M@I~i}Ev^0{>bi}V zj=}!dbEMiN_X+YbO{naua{EEa7zCc!uGhp`2kemsgL^lHz9abN<5EjkHV|I;ZrV6x zn`zjt%Wz7mILQEzH9H#f-4g06EoRd8cEUq-8@b0o7!%UJUVq{7U$QU#6j(p-NvVJG RHGV!(MHEp*6j4Qg|Jj=3`^x|T delta 450 zcmZ3?|C?_^AZyg~{|tY`+mHNH{cyeAPRhQ$#<_O+%=M*#nwxf4Y=5X*ICn|9q-|~X zX4Rj>rmQDYfB4xR@&62VR>%KwUH{K8N$c43{|v1CA5y<9%}?28wJ&Y1K)O%d z8}>hc!e1Pne27iA{`2vF+~5B*C|y6y|Lfn?{a?7f{#;$urS12h;qZpYifI3jCUr`e zpI5)`d^p*+Eh#UzX77wjksj9C{|uTe&y!1zrUkmjeK`K7XIJ^(dguQP3%mYxt;TMq z#-c8*?``%^QZMg+{Y(BYPxzP6_<8mAAL94_6x%0JfBoCq{|pPF!k?`b33L?+4Bun; zpFvq~?tg~(3;!8jB<)|c>d&hG3{40BT><)Nf5uz>17Z6)_f#gX**Cd-#okXhE9dVL z(%s=yzT)-9T~*&ZIvHwe8!heQ?YD@n!oVfbqC&&OG68(P@0I)OdDF6Tf diff --git a/test_recorded_images/16.jpg b/test_recorded_images/16.jpg deleted file mode 100644 index d40f5cd174205eb6a9b55c73b2ba47499e9656f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1924 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 Z_h?IG0ex6RG_kW1HT`sDmX(M){{sDK*2Mq- diff --git a/test_recorded_images/19.jpg b/test_recorded_images/19.jpg deleted file mode 100644 index 95219ae3750552b474c57d8324a30ef5eef57fc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1936 zcmchXe^e7!7RMh#5<*Zw6hT*msGzn|H6jItIm)jhYRig5p_1Ycf<;RaTf_rQkuI^( zZK`o~jfE)af{KeEKLl*17%`mnF+n;pk@R2lO`q7WGPk#1!&Z*qf zMPL4{SakL)@kQySe_X!u&#SVs@|(B*RZ)5SPVIxb`i91bP0f#$ZS7A~9Z!FF(cRPg zQ(ympMmMY<`Pnc!_RDM2&ux_x(Irqu23E21X%ekgK>)NkMENyY0L|)Lf?5t|jdoLW8 z*IhBjnl3}2-(8OkqYU@ zGz}1FATaG3f$){1ugn#!g7Srj1iM|LMpU@By6sHisJIrr)b0b4UI(1>tfh=Qn5byKm z1JY-yu9pYnjrhC z4#8uB-+Uw+g%fnSB0byX#ENSWd{s{Q@XX&rP{tlslOCNAwDqdzQ9mGcZQ;K6Wr8oL zw-Vwy&hgTv0Axum8J0V>mq5G+RiJVyeNGNz+@d1+CR+$yAkdiq8oAQy?+s8x8MD10#@%8SUaxLW;L{F>U9 zQ;oWHStU1xK4JM8Qhb#33V0kEBdXeT_u7Hfk@{Nk8t&|-&4vWLC~rBf6;+4g~V0hah0kJf1E3_`+YHr=gTy=CInW#YA#Vr1kvbjIZ8(PuS3e`Deu2$X%Ir=D-#w)62^<+DjkUW<9uNB?dokH0H0Eb(>N zyrVa3lSN)9KD@qv**aC~M{EbN-giE4@9RG(v>=}UXafW*0!!#aJ%?cIAXavVyhB54 zrFv)@So(z9_lX$$QEqCLLYh1$7`BT^Ocw0Ajsjejw={TihIHX ziN?0m$IO-sVHeYzBl)Yx=Iv|B{h-?SBui|IqyGu*1s&LQ{6{oR|634r^b%G(Li$<= G2Yv@jzub2K diff --git a/test_recorded_images/2.jpg b/test_recorded_images/2.jpg index 97cd06ef251550150c06cf0617e5a5e98bb3e66b..bbd96f15efd51121aa24fd422c495889886fcc10 100644 GIT binary patch delta 1261 zcmcIiZB&zG7=BEVfMgND5o!!#t+=m>j6JWQ9g zXa+U131n)Z1A=jk&er&FnBW9dUKN=%aA2@W1MHSsQ6%C;q(SPCAj}PzNs(%lb9M!_XjO~+KnDF zqK-OU9A1lnHnHT^uJ z8b3PiI-f zSvt9PHxY|~W@86=#}G|#IY5q1Z4q@XJekvaXJcGySJ#gU=dl9iI7>^nhEm{52=wkC2fZWhaY8L|G7S|0 zUeSjL@XMQgaD%ic(?+s+2vm95+Tr|obcvler9i-)c@+T(b74rYUD?vACmV1|k8t{u z)K54UmDJ?#e?7;oRy{Xxu59=Wt3muc0$iLNVjAO~3UIa|VD{q^&_@UFA`l}`V5S)* z0$&F{i}t^<61K7_M2Ji`bxAG1*srfwIFAmtT`oAFcX@F=9C`c6f{NHlx>V?!XZH3} zDAq`>Mp+S&Rjd<7(2o9^B^b{IAmR2$wQ%TSE^vs_x&E28Z0*TY81?a?Y&1{^_CJUW#{<{^gQpcd4{pCS5qgDxc$5 zIPRr}-u>kPi%G}+Y+u3-`)3?FxtKJTci1TA{*#ku6jg19y5EI+>YK}A@WnIRI=}sk zK1EkO60UQf446n9x;onY>iJ|&wv#W*WAz9E6rQaH&Ns^Ky(HMnscFUy_IsaB5SsWK DX>7GW delta 1159 zcmb7C{ZCV87=77fM2d7{s2I>L%7Dm6M;L+&aw8w&rjB)+78z2iGCE)}j9~#w-(_xy zMJS^xlRB#`8pgnmkAZZRs}!wd5GEfYpld6nuoY$tO}VA_-gno3U}4FV=a=W4ljocq z1-sMxmti-U@%#)XRCywxE6f#GYor5Pb|Ua?sQC!YLEv7@%`!t9C-@)rBm&dZoKrSu z-s}(|R80lbRj2hBao`EGMgJ*rqspam2=wx}WVn3dG>;y5tVF;RXf;$sRXuTXCMtiE zVzcVst1mx#z94sb5h{Aap-TvOU4pK+ibv?z5Fqx1W5349*IE3rj^%e}7hI*zTlzY= zN&kLfrr4PJILC1ffp4bwFw5Y`vJE-7juza3lOKtp&0vPjyGJ!NvFPCwL<)SS9L1&$B0VWlE5|Wd51-+ta+t4L*})EAK8`6spl{rQ zFVwjTC9%}m`8cdml4!lr)x@p1(Oo?%>R%iAeNuLpvn^Qg_OVTKdA*p4gzbFFCzYWa zDlvNRk2FW`iiQsZZ9^2%j=+rUzaVfGnAJn-bu>%uiph zQ`zOEu9H2lBJj0QvYohKOVlCYEhGX8jR*J{r$Pt!KfPIZe915I&CcPe-Sn#s49CePMNF&G5wJ(>MxX|P`||&FgR3K6h~KD*g+xl0ah5)e zKvhxnA_AnZ(osX)c43E$Kb8bO(uQZpUq8{5aRl~$IDa;_^OG-H6MB=j2z|OeQwO_V zzJl*cL*VYGTCO7mcH|eOc9iU!b*84LP2rp!Q3WGAe}bl^OcnyF&BqXM&qJW!7wXK~ zjR?fQqo+N`5vUD8;LKn#mzEUC$@NSEfjk7*^;Q8%SU5zefa!=r>CWApHjIF=mGPuR^eaYMM)@f&zLElyGp%~^oJLH+LW5-0l^;#%pJuWn#d-m7kBAV#t<%AVBa}}uho_an~(M=#ErKXCrVTrpYU4=;zmoW zrj)Nc|3W2M%<=fV$KAhtG(Ljp>MPB6EPuDFR-{Sdhs=4Wb(egge&b6I8MTjz;-2&Y XZs%n&sRms~;K3N-e8FdCJ(~CzDTaY! diff --git a/test_recorded_images/20.jpg b/test_recorded_images/20.jpg deleted file mode 100644 index 0673c8e71114b2991b33a911f8eddd909598db34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1913 zcmcgreOQxK6u$`D7{dTj1WjkCpq8W}5vaUR@)e>KilUe-{9qUwAtvG@ydlMOT1#h| zQ&@loDn=k5g0?ptIPB3D0s-T}IYxtG)H|T<9lU#QclK|8^hZzUKKDNNKIh!uIp=rI zfj#gUaNiIW69pU`0B}GHz&;QTra9QfeonKClcW7)IXO8xu~}^P^UdKpvpHN2o9)bV z=DOGg-CTJtuJ#A~9`Kw&0!VOh@Bpv{@DVucIVSS(w>V65bYihN=r0c$)VU*{j*iF^ z3%NnoxkwM3JXkYcTKNXsGd_jmn>lk;{@D`eh3l)EXKijL7X|JJ$v`13e)z#mv#8VBiToDjum|TNulWE zDe*b!`7bV9{PL2lwCw7&ugfd0->A7=TUXz3r?Kh2vZeKbs_o$qPdYlge(vt+)#wKF zgTEMthJXFdG&Vl*r`bYTC!q#7+iAl9od7|hkF5qD?pd1!!N>h72t1?d73xtb1X0a; zIqmm5M#&}@nm@1=9>%CGp#nNU+gq>`*(w>Y2tgm-_jIl)3e$Oy?HNBVF?NkH?S_nA zqWJEezMW08je+Fd`N92DE7J2a=vTB<83ekQNbTvhaw_Uj@WH7$e~hmzQe>;;-^G+O z&03eMl*HuqCoZh=i2N$DQX>J|-+MaUv}JkgC5fda_Wg*ny1N@ITlC(u2IRFDjWMPR z5a{FTvZpYnO|h!uo-YKc%){IDPlDE*mw2^vGZzoWtVtEDpnqEt$4;0gAUS3qY8(P? z1VPqgsnesU0(WPiRHVwh1wRI74dST*qZ9zePo( z@V#r9&at(@l?RxPet&tx=!ii-KN%Cv3wfNQ&Bs#Y8WH39>0HJW?=4VaJ%pwn0u2PF zP5lt4s$`0c$vUkiI9GeQLpF@1se6R_VER?J84xJLm`C$NP%y7f#SprA5QsD0hCq^A z#y5>AGTyN<>EeH=mEao)>II{ZNxj+sTaqa;x!spNtx)*N3~S=c7A<;^;&DN1Xe&D2 zenwbQkh3TJrvf@cV*AyT3yKjZ%`a-{O?>j9ymrXu{+1X1?6VBUPeScgYqFS={--fAI{5jJ ztP+l*az%Ky%Bh8yAvjgW_yn4-Kv2pZP}3fdA!zARzrg%})wYB!_*N$PhV78FNlkkEULDe=|)x6lNwyNjj-`P#|JS}88a&#f}a{WOgIE{ zu>VexKqU|BP%qCbD3Du)Oi*X{5CrsWQ46z}>=uR1!9>TybIUJPeHg#A=I+r3-SW($ zt3sc3x#?1Ji1zZo9~v#HTz&KMu9U&L8u3#8)aus^3E+yYtT;NU5dt?EDWItlKJ~JI zd9#e+2R$RKrk^o#8$q9qro+;k@o{}6{_GZR@4n;RCm3h2dvFn{B;-ExwT!*>p^DTZ zcj3llBZsCFhgltiUKAkZ{0`TGU3+W5$s@sY`-iayhnZNm}2C1OT=b6myn zED-p1E8QlUE@FbWf$l05FDVr-vlL>3`#Ok`NxscBabl~W7$XIQ)l1=xcbjiP@KsWx z;TA%iReqg1GJTEmnBe4Ylb8I^q%^K(zj@pu#iHSF a&1)kj;@?HI`CWsct&6hSxw0n*d;bDeqR=1! diff --git a/test_recorded_images/21.jpg b/test_recorded_images/21.jpg deleted file mode 100644 index 17a98f10f7972c91158a8fc05625be22f98d9980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1933 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 I-b&Q}Zv(y6Gynhq diff --git a/test_recorded_images/23.jpg b/test_recorded_images/23.jpg deleted file mode 100644 index ad341e5388424e7902a246005ef3a8a8d3f20588..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1907 zcmcgrdsGu=7XNr9fzSd)2++kSA}A_8FwKILIm$~^u&h)Rl^lE!ENxSyD%~SYfi9`h zZE9n&Mj?gR;sd2351)((7<6@0KnjEdA%q6DCc6{BWCD}>c8`;@!E6;s*US6xb^uv#Jm#LhSA~Cx6Mh2E@1k=%n7Nn zf12tsh=#E0d$))8+~pXf@OumSBlBzWOGM;KEun-!w;0!+id7IvNBAGj2mNbiZB^TG zwcN6DhU^9v`?+(;7vK{XZ`Q@96fL5xx3D6uEWiFks&6D*(Q0~W&@aqJ#KFRGzj~8hX=aA@8UfdK*#QPR!2!8l6DQO3E)Ef}ig& zsdxy2kpG<{gUFuJ(X$*}UaqhSDc*~LNeD=exRY9n4~XM}5b=rl;=1z#tqdmow4aC|S;(U;mCF16;H#tCO?tK;R|E1tjs3 zORNx3o0SxoH-_2FzaaQdj69P}#^tx8Gx~aT>^kb0z7qpw5KO9e(Yj|rFrCQ7Z4GV^ zsK2^Nx273_2??T`$!0^K2tELT8?DEa1!#xiJ_mxh7!~C)Ku>JM<8!o2iXXE4AUfC* z)0SK1E!>uEWRhg&R98t64P8P5Wf3_L2sEu!>0yDqDLrvPdSW)NB2V8vZbxZ-Yb2E9 z+Kh@~TOkM;=rY5it4F89 u8&f%(CBFtc{f)Ca!f)cu&&`4>C{8pCaVW`3E)n_yvjt&XN3vsKaOmI7+tYdg diff --git a/test_recorded_images/24.jpg b/test_recorded_images/24.jpg deleted file mode 100644 index 3edb945c34255e74e9acc3eea5624197c9973f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1918 zcmcgrYgAKL7CtE#Qzg zSTYt1LoB2aEk3X*2>8Hqi#&pkP6VVt7z`maU=7n7py2{H_sos+cYe;AebzbaoVEA) zzH`34Hynavz=$$Lu#npCzKLEB95CDOlodz7-J}6B`%LdoN+fUcvkOlJ*}+K63O}nkfDFiL8%4K7A%T=WNlr zzZ6S8{Y?5r*~Kr*EB;m~uT@^Y@=e{=Xwzszo{YCEG* ze4kK9wd-6i6Ed^+uc%1n5%+amy;cVHpLqV7dGD64O4)p8;vZu#=v#NzcN%<_k1Lug zObO<42n@TM&nzKSPg_X;{QwBksE4;&`ogzglzI0$XRez_*q$cbO8&fcH&b9Q#90p!IWM}ri%r(YTkt5Xoks)#2!x&kCsp_NdcpRc4m(cvOBGK6Vc zAkac!-Zct=S|x82FE;Duxp}%v{qiX!T{9#yaLG5^mO;=FO+8*6K|kh=r36gB3IeJ4 z_YlbPlpOO+oA?7Ol_C8vxe|U0L5pzu32v|ieTP#uX153O=U3YTI+L+-+1Y@Sr ztGf2OF8q?(rT=lmwe$~hwmTE;d;8_ImWZL)1^A8eq%Jo%GD4!)6oenjG^xTvPv1LK z_BhqGd?fKC%U7E@7rtPIz_oH|H`?oH7Ew+{2*%TC*>+m%kg3A#TM#&Aq2@5OBQU>T zG51c?0SF2sFhY*#%aG%mMgMAAllI^0$Xy)#p`vNh>b}Pt9V-=6fimK#Mw>-_8dQSd zJnpL|2@y@x>5BF2QV?q{LGYQ9@(s0o1wpOzxQ6t20zv11<~P(Mq^UF7|2w(x6Kazn zv8N<7y$pcNviXep>y6|teX%*<-J;!zvb7Bh7V@rI)z^sX_hDA{U(pG~tfZD_K=AY~ zi;9835Bc9Y1VqY|p04FpMMa7Q5f%Pya1sJ?g`|^OhYw1k{SZlROkQ23>SO+f#@6iH z`YoANmqosB=Vg@PlcaahgGipFKJ3P&L#Y$ZjnWOArLZ@R0`QepS`9}obhmjX}WOPP5I%}v$$8Msw>dPH0gkVy=pVmDYf|)oDzMx`2 zpeb#jQ_~E=gcQ-wrm!JUtU3Y#gVy7r7usRGzXF2jNHyg$NLTE}?h4u^!;e|6h>x~J zwxw0Mi*}}%SR|P=)s>%3L+8^#$wVpyLhWs;;J8rU#E69o^HccWgp9Z ziwbBE`Xpq_`K{+q?5Sgf)~_s{^+7MT{nHR7x|yilBF}!*8}{PppEIv@`{xKYh2#_+ z_g`k$9kOY0o$8T_*vy&UgCDe%J|!6$bn}$^{rv^^Y>945MdeaWz{t6vv!$&o>#pQR z*gou)l!>1n8ROqM88iM%NiOdjjX1}1II!e$+^Nz}ek!T>(q)GAyKL1njL1zgl|T^Z W?M5y;AtXN+$}YZA%!@CC!~X_qyVAM< diff --git a/test_recorded_images/25.jpg b/test_recorded_images/25.jpg deleted file mode 100644 index 69650c6f377020af228995f71984006c2a4d631d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1900 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 KF;7F`@V^1_?$nw9 diff --git a/test_recorded_images/28.jpg b/test_recorded_images/28.jpg deleted file mode 100644 index ce6d41040a371c7cc0d7eb8eae7cf83f3acd8dea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1879 zcmcgreOOaf96o$)z%W1r!O|HbC?f#LN?CK16H|Ol(?(XK!@?f!MU$&Pgi|xf`u{=4R zUf#}NRz4hWALj@98E`y78c1_-@dv04a2arqSxkoEpKx(?bN67enSVJ&;&m}KjY6*O$lMIXA`*yLHchLOckOfP_ zBbF_XT*rGh=DFCogv6v|{>GF|+tXg%A=tSqec%2AS)%NNujd_p=iMVm-+RC0!;eZO zAAchKT>izEWv9M6t*EL#`|Wo%=e|E*ce!5O(D+l+l^d;X?Kd?Yw{Cao?sxyz)7z&v z4w{C3HxG~e@uzisV)C(Vin325J@9nOh5a+Ds%sO@n=I?B*jvYV-Gg+YnJe!Ty|lh$O+7(BjjB41|d9*3P~ zaUW56^{4*bSLR!y$*YTE24+_06pHC*3{*7&#-~Zcu?@4oYvJNwWAcXZtf(;xfl4AOE^jx{fLWpkacWn(h+ZqQw3uF^ z_{{c$>*4+J4KcNEK;1xuvT(O|uVz5xL} z0@keq2xwG_X7RMzFcni^DAy@QuxxFw$P`1b@|}x7YdpNOD3;mGs+knRxDWxU_+Zc(eF52h5TFORt1KAkZKjyGxpE5kHdfjMevs;=#G*P=$GYYIRuH%}oC?gSn$3 zzw@~0jLH)Mi51=zPNq1UUHA+F_D~sxb1mHnB+50|)SwoD&zJr0RgpQqR1{$uIA>_7 zX(!7y-nu)NzR!Mxzmw@x z*1!1>J4By5$+KG#@HsuR4exZfilC<%fx&D>wk?htY^3<;Wdz*waO*m}HM~%#oP1%! zE(D5W2}*$(<=8>(^x{fJla{9p^j0o;OIbhc@Ovo;e|SO+!)4Tdtv(Na9B~XI`7yJX zWUXk7X;)%EyOLT`j=(3?FeKXcH3C&$gIe1EE&^@c+9%*`tiCON@sA4O2XIB&=8j|0 z*>V7K^NgG^B_DJFvV3PcVf|}E+cT$(vT|L@pT$x*O zRuuAlL5`dprh_7G#PKDy>n@b<$sAJGNtbhH);()Z17AC;EBWb72>2>UAx({PsTD%F zu^MuD4+*>VH;mjt&?otHd`=5KVXDO+Uc{a5%kL>hU|6%0(LEi3@gy#3S9u_yJ#mR? zjT(U=DQ29=;2@w}xDNpjMvq(b@K*D+`3S_vX`puxKkFvL7}2PHECXIQUPNb3EsxLVbS&(Rj!2 diff --git a/test_recorded_images/29.jpg b/test_recorded_images/29.jpg deleted file mode 100644 index d8793a4747b51a8a3547af737cbd8972ef01a097..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1905 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 delta 1163 zcmb7D{ZCV86n-J1&1q zhJhl4bx^k|%TU15@iiPU@1)FXfFR&jK6Itll}4!TEnRm@d+)oue_&zB$@%3x&pFRI zc}_1|6Zpfd4?J$G!SYpp2xuimB7383^2L1!d=XfV*)mMv$_7rL$@aKUtlNd{LQG3`olsc{$XeZLG6t7eUoR+mvzhBC9$Jj`C);|eFI z5MXJ?ar-ph|6Bt!vgp|o@-Td?e1Mq@Vx3p2QR*?+1|Q?bYIsVu@j5$_QOrM$z_@-D zw<0au~wPftNG}YcQ)Rj=%@l(SC@xASdUmyHv$lVt$daWSbQapwky|7KLStc{tE&(f!REyO-r*h9)1zu{s|$CBE|;RV~esQl6}X0 zR8ILh&)HkgBk=jM^kuSzNYx?`m`_GZmNSIMD`KYJdDNpgxgM7K(vP!C2kxA`Tp1vf zHe*`~eP)^?w(NpQ5-r{*wyk9`%NotXLdIR54o2{sSsDc1e8P3Jy<)~y*$6n}4_>TT()Y_d@b;-tr24 z41xMHNe;D43*>O^ct@%gugtw)>EGdo#w=-bPj zXR2JZb`$~e{8N?Kp_q0I^bW~V_MQ6J)FF9~`4aPJC;};O=x9GZ0!_OSsF^BHprvQz zUJkP>Pk;cs%`Wnit6VZh#JHhZxiz6_TM+F19)a5h-tfxKoQ1dsP3yIT;d7xQJ_ul( zjYQG6m|cXsLvDpZy-SV2m29C|9V|!-76?ZZ5!e;~4FaP32v|PE+q=93qmn}4?x0;u zZa7FG7wb5ysYA*LLsvBBDTHM`C*R&Eq%XXAIw8tu=Y=VkE`_{2iUe2c% zYyy2jsZ&$K3}fP1O5l>zj~{SddV(mabuL(KJ1clIrL{eR`;on$Ij-jJx3D=I3g#wt Z)Fo(Xzs)GmcpHIB-Gt*`J`*u$;U6s-g=GK$ diff --git a/test_recorded_images/30.jpg b/test_recorded_images/30.jpg deleted file mode 100644 index 56a42369914dccd42205ca9c4af3c31d399ec592..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1901 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 Sq(e}3%`)c{g8nwc@&5qZjNAPH diff --git a/test_recorded_images/32.jpg b/test_recorded_images/32.jpg deleted file mode 100644 index d5e5800d2b4874540d0deaf8d0570d5ac4d3a28d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1930 zcmcgrYgAKL7CyWZAUJ^{&sL&{;uDcaQ_yl(%Ok~S8L3e$WT8T^=wv8bX-BvNbclx9 zj76yZtYTAvUS8@Rb=ZkWIGbJpy0&spcLz0ddU z^X+}$ARGmr+me!#fP(`74)g$U7{mid2fNu_6}az;XqtAl1Ra3&2jmp}}1iF=>YXn1iE}vkQYspJmYjDo>iz z$%$rip=s#oLfQ|UydvH2~AcSy-u}Rf@^ZQ#ZcRM<}?y0-)|Jd92r2px_ z;E+~tFpfPpjZggYt9g26_IJx1VV#Fs;A)o*0c0u!WdXJZbYgI8J_MhRs3Gv?k>Q#t z83ak~Mg_V0H-wPSueAKxR(2dA_QVRvFx^n;0XnvW@=Xv7qr=Z$H76l@|LH?Br=*kp z(^QX1G=x>Rem{Jm#cwhaZw=y(EQIG4iO3B)q80-E3S3vdRY4?u$UU|Y_;O}*Roh98 z;!biM)vj~DOi0bXzoSB>SK`IQdaV@f`{3CU^PY`e7o>BY+y9hsPT#ttzSHRMV^B1m zpG-DaKw#XZI=O&Q-E9$lw}T7bDeCfHN%t z#0&&(2^ijtWG~?@L>?5;SCMrTEq}z#A49XlrU(eCv9Q?u16VUM8EHU?{b@onLO9uO z+)eQ4^!=NtC(~QG^+&0`kx<3WsTU?=PzEAi7W439T``iW(26PVv#(O#=uoK|8N{^B z5NIJV?;L?Zt(3Qk=2f~mZlSKSPd~m7uCxWqOLk=z54qF{EQBu$dfpb1;jzT+D7xgJ- z-`ct#f|3}FkRy5-azrz~yqeae{WTrAlY`$^G>zLlcl)BFpNpu~QsS^in@^n%Ek|%3 zckz)#2&d?BC3tr!h?SKPoT;S(A}wD*P~&FMkX{cV=Wo|dom}u&YJKYV z?()bS831{*x!k#{4dhOJnK}6F(p}r7AvdfR@|IfJ+koo#Vm8*_(J{naOZntN@c0&! ziiaQ&`QJHGiHr$7-OI~LOBGfj75!vj90Jl$+)1s%2gGrKi1<`|VciAgiIlYstpzvr z8}q6z3j^LP%$4Eeq;KfmSf02(>RM%b=9sEMvX-+D^|~n)d}XVx=B3?&fGx)bB=Len ztQS!4)KZ-2QOs(7ir{-O@*Izh%WX$zjP>Z~b=2N{rv^$O7+3G3bx(s}I+250l`ary zKEFYiMg_r`1kulAupm$@I|P9Xt;hYPXou;x9|Uo+YRY|p?$~wr&eJX_o@M!3bhtUT zExXE7xFchdNs|1DuA%}Ox`+l!BQhZnXm3)*M+EYwl*FYei5a+>{H*1q4W;$HB%vhN zX4DjG4uar;4)#3NkIk~Sk^ME2H8qlTb7ja_Rv-3ao@4Xi&%P(9MsNXU^=qQyA&B>}`S73fNnf_5j@Y=s%PDeH5j%}PEy0GjM1xwO3 zqk_|MQLX(I;YY8lHn9)HJ2fZ8w>;`fihLZD_kPfs6FwD=Ng28aF)xQyM? diff --git a/test_recorded_images/33.jpg b/test_recorded_images/33.jpg deleted file mode 100644 index f0ba514ca2f881cb00de3a2850f6fd8667f4d268..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1919 zcmcgre^gUP79Jo!fZzrMBG_syqNr7>M#_SgcUpc#ROnLCC{}V1B`CU-VyoQ)yailh zLv3nfaSeqOu*E7iihurk5v!>BVF) zJXxMz-Y%n7J}hq^*9QIsSe_siq`JBJ0oVz+6gYhzlVbS8+}u5AbOw_;%c2sReJM^4 z4~mIS(NNiiR2nsgcdmB?zSo0=@(z4h;^oa*6coI8 z#mcZ%tJiFbcr)_PQPHt+@d^B`iQ9Ij?%FNbvo|gC;Gry0_TeM>$3Ob`#K}+oR(k3m zW#ZGHO1_kx`>NvnKQG8@>n?u#UHzr+FE`$3YHqptV{6+TO=s6#ZTG#Od;1>u|EeDt zG?+%rqt7g33DV zK|+UFL9F~8!R52d?H@SHjwATaXdw}994y^O2Z8A|%vioffhT+zd2DX+i>VD&suMaz zdtyD=Vf4O;OKqH&s7UD-|4n>@K??R9d9uK^b6wX3=}hPLzs8+4-P+O6X$}e;Q8b;m zCfX_>Fef*km_x{J)yBTtArNGd_inWGMr=MO<@9*vtr$(*oF!aO{I))sk?JnQnD$_N z3IeY&Z;V9WR9HzKA@!VownvRHjp&TNa79lLI^Z5__< z>8>j1`Ak%!^n^fcBOeN<6J5nFS_^?AM2e$aYd-{WGA%MQqJ!YeRsZ*_H92fNTx}h` zWbCN#!YZ}ieGjgGpM4Z#`7+Snx1LWJ@K};nj9nQKbg|h)l-Q&zj@X}PRYveWZrd+= zkl|A?wEY+}*pN3J;jlsAb73wS?V;I3q^AXfk!(t~9nN}WyyWB!2x$4JZ4;_lS=6VP zetXMa2uh;VxEwLbki)v!W!01>9j_XRBrbMO(KP1teV2ni{XCakDa8-!4Ef~guyO?B zN6vqejiL#vTyg$g3VeAb1fSNC!94rd5Y&2&=m@`u5OntI{zU$aGoil>j8s9s)DTB>k}$cV@KF$jo7;!bh}rWeO7M#KfNh4mMdAEm5rymj)X zX-B+M5fnZF#htfR_g2{L;=1|fh z(0zWLDory4qY}h4mCk}du_O}$I;F?G090eSy$FJsXf5fjr#g1c-SbpPiXF0ln|rV& zT9sAhE83B6WfFv7ysPLW1zkh|rQsP62n{#M;=@9DQ%Zb5N_;w|B|d9A;Y2BYYb2!P z%9NI5%|H;M*RW^Fe)TkK8_{1YSyd}pGgF3)9_mv+pXEAz1k<~O)d(h3J2Is*mI1O$g|ugBNT@w1EEoAD&`{RM}nE8F8=RNQ~ye028M9shRz{xf~O zs#ht1DRPuV~wsOn=#RinX>!`>$Hws!Z!vWt<9oVLe*Gi>b72*6Kb8 z$#hRLmG4R@D5yEz8tP*X3w-ufPF$Ph{@$kcs%u{iC;XoGh(ViH>J@l_z*-JLJcmsz TJR&5{2&L!dB@0Lq!omLlA)?wD diff --git a/test_recorded_images/34.jpg b/test_recorded_images/34.jpg deleted file mode 100644 index 2ee18732583660c8019b74fa27f56a4540a43468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1936 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 C(CK~v diff --git a/test_recorded_images/38.jpg b/test_recorded_images/38.jpg deleted file mode 100644 index 182fa0246fb757c4c72bef0fd7496a2e23da3eba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1971 zcmcgsZCDdm7QTEW0fG&PAn0loQ4|Uyh%6s6Ps>*krAv(SX$5-mJB-G zf@xuCWen=hnrUTie1Ja!rUl>tj){pafL(x1fz#e%QVjnI6H_yD8l6GC%cKgLZ75DN zGm42u(NNX7R34by($;R>^B&zUCW+ykxz0Pkbu{4-_Y39+|v4>?cw9juI?wYp5CV~`v(SJ4GoVd zRFmqde`=;@UjL$-Us!yjU&5DHpaNJJWkUeLfuP9A(16Yi2W3HUc}xa@T?FAJpDTqR zT&flmJN|{>qLpp>KN^ZYLGZ%?T*6a1Qh1E2?IaySxufXl_(okgqH>&1UdRz@2j|H? zO~#0%qW!_>v4`umK3Mx^zp+)X^t=q>T_s)xfodzJEDjRm;phB5UfuBTg*`VrF3QC} zL{^hhrPXa*sB?IO^6G5Ez6q;U2*J_Q<7;$>J-TlQm%5_PhL)(>57u_69qlK@O=a3h z-E|1m(ajfE5wfSlyZ@0h1gT_iW6Mk5z%PXkeU_Qqry>JWxn9ICUeR=pDHmhto$v(+ zEJGz&3zE7fV%6tF26dFu&b%!@`DIO^sh)E<1Qim`fUIMZ7DVeaiQ@4IJi?o&m8w6) zBdGQro5+FrAivr(WdE3}xOHw;qu!i|@HhEC|5TZeB#9M#((bPtNjr3;P=*Xk6fF=a zAkZBegFsd%>d07WRxbJFD$DytGf0|zn5Xt5cC*$(&>2iV+w4y@vwJmCqS^$3Ameus z2y?60y7`Wb-y6tu!GH0J`*#RhxO2}jwchnUM&8n~9*f5Bb~uYPfiYDsE>DtduPZe@ zH*@+v=iREafPk+fpK})@jb`V)3&FCp5J%bCK?p)iWysQ`9D*-){@<(I(pk8tL_2m@ zDXs3t%4Jsl&+5NRJA*N8=;+J+vvUeOgk`W1pSg}lT4*4cOrvBwXsAYJ3bGp^Fwa7Dd(qAvdHv$W z_k!XfDDaoyB1Bb+oRY6>sh~8G{zge0Vq?AHrfGxChYsk()eLfn5KoaSvdAm0#RwMR z_x2<4=FL%dh1zwC@onW0d{#v|`RKofpweI&X+U&Oscx^tp> ziha^b0mv*}N?-cEfjFcp(mB6h7#$^asbAI;ZL+$T4X7$sVqpFaokDa~q9AwC|>4~z5_$k5D@G6UF3Fbh#$NG;pc?pR^O;QAG52WJ-b!q zk$Lkr&uM>ddMP$dIJiCzh~U@mttmgAG}YW7*u`GmyHCRbUmL0_A`;plV2Lm;fzPsW zcP{xs70LFUkSyz7Ay}-0D2X6~)1~Nwx)zXm2!aD-q}32Lv2IVwsFV;pslStv(h|^- zdeeq?Fj31Oh`5>Vyle_Oj{-`-lOW(KTFLxVTv1a@*t(doL`+6}{_vs!rS!ceAO$rG zGLpFjf%8x&YlR$?EHV!egO!4vl>)b=B4p}hzhriWZLp48Ji@I&Fs@|Tp~Dd!(%*yN zn}j&cJqqy@p2fj5d^?noEUoU@U167e?zq!g`is!7to~8|U~BKhrSOyX zf9_<@d%sq`F|f!Y_Z7D~IUC=tB#OD#$n0t?<-3RbLadQ{XU(`H1SMtB5Y)|}i+i|z zNAixK(mz0O8ZA&ZUEoi+b1#nv-G9Z6Y#&HmKJ!REX6f+r*1&=D!(;p1RZl4h_ePv| zC&yIM@9BcKsabZfTZ@A|PP|ymKAW7~ay9<;HH$OTmss}I>NPBVY%@0aGfBe>)lomh zC)1yfeuTYg@(N5z39Qv}lJ}cT+e>H4V&c>Hl{L1k-FSEGrvUI{#kCdcx5^S2O3;}~ UDdpUuD5~Qc-Td4BDSkNeE1s?Mvj6}9 diff --git a/test_recorded_images/39.jpg b/test_recorded_images/39.jpg deleted file mode 100644 index db36935a21116aab476a2b0fef49a32ebfdf1cb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1969 zcmcgsYg7|w8vYOxE};TN5pXq#AP8QNOIa>5$8u}D&{DZ57N%4oTy$B)3*7~#fJp;4qv3wtJ&EQNY9m026uvI10kSDidQE_f^I)Gd1oEGc!{&CWFa*dzo8WFwHH^ znM@0og{74-=sRncm9_B!{t8$YAP&TtnAic>1=ut=<1Hr5@SiYQWopJ?n$z#H=z=C& zn$y&jW@6AZbaf$}2WEDRcQ@_Y!?cf0HFwQj<6C^8%3|~T_dC{p+=sjQeRi_M(#m0- zqm#4y77x#@Uj6~^1^zxLI6NXUD*6M?-h*-R35kaeCmlVOmd?${%*s1;`pnt<&;L|< z?k{D$FVFM86<+-7rOQ{Yif&Zjy!AuP?H_+?c+l9?-176o*2kS)-A|-Xd!D`M9~gW& zG&~|#PO7HS0K;~ z&QpEroDoT7+s~s%TGwg(@V1SCV|t(Lq8xIYf~bZ-xd~U4hl+`)lYuAn&i~Twy54?P zCjNy}Lv<*uZW02m!yAlSZx{J}WUX8P4rPtMqdmC2`>J56Yu_ItE-2gf*LJBK*G`HX zFKam3OAx4Hn$GGG>S?=g|07oj(y5*Y%`XB%E(#p_EOXtbI3ek%5Bb_Bh8edC#myI; z2pt5L5fZ!^Nq;9=@Ap{_eH3A5k;~r#^QN%$9diT(m69F7c}FD8h{kUcBMv8VNnfs} zL-ipMO}FpZNDa(~2G$;@`o}!PEpxMK)y5Qrw;`zab44+dDwgvo`>)qi_Si_N6d9Jt zn<0=xpgk}KfwW%Kp0m=VSPCpuTv3qdnF*NdwbJ?`ODmDc95X#94&t4JLZTkYodB-QSc zLjCl5LEl&0s(K3ucv`9#UEmnaF4_jcva5i=*qT8IB7{<8X;KEkx1Rs^Dz9uCVuwUC zc3aU=(~Vz~TJ=A_|6|5+oMp?zUhJNolM~?-s~EpCnb>V(Lk97bvf_Z`Tups|-8U9)_SKNJ5AZr4Y%Kt+-Uunsoe5K^|b^J>te`gYAb7*hEDRwM9T2lgaa_FFnc; zJUa00N8-z!qwR{Y?-moAuR(CWnsV}6{0@Q}mXk8lt`~x?LD_2R8PeDl=5kMjenEN1 z?R#48mmvfoSGbhD^iuL|aX*&4%E& zhvrl`1kT9+E)hqh%qZzu-cVX9UglB(14Gjgkn4C|lsi7e3v)(z1>uD?SL;v5Zf$7G zZ&7Z~y?&GHw7W1{h)&R~%i5O+o**GFM3Z6J9hgp4i%ryF#_1~5N|jN0fW|~XARb=ezXpPuwW@=HAGLW*OSY1N`R*=-pV=F z9NeCM-IlvQMPp8qi8I|r`80G94U|NrLV(I!sNzgi)EFDNCN?q!my%z#o;6^!zEymR ze@7>!SW6JN4t3hBP=k^M)?RY(2H*1r-)pH1nM&)I%&xEv)`<)8XeEN9l4XZ>M{H=Z z4ubEK64iAyV&-hhw!x;k^_<_D7|rvivNK&8GU{U8=EoB*^3p(0*_n>x->eQ!NL%~o zPWHU-E5#dw4OQm7;#DtW6FU`TIckl}>Jwi^hE92$%8g)Vi*S+P0ql>kD@5xs8frO;qTbj9ZWv>JCD!%aXxK;Fs{)0_Qj-e}_ V_pk}!$F$yAWWihM=nmk>zX2B(?s5PC diff --git a/test_recorded_images/4.jpg b/test_recorded_images/4.jpg index 5a37bef70c7a2159e665bb45ea56a80def866d96..695b7c1db89fa4c1fd9c7cf6b7f70f80ce5262a5 100644 GIT binary patch delta 1212 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 diff --git a/test_recorded_images/42.jpg b/test_recorded_images/42.jpg deleted file mode 100644 index 45cd7290d2c79bdf5b4bb815f1a38a22f2a9f817..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1951 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 h5|z>+I)iFP)rWX@;pj2XT@Za1)-~<2w diff --git a/test_recorded_images/45.jpg b/test_recorded_images/45.jpg deleted file mode 100644 index cc00964485eee29a3c4f7e5a2a141d49e7651e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2034 zcmcgreK?#~7QbT5htc(w_)3^mganZU(^;b46<uY6 zXVMvlIw5yPOhY5x0sajz=^zqB>gkyR*acW*aDz87NrYcTZ;L*~fJ!6pGD(MK6B1Kj zpF}bsVMy;x(hex524-&`^rMGJZs^!{VnFTS@&4uO3_}Y`D{GtG zj!t{_I(xF;;r!Oi+dm*MDELT7=*h^aQ_(S}W6zzxkibh!x|sIyCs)!lu6~+xg;mve@BO8w_UmsNA2c<$v_5>)_N23``>C|2w{LLh#qdufqhoUA zlxq6#GqZF5c%@ldUU{uu#n#rL9ME;NApnnrAlG`c5uF?LNrT|VgcJhvVElk=u?T{o z4wVRZ`~|^;>$|icZRUQAU?;t~xSL`u=M3rFNmvAM$IHkuOq=C`hx)M{XJX?(a#jlNs=%rtP`<5J6!?g+pv#;~8#e!3K3LwKE)#tp zQbTko4DVtBjm2w}CpHcIb6~w(0Aen_d`ok3U-xanYFF5Y0foxPN9(&(R@c6VUM&d>CJi`3*?SwfxmLo+*CGr*s z|!w>`%Ns-kl83bSM`M-NPCmUmKl7)#{ zMMq7yx=d;~^t|Eg#1GU=6Dm6R?);)0^Cy_u>bj}uZewHID^DrQW}i)65VJk5w4E(_ z9&c1K9(IXlEl*uxuW2AKy1fyO4p1~af<6PmR3b^+(ajoU?s~=p2q=JW;Sw3v zQ{a(U1VC!hYVztgjrcKTuEzdwPI#EWp7Q z_(NcW{O=5rSlpbF>}A`W9MKw&V80ldg#fqA>mqimNAi4aki2XDnKie?pG53!e4Np$ z+?QH@muLNMW^$2w7PoME;vJk`BR*<|jmbN`e;#%MCv*CCjd#*n!w3Y(%nXB`>#@vDoS^R^SQCl(i< z_$4K$SSL9ak2+V?PB%CJ+KG!UWyuAH^7pw-X57o~3){+%D$MSn*!j_#-T8a!URps= zSQ-w2cn)1T$Q_9K4@i+E>7}1${v55fJmKeK=6b82S)B3nj@%Po6w_P5p`q4?P|*PExy^LrgCLY%(;Zy+K9w?+iUsipYMw)9PuY?ews!LM7E63kTy>_<9{ z*NI`t3NsWRuHx^h;ybVABGVU!B=hU6O{3_QC~h%V9fQb4ldX%km6+j(k|S_smkxgT z+Oqx3evj3|fvxoL*S1$U$3wBpy8A9a`Y@`9=jjzztq(DQN@f)^ZzR)}U2^(eYlXq~ zA13ZE*X_8^=&^F(_i1jRhMtH`(h%;dv3O9MR7k(qCVFqEy0v(>nOUC&=cDMvlXqqv hZl=m!NpW8nZ6Nu73TOm_y`KmYOZ!ML-4w&Ie*ub82&n)7 diff --git a/test_recorded_images/46.jpg b/test_recorded_images/46.jpg deleted file mode 100644 index 01774a3c288b90afd228681a71cbe81d3f0d462c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1949 zcmcgreN+=y7JqytKwtv}B4{xRDt;7Hkg_0UPRmCcQCwDP6e~HX5G=JRVhh~^%mQ7~ z#TRuNZ)f!m_V#x63|))(p8(4dB!MIw8+QOZ0G9@LSjD6({Ksr;?d%;GO!{9IozUb) z*R->vD>=|*=UfH<&O@>EeD$_5^Gq~_Vm81V#4eefk?!`BSoH$$Lw(kjjJ?xL+5z#TRalE(r`wk_&b69ZXX!6NZY3ZVj)9+=U`{?7G+)w^e z{OR9HB%ggQy(s_sAEjmgyrihEx%}PtwO6iQYrLguYHs=QcI$n0N9O}g*TYAB{Z9s- z4h{|L4CBU$Uni%g|MlE7H^1=v;u2wAhC1MAr40dO5(FhamPT}XC^8#@Pe(Nnc<{(w z+F3aSaqUJWx#c&6P%Qf|erPEOi+Ji2{v74>8;GOX@>s(&;<*)scL(zreak@$x9e4;NzQk6OhQpJH-vV$G&a4^rJr z^^;u{dA(nVs_GpfkeH|*;R4?(cEM{9nEhk~%AFa2AV#i1md3RZT-^G9&)S~JCW5e; z(JT7)+D^P&hlD4&qUZy>048rPEUJrHyZX#YSxLR1}58*VCuf2DRL z#dn<#$&dq(C11*1y4FY@FqD}5-YQOrmu+e=FOs)4^?i+~;V@=l{T-b^Of{5OCIpXf zGpT3@)*}DAKoXHMZJ=k_x42ko7Ez&32B#n(*GM|3&G?`sYAqtki_WjTRR2-pw#GZT zEr!6XipwIOH}W&(_!P+rxF5lj)a|)memr%esZqL(yRzr?$t3WNrKXaXd>aC`0vD3R z3ofxkNWEP{aYM&2v*{^-6Of7C|tjIYRTE48dG17dO{C zK%o7qftIETf(a>Nm``Crp!7WnfdkFQLr+vad3Oy2Q4t!-d61si?GMW6kPJ^-{7!tT zIifAS!cDY4Wrj(Tg6YnJTpGH721+JUArR_XsKV1ih3arcSxG<}eq%{$98fL9v#xBs z_~_WpmSA&LSFSO#HK=eLEty2W-n6% z*aB-GIZ!R#S}onaRDw*T^cO7VEP1BeT}3?x5xrPR}-$LuqLs^whs%-W?FDa!-{+ vXV(o~_V~cHY@L6OxA)joKp!SR4JKjZPK)Oe1m|Bx=RymjtcS8L6b}Czf4J)v diff --git a/test_recorded_images/47.jpg b/test_recorded_images/47.jpg deleted file mode 100644 index 0ad1493fe537f79a1ab846f6bc46084652c260da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1949 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 diff --git a/test_recorded_images/49.jpg b/test_recorded_images/49.jpg deleted file mode 100644 index b5a99c6396b0127fe5f601cd09127ba378299a22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1948 zcmcgsdsq`!7Qa9qyt;tMdo>mn@Bu{-SsrD!g@9DWwW26g^P!d?(Nc;JbRn~dB`sF6 zG%YTnkOESC&_)nqk(Lwz11hG76bNESLIEr21P~@9jTmF zR#YZBm4=GWqx^v8L|^virgs?5yHc6nS<8d+ORB6_zuVC6@_rw-Ciu`N=WJ|U-P}Dq z*ZTPSty{l2WJ~B@!os6t*s*b2Z6(7M%aI zQ1IF3MPG`(`nvSezskhbHJ59@tGjabTI0>8X4$PDTW;U!=Z6Z-Ya_ zDvee*{`x?eGi?YU5+Nw`Fg2o6Ly_4KoF7#{;2cK;DrZCx z#J1}sgwG2E7cZ?|_}El<0>O8ObBF--a6t+c+d;a`HF^7xs=Mm1gof#yw2eIZhU$9@ue-01moZc|0uX{F@n z_&Ty(ZF?CP>Rn%eM7(7zpG5R*tzYam=aCv_WDkpyNg!RbZI(X zUkZUPq4~5CA-mgx`hW6Au`sS=fdbiU|CI-|n{3S>yGl0l$? zK)+)Y0)YMOS*3TlBYt|N&09PXv8!gyn!Bk^rRs_9 zirl_0xK&bX2n2evmop!47Ms5j0)w{@M_JPY5X6WS$f8yW!Iysj_o($e2RuMNJ$gmm zUe|?{D{T88G+a$ThS@nX&_{1SpHbn_q+LFCU7OV9;6Q{4G|K#t16kA3kl<6d4~QP5 z+Lw-OJI?e_WzB~e^bpvW857Vxnx0EqPe7ner)b-5szavE<=ljTmW}E+qa8l{e#!hh zk^3Py7beHWh(?4QRW7Znq&R8+vzpk!!g?f4lP1TVuIN~CCg~%@k0@2yU$?VPEf!3dijCW@#e;&bu8oNEfb008&geXTyhHp4q}W$;Lln3 z1`fHkhGd0|$qoA75NxlUD2XGYc5p9+8E& zrByg`w;!Bl5=7Ee7e9xB=2Jk)cq#-O)h#mrC`a5}cQxnc-htfU?{X6K$1na+;@>gc zm|T6|sQq-{33zC+{mP+JFOGf83o7!fF8Wy`GqUUcQUHe9udJwEKP?IyjFkxl5<6$s^G*IXdf~8wi1PhPpKW+9d5wrV#zA zr8$Sm*aH!yyoyq|3uW&y=%^Zu5R~vV0u!2{UZU6XGy2T1E`RS}%?3SFzcM+Hg&UUE zOYceXjjWlSSjs~2uLPY(otRS3`_DqpUQqjADl=AjkDT{CTiohZSDPF5di~T&S|6Gg zp|nqVk{hR={9@zDLauR#O!RGv((>ZuM}ubuij!#L_RH9Z@Cv?HdSyg&xklD@~JDQLn}YRS@OGqj)~r+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy^T=FC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu;sx%1S{@eguZX;DuiN-r!g@s4`iJ45gluflI0SZgn& z-RduVwq9rMgo|zvo$5O5Zl0C!%s zrrt*mLkvZjw@HBSV5Lh+s6sc$?|THES=9=C=E#EM&cr0l?L n+;~&S0>4dv;qhOxFZ~o)Kk!MZfATecK2b#!QAHF{MSuU2uXRx=vb%V<;Vp5Uq-PmD zeQOWH-|$wi2x$KR4K(de=Tf+mTX#)9O+W0ruJVwnGZiy)897kd&fq};qyGSh&3G^V ze07if6|esQBvJnW51Q~_{P^o1_$y!jNTdEAHQ>Mb@zy`^R=<;{1tXFM-G4=1@W=d& zx_AA5L;nDwivEhL@~i#}2m4d}7X72NKLJ|&Ch_HlvieQlqW8;X=6>i%w&4lhqprs3 z>0b^}MHEp*72JFsw)hlo8&LSW;@=VJv)kT8_DQ1Y5nQ97Ib!AILcD>{9xL@P{vQ?l fBL4uI(O}T_P6)< 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 diff --git a/test_recorded_images/52.jpg b/test_recorded_images/52.jpg deleted file mode 100644 index 7c7ce043b0f1104058338e8feeafa13752c4a9a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1955 zcmcgrjaL&_7Jo>>w*~peQes8XB7&e8MatA7!CIACR1~*lMIZvFrYi{e(M&}e1YIMt zRuCnY6xm{JR76|_A_R%(;Y36YAB7OUf)vUGFigT^-ac&qggtxb%sVsZ-uJt|`@8qT z4%i1Aws1b<05dZH%+Ld1HwXvw%;s$FoHu6-^SP7BV3;#3m=+fAUQ25$3rlND3kxe- zD{GrMLtl2bHg7m zl!=Mbpy+RrA21d$9X|}*XyLSDzvbe8I0v09_|eMy)7uR$U$zlTR>vRCwzhF~bN5)d z)Mwf9k9^kzuVt@W9}>PPf)lyop<(UFn^E25)bv~Z3~4aJE?_k$8wRMI5C}a?ckq#p&@>2gdK3^iMN+Gjj6+NsOppQ}a-?Sd0J0Q5F%tMqDlf^`fxXSXMn1+Qak8hui zenRx#u9}TXFBPb3q$OvMX3?JM+F-4KVG`mgEOPrAKDq5LO7Re+bR)J9JZ5J?;8mYu zkd3PF-+E>Q{OzgNOcHFr_^g_!4gDMfyV==QSz6jbHtvHGWzrwjh0`DF&*F-whPt#F z!>=o7cb>il0?FTXO4=!tMQsy2q&x8%wp`RvDwi8`n=qTyV`XH1YSB37?D;~E9L_$x zWbu(HPGG69)|+N2W`pszB|4>vtb$-LAJb5HRgB3o3Q4CvgVCEM|F4jrf5G}5Kv0z- z!7apYjeO4)Q9;e+KUO{R`@{o+%`?)PRE<69Z`ml#<2r|8#4sy2jPdG-;!f?$)~+`h zQGq!@`@UXz*OQm5c&^eas36|>dI&Z-Jra=P7t%x+8;n3Fem z1T6MzE!zsrnxlH8y_L^&Y~lM&c{cOc`-fgoXuBu1Ua~EyrQgRwFzvq)g7XkGi^yG4 z2tFNT8SE*<@_+72j@BHPWg+^|?go={~& zpjGTaQX@4cBUpq%%7j39?l$U1^`8Sf6=w^9_=5w81zM>VXIws9>xOncL_yoAAh_V$ zdCHF(X?W&3>wXx{ zEXej1W-J;1!X@(K?|}U$%%J?`W%<4{LToUxUG}??WwMKz-o-7&2(HZFTJMgl^fw{6 z78^5s(|JdP^NyI>KnT43uOi^*5RAmj$|@-xB5s1 zsJ^!PMb|e0zxplOn{+O0XhCr}D?Z}b(wSWRK*H_fX?0$2*zuE2?v8xB*vi!dLv|4@ zi+CREq<%MIm%iK`+gd(0o+BJ(r=9z5)v|IyEd=s@SpwI%{1)C<_$AUbg*x%BGE^Mw F{4di&?B@Ug diff --git a/test_recorded_images/53.jpg b/test_recorded_images/53.jpg deleted file mode 100644 index 37e7ea0aae45a213e029fdfaa30f5bb99368885b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1962 zcmcgs3s)1@8a+S=;bB3ZV$s}+BEEP^shG>u3X$3>iy{T3np;tMEiXlohhnA$41(04 z)QVWiHEE?vX;eV00uh1)WpM*iZUU4?00~+s2?3mt$((y=`xCnQ&78Al*7?rf`|SC? zfl4?6>~^!?X9E)x08G#Y-~iYOOih+zX*OL7n%UB9PNSL8=;n0#@5929LAS89pwk)F z3`?t}KubQ^wOEtt==a6N8w~gN?lwDp)U8?TfA~bMrIoYG3fGnE zJl1<|*tj*|?Z9`o1?>z8W$y}me|O}*sE?y#_8*8la`aeyLSj-{`pJyUtn5>H`Db|r z=L(B1m40>k>nmkf%Y~wEzq?ua{jJ;gYHI85*FX5_VT-i&Nt>+w>9glOKllDmq3r8d zjgF1Km{3o?e5IY$&CM^oCiIK2A260|!vMJt0-me!9zLmLr9qHCD1*RZ7wIFPE`@;I zJSHGLe#40JMfZizjJ$M=hz#P8Uc-HPu_#wcIfrlt@PVN>wQNkaVm3~f!=LJ%rMf3l z`Xm*P9t^}jbeZzkJX#$%Xz)qqrjVP52@wRUw=~1&SptH6BJj9j<&4hvdQ+xc&=})K zN#DjaT}@jksje#*&yasoQDKiA%-D|aSBT)mvcoC)|@tSC(eK@ji_&i31iTX?6vo{)uL7H+WJ#c0_JVBG-(l zj__Wyxl{NdFlh@P6c63*&<66}Y%R1}w#|!mNv0l{Rj-!pMxXTT0SM;2c0f=9K^vcl z5<~FbI8$#+B9(vnT4JQ?w5R};SjHP~;4cJ(B9bG3Ky!%cKwOa?aw8I`RoZ0>6~`KT zLvB8s9v#lFYsHZ?^aN|42XLotig$ zLDYE4g$zz^#&u&q;3L(zehr_=O)@V#3KWBGfS=y1^F$cdzRZaJnFvJS-93CbdYe5rXzQjg*qq zr5H`0O9B#vMV`Weye~c>PYvAp5t}E;?;atPl`6(NpIUp0h1!pTr@* OUeC_c7 diff --git a/test_recorded_images/54.jpg b/test_recorded_images/54.jpg deleted file mode 100644 index 17a1b92a20b450ace73d9d5fb019a55d136cdeb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1975 zcmcgsi&qm@9==EtURsc+C^{=3QhCU;6lIABM0|2AQb1147OgyTTGsLuDYFX*0+t}w zf>22%1zN3*3W6&_gdh<)oIokdYas+E0T)UF7$#&gcW>JL6ZY(H=H4@N?(crzcfa}l z29CffV0Mgklm+zk0MJ7hfa4$-Y|_((Zr-E|n!awP(`foM2A#q9eHa)SG7O9i7z{%b zLnC8dpr_3y#+!97@C7h21ZTh*J-w{}b^#25(|^ZA41a{)CVd*6VSx6UpoAx8h*Mu5 zG0_nX%Kiea1KL))`EJi3hQ;ZR4eT#jdj0*zT|^13b&9%Pc8g#2y#9Icm!W?SkBpAV zre|hdyjYYgqO3#M?u(aiPpG)n^^-0V2sp_j@zZ{! z4|a_yy9L2TQ#%Mc=~R(64+6`{1_%Pn)DS3%_KXb(4lYxe`@V)3*hu`0gxq6}Qb)9v zzSv@4k&rSE-$LZQKOwoHt!!~46d}oU%KjvMRDxL=%hhVctaWMJgUoK|WSZ}AgxM`}c(jlwRbF(<2*DCSfyv96chw9RM5 z;??$Pt1Qo&g69qtCf4}k1CC0GmS}`vwwNg+@x~~vc{s98TEe8l`2VkzAAV#`J%gYz zosTnkHl4|KF5zC?b$1(IxE`{FAZ%UG!jYL0?gpKLBDQ4!Q!$4X2GWMo#E+l<(l@q{ z9`2d%75k}MlU;nGxPMqKCcWa9{2>Ujc*!Fisv#)iQ?}l!Zy=~OnwF4T`yl8VK=$6& zoWcia%6Q6f4ua_fRQ)Hk4b1u6OymYF1y}muBBz`|-da#V3Dq26PLIk8B3wA?JZ#{j`*Sei3&KVai#{%h}_P^9DU-! z>HYSueYGcmUU&F}VDetC(yw4gSCR1+fA@fLv3z_*zDsxvebTFEAy{({f}jk7ZY~ii zfZ*^frZy#!%K!OVVub7pzYvvJ`aAF7zw(IT2sRG_#W~D^s1TjABNC{c$}Oszi)}+8 z^{Ld+6XU}EOL;4$ z{I)C`GLX}Oug?64Pd&iZ_FN)+I2QuBI2yT#4!RPGDbxZw1d`H6$ml13)Z*$n69{-a z&m#iVEj^aFXzsZUYU2Z9%6J%pa%Tt%`!e@a*=bzT3i;!B8UoWQ1)C)PjS((vD(wDt zHfhc5s2ID|RzC7ZU6mSi$MecVY*oqTTd6e&cBOrAx57a5AaEw+=x1|7zKmv}_ft-4 z^wRpbhtiw1J>@J`M`^v#E1|a7xwg1X##P&KUX9X}iIZ6>9M$=?1+nCuu+jYjs70t#~a+-)c>%0+)?_g4Y7V z6dn3($*afb=m%*mLE3cxsh1fH0L;u zC1t3xg1x_JmY-;jX$WeXi96_=T%9mmY9t6jHIS^@hx(*WiOe^O4X2I@e3XuXyYjkh z%7{~{H}Vt5E37S~hadGh#;9Wkj??1~{4H$#UL+^vS#fVnQ`?<~WfQF5F7-2LYl2}O cksY;I0zs&?DQTX>Cck8Jze4`#ZZ;hK4?pVk*Z=?k diff --git a/test_recorded_images/55.jpg b/test_recorded_images/55.jpg deleted file mode 100644 index f788ab1cbf7407daeb4adb9a5f977d87d2fe351d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1982 zcmcgs3tJOc8a_w}R||4S&{-}57DPZPRkKd55-wIL3y4ZJD^L-5Dz#iy%&dSQh{j8; zh)OD{vTA9nz``mJAzXE7xJU_5E&(LyLP-E&LMC(eVD~5Nv)?>(o|)%-^SVH0M5H~h8x3sps=<0se^J}lPuU|Gg zHvW1-KKbUYa&~V1-NGWNT7vyRZ`n2+P+<_{*l3;*lTua^1lfZv5SaN>o|5Tn5U}gV z_>}YSI9ashxbU?mCmAP0w{j?t;l8X$lq;q!cX0-YfgxKZ8<$znM$cvNrg~=S&WXf6 zQSr0tfyk#;Q=1ge*7^>rJrlTzl>0C#fIw!i7{0*blk9JNzf!NBne)0+mnPxY?)Rp} zAK{9Qx(&2gQ@9bA9U|gfC`ZvUd}2RWG7iB@<8qIwlQ#z!c(?8kxk(^MNR-Bo`cj** z^SJCf1V@eSAZXB`^E6oym=Bdgu>Gr7FqR8#1K zO||EVXw%@8WY))nk}I0RXH{eLDXRKS`*B(d!OxOBB>BrYzM_p^u6q%eVW{$`Zgps@ zV(4+XIykwQJ6t8aRd6z$wo8`#$hizn4iS%$dp9SNd;Tja3WE3nq!xlE-!ur;*2Swt zZ+nT~1{b-BdlSCb2=F8Pf?-7sYc~W&YPDy&oHh|nJ0qerdVTFq`p*jmM9T|RZPKFZ zCpX$UcA*Ud!C#dU+AIyD_HdukeMFV7m?te3i@mb|i7j zA!Uy3Rh(1fNMkK(AEMJqDbbMS5RB*JGKwgV(3l1z>xM7jbb#RhmGa<6eB>zv<*5RK z$+v1qv~vsgZoYT7{JHxlHV_0X3ab)i#-xXCgD{U{&cYQFSnhU4PfE*^npf@pZ&HK3 zvb`g}+E8H^8`sj&D{rB^W2d)3u*6PziM)kX(9uxgI)-(x~7oF;GfPYus<2bjFB+Tc8uADC5QN#heXtPLEz|d2Let9 z1d~ysl82NM6`+BjwNfFbMU{z~6ylMh8KVnjsDZpiS2Ksb#~+fOQl?FSK} zYl$#Dnr0u`MvLx3(9uNrg{#7mU0Iq3v>~^%ANyMw*DQTjeBg}pOvvfiPv-Dsr^v6f zXF__TljnuG%Lu~HyJ~Rt+Q54Qfn^!HmE#c?kLUdEMi}+i#Cdd9yV+h2%DQdJ^pBU< zxy13cD@gYNneGLa|AT;EAUJ*~EigyQuC@)beto9#PTwzHXTSJ0FU8`!^0?F6j@UoF k_}kd`M*43!LR>)#`>g1EcZ_s;B~q;xVeiEw{UX@+ANZH^ssI20 diff --git a/test_recorded_images/56.jpg b/test_recorded_images/56.jpg deleted file mode 100644 index 6adbe1228d973e9eea728301e512962b14f65cda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1944 zcmcgsZB!Fi8oo#pz6AyOu;{FyNR51psgg2UC5o+ZETU9Tja4fG+s#@&RW@@31VPrQ ztP5gGDp6Ur8Wj{*J|YB(;^9O@B|sqrC_yVr5x2^Sxgkzl zTg1dfG${KoXdW=;G3PG{ThDUe_Klt2VUO_RXD`|Ne|D#3!IxdSr4jqS&vS6}^z!yu zxGZ3K;KwUgMXu(2vS#gujWN7Un`5^mY){;=GwG{c`wx73F!@kQYI;UyR(8&jqxl6V z3X4t_mz*p6+xfqjS6ry9mR!DawdNn!uHUV#yLZ3-!9O3i%G(~dE1o>M2;4VOp~{Ie z2zV_cVk+QYI9X}(pZ&9?FaswO*7B)fb#MM|lq;t_H}d<5{=tv*JY3^#*guskdiTme zcZ~^pWmOFi`gcF{dKaNlMTV* z=2WBXZ4dFwz2@Eo3bOqb0b8B5HS9=Eo!J)TeNIv*iDka_wh)=ph8P zSrURJ_G%UQvg5(ex@WUyVUw3zR~#dTv?Q8eRKrs8hn%g(+x zS@B^7;k&;Js`E`wQ9SR_DyZ<}i8T;xbbl-+{VzgLETMfOW`BU7+F@8p&Fh4qtqa+E z!5l|)G4#o_{TKwphfwu@VX48#^Ky_IjC4Z3ijW5gyT#M%xnDt$w?;-*;+ir%MQQp& z)k+9jeAU!e43$Ei*5VfLNerD9&;cUyfU+;0KDqo9uG_>x{j-xBWe%jf-N?Mw6rnA7 zb6bet%FgO9fK7Y+fOPQsGd-v9qqbs4mo>rMa|&(0LAzMC1^vIR95HO2L$z{(M&7r$`n@-#;IGhwMy85I$;uh;b$l-j$ zX-U&jFDg2%g_s)onHaiB82vs1u)B@zs(rpm9R_gc^`5Q*E`Sj)+ z3;C2M-csIozUiFmt+6s={f}YCZevq=zGQ)M1i_jiIGd&^vJk0i6Z48ND@WA&+BEn4 z<+t}~_KO*8;`0p={Yi11L1ni29vvO4>kpUaMZJ#k*cRiFIO$A0c~(R8OyeeR>G*XS zml%=}hM?R~2&5C}KwMWR?c5buT@qL=&Dl@$zK)`0mmqlln21UIZ`7$>R@eo{0trK|4^_0PyMB%+S|iTc3Zk+`);_z^^v(>lE=*#Uc`%A??2ES i*Lp1-mc`;4J^yZq#UlyV#a<%}k-}(X&WD?Tz5fO@)#wud diff --git a/test_recorded_images/57.jpg b/test_recorded_images/57.jpg deleted file mode 100644 index 9c62d988af8036544ab07c2a186fbd44a23db054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1933 zcmcgseNSaohoLt?ksN{`x>V$5%KRwh7$7F;N>OCX7V)Xj?g?B@8CGN1T3056Vas4KS*#b2or68g&cTkwvUjp~ zaI_kFb9Qocwtm3dz{wuOfEXK_Spc>G3?*m2$cYeMn#~Mb29srnVx5pfjVr>mwM9rw z1cSUkL;HX+i#dBi$U2tW_7ClRlifoL&(;Np!4^J=exr_W4 z2fV%{Y{g2>8>?2Y-w?^&xM}m2=$P0YaXa7JwJ%}+fy9GJ{FKzR^o-2IM{@Iy<`*0* zEGjAe^7L0{%FdQoO24~Mb@BU4KU}ZAQS)={&0lUcD_UCHly}K>!SCJbo?h+H z@W{ha-J{1(4C51%&!?tIqY3r`d#h|Xpkg4%_qJRo9;w4qAjs=iLg2QMTBaH+g@D^M zETR1W#L04#-_$3T{8XHbUd^L|G(EZT$X7voY~b|~eFLu=xVYA9eBVU2_}PPTx^q<6 zBd@5t*%yDy^VxEJ-F!~Jd6_^Yqyjah6awu6z2vCb~ll^j57mWoixp*5>Cl0HqMYEBs+ETUx zd)84Xr)NjaBy->BSDmty)zuEuN2r^RJ3gk>5L{IiBFg)dB>HwqwcQuE7DJWq?J`H- z(GOg!Hb`x%4AGcngB+bSc4- zcs2`t*ioTv7tUAT4t&!af=$!1T7lMu46+*&21-#G{hrL_0*sjnfZbQn@mvpOJX=|u9LHE$z2 z8HPmKeiVYCgQ)x8v0TI-4p;Z6JvSmx^F_Vu3{4go^+0J7^O8sa7v&pun>HWiFrYkN)k;GfrcHDOHUeo z?ga@CO$wrF_$7T++C!}5QBGyf;kB28iUKN&mQ3g4Bm2ALPfeJ`Ic_qRSApw!a-&D1 z7tuX+1%hvP#f`RbJUt$k4`dYIa^G9bjVX3bR-2+xY(S+fb05v!y@r;bhu~f-5gGe$ zT=<=l?%N~hWGS%m(8rqR78g37ZCWBzVPvp|I?i*(pPF}|@TKgD9acsGmj}F1F=w_x zAbUhihVVLLMX^NF2k2)*zL#foBT1 TN(`31i_VHqWn1gA-mvFyGacUh diff --git a/test_recorded_images/58.jpg b/test_recorded_images/58.jpg deleted file mode 100644 index a00c012a26e4f2288d6e8208224a2ce6fffcbc36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1937 zcmcgs`&Sd!8a<5nZfEsS=+k^;A$Yf4WZ2y4%aM%52&RH|-d}r@{ z_I%$!6?_JqwsN;{0fPYm16=?PfK6Zy!y49kjy0Gz)|tg*+A!HHHv9G9*x9lu7mwt>kGUG9BjdMu${qh2CyAq2%PmA6EXZ5j5#(;7Mp|iI-rDFC&X!E zgP2%|24(*ntplbrYrz}Ak!+Xvy&Rvzt|7Pko!b{eFkyLFdDtdwzNHv{%*F zuN@kGJ~FBs8-HP#G`^aeo*_-Mupii3ZNmYz9Ri`J zc7@RLw{ZRA=GC;^QXYhBKOy)lDBl(g*U?7{bXCZj!cNz;^dG#KqN*PvC%NL+j zm8Cosd)ZaoLNAD$M;5$2s61;aZ>Srlk5YHXyFQ~;5d5SpMv@Qk#rjUMjPnJq#n8!< zd&~(B^y*tOb6jSXKvO5JEX~cKy)t#7IswxnBvLUlc3nET?Jr5m5Tp(uwGiA7%Z6Y{ zbE>K3MKAH|;EW(WHtk!B1m7zz)#w`|-iKhW*}Nu4M?1Al_#vWf`pu?I^t;oggyNy8 zDPzWTGk{*0GTjM*AEBm+5Z(qf)#1g;;&iZ(Ex98uhE{H3dZ zJS#4^Fl6_qt82Vc_=?B9It3MyG7%0zl*@fF>01dwv4r+qJN-2T)pkQl%DD@I_HJbF zMRP3C%`~LYwxbXX9YWRrf#oVbmY;*%U}g}8b%fkc&?9~o8SxPW`Qa^O1+G1h^Odtp zt5!kK>ZPH!VW<>pbQY&LcjDRUblOiu?pO9_&?i@%!u6ZOQ2!)GykqvKdz{GpHom}y zyb&Mdv#P851HkBr87S$mVcKj?75 z~O{h7qh8g0pGbA`6kKnPpuTq;^NU#z(sy zlVg)19>x!#eSrB6j) z`Kj{6!tKU}(e-;R&9+}M!VEuG7re)2adc9!^8m-t^- zFGL#4Vj+-@5wC)I-8%$1$TI6&BZ=}ej0kVfZc|s!JUTEc7>l{1wNp!Oc8rhn=D!AT`!&z|4(a;Y z;t$D&A&v96Y(O0~y`_5G`D4kq;mIQ-8yk;5UJ@`BL}PAd9|*dm(Z7{hQ3io;;_wI( JV7(Jz-yaTg-BADl diff --git a/test_recorded_images/59.jpg b/test_recorded_images/59.jpg deleted file mode 100644 index 546af9664e0e11bf3f5d19dc95023b736d6429c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1919 zcmcgs30D(W6n;n&HZ3T-qNAXQ2H6BrM5ivqr7A}eH>z<#5zta)RcPiE5CoT~Xhl>~ ziTf565i3iC00BKTA|L^T5K!VqO+ax%CiD8D{Ri#oeKYU8Iq%-@yYGAV4wS<#V6~L9 zgaeF>05C!Wz;>_z3^OvAVIF2MhOuF0G8o1T7L&#L`kI)TvP{fOSS(WuQ!{geq1A8; z^WlaM_!wB2g4JNPk%*sBIbMn-0 zr*qHb6$me0x_ss8wd?l^?-xBNe)z|uN=a39jkLDz$@9jh<`*sU);48#&#TwHsyA=n zY5E5~eIEQmYKLGOFg3`A18Ow{8IJmU#2a~FEClHtQV6UUQC_mX90)iSJp#)0FPzL9 zavA(tpAmm!@-pf{o4jo_#c}4>4x5zR&jpG!}hR8 z_8+FJOUC(k=)9tNF_gQ46hfe!pjI3T6p);~{=0RfKMr`GFHe*S%GUYNk{P)AS@|?t zqR;ijl^co3$&`!O03XxFlf8oAsb!(Zhka){2Ki?%cd}&=M90V@y8S6%>>#c@1;GwW zCkQH;be2910-Me&5X?QMg+N1=Ck{a{`y-8cOuh0LlSlN(s7a%ct6ZP!hkdBe64RrC zN04bVJ7mZ8xh2It^nU8$+xnkqIRtlPSt#Z0kpgv{pwQ$9uEfyEw>IiRYSo>03w6P9 z`8-9j=v2mj?a-!El|6|d)taJPT$2&ix z)P=^RIzOUeqDH1C3n6%wjVmdlaIJn+Fp^Gj2&Wed|1XzoH}S4V5ELc|36{XVGRBD= z>{D~;Lg8cg?;Rmn{6$n8t+XUPOe#fLT$?~#-HT<;Wi-c2@0B*yx4lgW_D=T++db{R zQ$(cnS&K?a`9$>1f?%O_wSaUv3qh8UcAP$V4uS%+ZW%SQ9)hX{B<~sB3Zj9biJ(n; zA?V(Ts(+dO3jQWF38}$|B{aT-#Ff`5_%ttYJp`$<#AF_>%)ujNL*w(^A*gUtP|Gn? z3inldt6)2#>u3z^$|u8RZL##h$%kFMlVU$6`q z)dY8lI@>PEvXQwr0bB1=%D>Um|81hLLfVO7YSYTtriD1SwJ8dyA2VbZmF{& zB)z5fsEq@pw0R2zC)^;&tWWZ!Q{wrQEz)P=N(e0T)Le>ukCALHz4*pxE@g*ToNhZ+ zc0&G6n-@3lym#^)Y(T>m+G=|ctPX z2773#NQRM~3hEGdIR0L@27+hP*aK^d+N%P_kXA|SOC5LkO>E{h<&R(g+FHw+b8A;! z$7l?N%U4+D3CW&Zfl|P+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYm;N6$;J^9t)<5u8zx=K!DhZCf5O}zMU9{QAv@PQw72_y-ymoHUN&dV&-@48yI+&91vE(&V@v-4 zg2(tW`%<^ETOD6BPKYz6FLnd|ek=51zdV27zkl*Ad@%n2ukBm^06?^_%~~j;iYTJ5 zcw_!XT|552q5lBT#eYRrlQ9MqENan36j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t7pR{sFdEi3a@ij!LgLx1wC{tE~DQ~VbFqqIK(TKp#Q<%Y8QP2QsS%Vp+%=t#EV z3Ercw#_8!_4pBuEQC9Q_^hvebD11wGaR!|Cag9QINQ9Ed0b#w7Sb)qIBmzJu10uaK zygB<81tmTyd_gB11L12={zp%QHEA~bI0HTWr{s}cN{zk9I$|$0WD58oeum9Ph?B2uXRx=vb%V<;Vp5Uq-PmD zeQOWlr~DOu&t8j5@GpmaJ+Epyn%D@^-VHE2%3_4Gk(+_LY# zv%FFv%1Ij)Wj>&el*%ZgiYTkz7?ZOGJb&}Y{tNg203z4J5BmPqzw`@A{MDk0D58og z_l7^@Wz)aw`XBuaSM*h1oiv3If0EfkX d$iMVaVE+KYCZ+!X$kq7yMHEp*6j4PL|Jfy;;RpZ# diff --git a/test_recorded_images/60.jpg b/test_recorded_images/60.jpg deleted file mode 100644 index bb43030efb29f36bb3de1f8b0dbee11133589c60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1930 zcmcgsi&qm@9==Eto(jlIEIKV9Qc+%__+S~W5Us6pSVU2d#)<`j(@mA|P-tcskeAj7 zmWtStl~k$ERFTD1AwrOd9vV|>31J}wl%N$!!ox{2nY%Z3|AamL&CESB=l_AEOGI~L2{ z$=<=y8tBd0$l3w#zX z30xZV;j+k8tE1MeUAHMVj=g!y$6FJ3B<)cyFE-d~^n)~D=O zX+}n$zZlbwzkH=POijv@+i*bbfS}aJa*G&OMrT7%GAM(g z+Dm^^-IfvaIm|rc57|Q%mNfRHdbM z752KPLPF1vpGy|68I)I9YVWm-(#NPfFMIw*D+VN?0)eyH9G0)8T_qENh$xT#uyqstm)Vnq?6I*m z`>pXtFufpswi^P`e!ZM_&%>x~{Cjji(Gn#UDC?zCQ&}hOn02gytjwyNV4pmF#;1gx zLY()@nPP|6m)`fMF`0Q4p$O2+Eo2h}&ns~aMKtZQ%#TObsZZea7SW%Ta`_rQd>4YI zToJ(%dUtSrgX1H*E?#JQuzZ6L1Y6#UTe37RWQbjdxPs#mjqAp+vKYp*9NDe=zxJqJ z=EjGYM5KJN;27}4b60NFcL!%?#EZx!5HKr9(GOm~w1w^IZ#{m!u9HujhnGncN-9$z=|51xm`jCH(?--j3cgiYx=B2VKef;B@>m8B`O5SeNd^CCY}5$BN*=UE`d z3=uEYGZq)RG}yFEEXT-DHFbjHjQ?)l3Bl79!Bab%3*E4yG=1DPj@yl#HIZo{p@E8# zuiyATUfq>+`uKh<yACZcCAi4tV-TrH4v!^YN%}02#h|wNfV9y-sEZV z+@%#z-jj5kxD=bQTqVZ6YK&K{GCYzdoryZ3`+>Zio!4m#1rVu z-Edpnvj-stHHh<5Y4+arwB!Pk_mGH7GA5zb6Vjogn}2h zrf^r**gvvKD^9BkXqvrltxL40DpYETS^eYHZ@XBu_JoUYK#BgEX jhH)29(^=$jrKO4(Z)ivRv<)3mRaf-}q`-Oy!~XvQHjUg! diff --git a/test_recorded_images/61.jpg b/test_recorded_images/61.jpg deleted file mode 100644 index 06dc81853011a47eb698f8b7744fd1eb492b07d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1918 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 W(84f`T=7z7UMj zdtpBu1&-S}+c?0&0sss205}9Tg9R4zF+VPt4~FIZ$Yd}q87wA?_2IR$v1VD>Sg}~v zcGfnw^MStX?QHGmf8ax4XAR;(yoJSL0J{K&z?mN~5yKy0vA~kSWLcrLb||665ph~t zA|@uHLD|RAJYXzlF8MellI0Y;&&untbLh8Km#n=v-R^Mti$deGX8(~Q8(UX5caNnj zd{_E?vTE(RPuZV^t>3&QinBF(+xEElgk8H6_avnr`08NVq4bQb?4vokdB^gLOHP!Q zl~)MPp8Lo7@2YDq)HaBIynLnc>b2{4nwndFX}$Z;d!5p*?jG5r$4`Fk`|bI^l>GyP z>ap<`FDE9aUcJ`p^t12g-jfC+90b<$w&8$^hoIEMe219o56^<2WLO4)(^e{2K79@X zPRF>A@_mbwwMOr`Z_K6HI2pH|O9iS1ijz^Uly=?19U_KCKGJe&k4Rip?4^~W03$#5abIl}(hv~)%vaA!&xYky=9>Gh<8(fC_f_v->3#@)mRBIjU!@B*kA+QEf5+7rs(gQ+ zDejSG2o0ax>Wk!3zPdriiB9<|Q%6I@L*>ju!pDQm*}kkKTiz zDMv)Ggl?TYPyd+Ep39e-9GXs{WRQ;T~c=u#ki zFPL@`3Whd~ww{1s>=5eyFU*bjR8bysgONpO*Ah}+exGnQGJFpNMPU-M7FVCc)8)oL z)vt!2!&61=z)&kRPnsQLT#3=sJleOCJRl#;qRUsF#5G&l==|&s-(d2i`y9!l&UC&d zc{4W1YjtnK7r>$?W>`FO{i&8+`cYSf?ZU9Y@UybXA>HJ1$#%4*Cz2qT4UB}~33!0s>|QDf-d%*Y@C~fwmJjOAaSSR9<=1x8@e>K+xf0 z-Dy!39EyX1C{1Zb^J zQ`>UKW}H=a7dIJWLf@*tjHY@XdJGDjms>^3Q(EexoD*j3iAPTx3FRzqbQe!umxL3e z5<(YH7>u~5(fzxzS=^g6uc<+tmr8T?ZlEQXkkoD>D#4I|DlIl&qwV;LLF{ig`A&H{ z>7L`hGqD9P@96PtpX6^!W@448*|XxZ4+w&{5sQWjZP^R27Vg#Z%4Y|rXS@o06xrps sVxM{5KBBvnvT@46#aNBp7MQDusfG@;XFJe!RdqwF`(R9iz#k6$2Ro?ae*gdg diff --git a/test_recorded_images/64.jpg b/test_recorded_images/64.jpg deleted file mode 100644 index caf4a7bad77b3b0807813d25cd55747eab231794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1921 zcmcgsi&qm@9==Eto(js_BC`S_73HNgRar)>MCz&>7V!bAsbWRobW;U+2+eE(dFhJi zS`aF!q>7JfD&XQO5Fto>92!#U5?~<&l%SQ82f`$o%-tK?KcT0;Idjj zd!Yi30_Uxqk2%1~3IHqg05}9Tfq7Pzu#EF8!LYWBOa{Z6!D6yl?_L`_Tb7NT4U1*# zU~6Y@3H0UYVDD)8fe(R$E!YWmT3IawunS-aocRtDG5i`<^Q;+6mJM3#fD-OHBTj2; z#Kc52DEkXE4;TxXi}R654$;cZe7oc~8s1Ri3(JeSXE8=Q>(G z!5a|QJ-9cNbl>C6YRv;5_OK~5ozJ6IDoG&(s-+s`sYn6IImZ6Xw0K${cBwsECTQCe zPD?((HNEYtXo!)cfctyiQOp!7!qn0f~sS0y- z1oozUT=ZVv68sg6+d8RlXl4I_7~;gQ>alXMV*v>~Jxf=BFZ2z=Vp z4C2@Q#Q%op_`DtI-WSv(bhh_dPT+cwdEo;^)SpBmaS z<_x!kXwQ_{ClClf(aLC-Y>e8@e?SiqEo@1JqD~?)mUQ9v=_l&R^7QH{&grw~y^1(V zM6K^}JtwTLxYduwq^1Z$?yr@Z$tDP1l;bLjXxeRF6pO4=p2F!E;UAT9{X2a0J_Jo! zLV_jm=;V0^#fEoZx!m+{8}P}39OMQggV3%aBmw+B!OX_Uy$}?v6_Yi%>O7t*GybV= zB?KMbN@_cXTA^8Oc8+x?M$ho*fC}=EY%qf^U49DJY+Z{2@v4^13sJ9(?<=$@#GtB?Cu-)0>OIa;VY zBWye2K}Dr^5c=`&h|ybw!MB3U?=OHrE!~4$M1|_2F^xgQgg|!Y4l?@guf3?>?*M^d zNirfpr{#$&A(?3PK*xBUl(z4O;9MXCB|SMIbpG)Q$_@GB9|wU`jfP8+KVxJNmyWr) zm`l0i9aV!D+RiCn8)`B)UJA?m9@A^NLN~)Wf;B-2m>PfWF*NbwJ zY0kd&wD>Yo^@xa0FeIR&3eDGP2flm|`^PQ5OO8&m_ltn(xV)E*dOXuV>GPuLxc=nK z8BxhQgz{ga77XRvv*%yS->2o3&J0XV`{wz}GfQvB^?Khqrn|gpRf)Y)3a!bod@;hL2%&zMvT`x diff --git a/test_recorded_images/65.jpg b/test_recorded_images/65.jpg deleted file mode 100644 index f4cb6c6a1e6a76f2368f345dbd136c6b5bd0b7a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1939 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 diff --git a/test_recorded_images/67.jpg b/test_recorded_images/67.jpg deleted file mode 100644 index 25cd19815a09980a95016d62effb033198cd486f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2001 zcmcgsYgALm79J!CFD=L$i{>hd)F=o@@ew^zAwF)EMG-+=HB~7P(%wjUiZo}*Q$Xcm zy&@EHOBAnKjS5`6ydngN;GzMM5}*(Q6i}f}0P%#JoVi2WpZ(c&_pCE(X3d`cefv9m z4^+ZoV0D1Ap974H05C!WzyYuaEHPTN#d*o1(To>oI*n#bW6&9l-#!yFQ-+C|34>v3 zVQOZ+XlS+6!hGrC20j56rrI6AFZ z=epkQgAH4JKJ?wXZTlYo0M6ch`ws*k4mlDUcJ$ck@XsS6qj=G=aq$U>NoSMO(lau% zE@bBvUis$gKd%*CFD@6~xLI-Q-?#5Ps;sL1PtD{1);7ypp0>)LwY9(Ke%bS5ud=US zJu*7>^Z3N%tJm6@*}1p#?+D!j><6ZcvSENc3_+%o;SoNmWXD2~J}8I4W-qx}F?|IB zPSdD}bo~V*iWgkw&lob}Fd}$6mvmS4r5#7UGRoecJAe-iy|3k9YR8$=vnhE~Ju_6- zxS&s3R`+<|c&)>fx2A5D@1TA&Unn3qst7Rz>eU)mE?Y!!zViK2zv9Q8Gi32d4fM=dCAQq>JGN{X)eU1kWui-KWl8ADquCsTg7@Am9s>kt4q3 z7Ul&^eHDTTOJ@k0=~T8M4FcPtTM+EZ*Fm5q8WR^F*zqgHbl-662~!z4svy@{BUh!N z$cH)Aku9aH1D6qLTL%>dhN8NfQ7V~y{Ho(0loEmmiflyrbDl`kCaN^KgsGV*^HbgW z;Afhlhn4!kxH6%tMpAO|Y!c-hH{mlOq!}{tXeM!Ji-0)z2c=UGL=Pag5IprwgkV); zv`+fE7yoJSoltOy|1X0WJ1M%T($us64#85resj_UWhI?zv2Mv3uo%0uQdAqJ5 z_MPrNi*k&dZ-YSmnN~sBBr?f^!aAxCukn@TDa&NCg{&6LoS$4yHyVhzI2BH#zu^dcI;+3HW>p&!(Di@>niT__Nx4*}RYaysi z5aSGyL$kn{73kG^^SjC?8+SWFu%OBOh?C5`$ z5a^lib^OasRnCz-d1vp0ob-yE-Uflc%~KKKQUXD?m~!%-{}zIBvk?WkyaR%kE+p@D z{UN-Irj4Xb#~~PrLe>AV;TATTnuOG##p2p6xXe}9Et>OVAB7-wo0KTV)K@T`V&QLP z8zE?NR*?sps1&Lu3|4{m`0!-`<(fx?EBa%p3+r<+&0b&BKcVa$dN-=uib!qd35|(+ zK^|*1c9ee%j9LQ+B|~?fYkf1{Z^<@aw#}VgD4!UZnOG$~fPQJlF$m_|{UFGPpf!&O zkwEa#7*l6SB9?#o8829UPMn2GEaAQP@SjCQZ!lK`f#w9$hPWm>;Y>tPE49n!%OV&?pOxUixif7&4_Zi_HF=;cG z#SO_0_K0Eq7K70??t;r)&dQ%~okcS}^QKB;eOpQ)Lhd^=pAriX!_gb7iVF7_? z za7lZt>01BQhC=0QU2&XWspq)|%vmj0Y^NJVVf7Fc@YPucJX*CtzbTCF3a||dusbJX z&Un32y){@;nXH8k5(Sg+P?5RZrPv$&5eParv1X6txRvL)-5qj70j?c_Kr)HXd2+i# zgh?nNA)gnL8#qQ^0<0~f1_V?UZA8d6S^Kds*JGF~~jlcjEVD=!7FWYFd$y&@tdbSf8u0DDW)I+{yf;^uu5w5Yyq5Eu6S4=uv}EdT%j diff --git a/test_recorded_images/68.jpg b/test_recorded_images/68.jpg deleted file mode 100644 index 3765d64587d7f637dac308a783da88c6b1f912e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2008 zcmcgs3s+ND7CuPATS49+5(^3x6a*9sGTvGgsZ(Sz_&}MGDr$sOse*uy=B@&Q1PY?V zfKW*#3M~|)0%GM6AxKacjYui4LI@}U3N;}JH{|A?IoSCLvu2-l&pLOVeZOz-Z|{9! zKO6;SdqO@90XjMW=%5AQ5C{e$Xt)2Y_ z7gx6r-M4J@^ZzIyFnH&#klmr5?up#D|G>ehLx*FJ9Y4W385f_JbS^n1_56kOjLVr> zSF*X+uK%m>-$lhYO3L}S?^IO&@MG13+PeCO4Uc|)+$L&&+9B?I_WV`Puf4zZ^$!fn z#>QX2nUGITO)KYA^Y0cG3H1^j1P05pVSwBRL8hJd0Y2Fuln6n_uowc1-Q;G;>~#o2 zTE}^$%byrgvgEw*l{Pa8BO(Ktq^EQsJsSCnDC?cfA$(|LjWPt2+0MnPF6Gbk&QaYH z2?N5i#z#ZZk8Ngr6^)Mm!7Ecp<;EV#GrN0Xw0eHRexl zVO+svg%F%Db%3CaPGxJ;A+Q{&gkbwsH3UkcC1nYMZEq=tr+eiSMn7v@LT)feuKn8L zt&EwjY$0VHzLH4)XjoF9EpBWWr!J6>rn*j3{Se%fWTTLe$MF=;c(wZ9VloEG{AiCR zvQsf~zg82TRK}4u2ugF$r&10{@~v_XO`D0wGl;!g5{R(>hIABy_#qT61W)}_AaHDn zR|}{6@ZX0QISG5&-)s5U5nirT(G>J|2uw7Z&8c$AOgQU;h*GEzn}eypE#%_j=j!If zMfF_|%9ge83Y;vX;V$D{(d%aSkC2Apf&BbISUVBh$9*(4w=3rDP|NrIk<4@S=V+d-K z`M4g>rY*t2BiyIs&aK)f8$Y&#AaqgCz?PX3p89QqY^G%prkG%4ZKw5~6F+GBwQF!H zIovzLC;HT;ItNyq_+_75O!}~910dLG@svk6mqL)ur|f(ezJs9La7;q3?t-Ab8_9b^ zvls8CDOr@k1O#IzQTKnQt;8nNQjr?8L|nNA7rAhHc=J1g4ndF>AS6mK*>x;Vvb3&j zBLuAuQZkHzTA@y^H4C@KNAnUWmwe)wWH6Ds;+lggcKf6GIT*A}<3{zE5ov9499^O& z!pmu6SNUf^rz3n=FjDnG>7Ti#J=!Oqx;OkzDZIv3KtTYl#gI(6b5tZR=Mpn-32(U#`hG6SY0RqO-^MuHG@PGwE}A z{N@Wbi@Xrjpmjd7ruGU|iini~XJU8!EwrE~eD71C#Y1O%of3MNVX!5}=CRA{w5 zleETKiv|muuk}x>OOkfn^uBnHp;9vWR_bvCtAU_^Ez8p4@zN#w9Zr1rF3X5rRu@H# zIiD%%JFO{|>9OQ4kT3`@DVf7G!T!)3fZ*jO57hy#TRGRQdc+n16zzpTFp1B5GrRY5 zQc*%26#il22n5W*2I`wQW=UPdGH#4QOy)jL(c-}n+~QK)YL%EWUWCA@Ph`48^$O>W z_mI8iT=$NG>iED_HSD`_HevMP!nSaBV61m%u3Z%C(K>tHQ%9HInvRdHkyxeXO|e>p zH!B)%tP2(WJe~Z#k?>c)&FR3I(`AKTAU9;f&PhFAkl8;LG|~ zb;jpsd*ok~el9=oWyPzrd|JUTzW;pNp5vA2XFvZH>DpKS?d~wYs^h%qdwGLL{3d?C z6`Mj&o>?akaLx1JmDijsia5mfE2@2HzUGJFUjo6Cvce@5sux#VfKQgUqN<0XA6`MV Na_+sfS2}b|` diff --git a/test_recorded_images/69.jpg b/test_recorded_images/69.jpg deleted file mode 100644 index 033c04215fb6e2ede4a7534b4e4fdd3fecf4b725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1980 zcmcgr3s)1@7CuN4o)#43VbQq-L@LTlk)o8jREUpT&_Ne~BVZp`qq7>T>zdVI=&r6z21A#@VzO9o9z6qnmY#tgi=}U* zZ(z6@=*`&3(0KI&J_JVk;3zn%qq7dc4uBzW<{M1J@O$X2(Pc1MdgxyxlyJ`!aq8+K zCMKdm*)U;Bw{62my$buCCqK_HFto6=vfjAG zVXNc2+je>E_I%H4&ptnY_WlD04+R|!4mlQjJS;Nm)amFmF|i4WNy#ax=hHH?E@tOk z%FQb&{if{O@`@{!)%+i7Zq)wk=8yHlhI{{Ry#I4kySU>~r=;uglVAFt_5XKZaA;UQ zG5P$()bz~DSIPy|;_IblQoRC)f&Qv(IG~O~kZrB4CuRn{6ClVMl|W#&pK_JXl|sO7 zo8(ar|HsM76}zR+wAqO`8MKE(Im?DJ!%?o7w(#SO5F=x6E7`c*Y9Uf}p=h>$f$p7( z9}-nPxIYr!WI4N2@nEy(sKzyp8&7SQk$ec`?vjq@tE?^;u&yp~XR zTD%)qJZ;@Ui?tOlxcp-xW-DbUT7{1v=1QMK&}|}go;`nMbgAg-jWH)F1aa|$(G#B3 zF6-Uu z;;L%xcI|85Pzfn`BsoZN(T)@v8!a?HJP#T1s~!{|?v)Hgrt8Ge}@ z;Fjec{^^beo9GzH(}8IT-e{x9IDA9D)ol5m|}LOYs=#%HOKC zL(pa;qYh)J6&j|srU4ejcws#4P((&ahZE>aTk~_vNKL@o~@>_2aFL>lY5QhhWA_6lb%f%5k6U)K z8&BpYWLft*lZ&rKy?!m&L~enAnM?A2u=u6bHEgKmVqMm`P@ke3U41)mv!YziWiAx* zThc5kpSU(cHTe@UUPq{Hi^vND84yfMLXnH8&;@@?p%yS9kQUxWM&J9r7gZ5P5b!od zA_6omkIf13RI?=-<2@4EZ~%f5M+kCyQeEf^Nk!BK)+}K`!^FaR%>0)fb z{iW=+)`ZS>TG=L$Vx)_V%I6s4ziL7tc)G($6_V#zo#%LK%nAXNAAvwHLoB*+dV{&C zs30zqA4Z;lfHT}ke-*>2YzSP%jZjFaf~FKLu@8dld34?_m4r50hQM|}Y_dZ4ix!Oz zQT+(DE?s6ilfqqFub7Q67H0mlp{e9xQde#He}4YD$!{jK_DPy6n9Qu~surY1((I4- z(xU4~)FZ+_SRIUN%GBPZjkvwT*q3!&v(yFg@h=?a1JhsBtMEko@Xxa50|z1#7X>*; z|DucT46j}*yI6PD$2L{d84}hVuQ_$Q?E7%(S>9g8@cbU(sokYzR`!MGDqm1UjDqg& zDDhQvAMbZrEZ%5!+auq;@mj0TCxM$Df<>>XyJv2NZFv?F)>AV(mzDj>GokQH*R3_& dW(dR+qA1Ra;~iqW^dsa=EOh~u`R0a0zX3!907U=* diff --git a/test_recorded_images/7.jpg b/test_recorded_images/7.jpg index 38ea49bbba8a1e556d466f0e7db448eaddd18706..4636fa74cfb83e255c58b263ecf1796a0da462d3 100644 GIT binary patch delta 468 zcmV;_0W1Fe4zdrhQ3XoK-|$t>+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t4%`&Rz|&@C(TR*I8q219@HtNsfI`&0ZD{iC!$0b2Yf@#TiH`c2-V_seDGe&|TH z;R)WOuEy!Fvdq{+m#{przkywDt7bF5eCj%nA z8&dH1>~$WUaVC@TGsm)BEDmj>pTicajV2Dz#9WdAILQFuR~2RAO%X&i{S#0B0EA}R z-s?`(o_oDsIV3V&M9mpgb;(h)Yv8EK--FOs>p%QHEA~bI0HTWr{s}cN{zk9I$|$0W KD58oeum9QRyYmA8 delta 446 zcmV;v0YUz<5Bv_WQ3YD({{Z|Khs6FR@Yjbv8b618Lw%>2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$e-wYi=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnrlc>e&we*XaETKHlA0AJd-{()&qh^i^M;Kk#3_`4+wyf7kY{{{Wy`SLUr0QAHF{ zSG+O*03$A){{Uam{{ZM>zoM%As{a6j!T!|$00qBj?GM0KzX`l~VXVHBcc{Jc*?FJ3 z5-qqwcc|;JP`Y|o!<11)6j4QY9|vu|1sjIcJ}&sT#CmM@_mMr4Xu3pKDCiDYxp`2p oAanOV diff --git a/test_recorded_images/70.jpg b/test_recorded_images/70.jpg deleted file mode 100644 index 41dc9302491ec0b015d6d287ed4a8f0e64fed9d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1977 zcmcgrYg7|w8vcMJTosg?AUG8iDR&U1D0S8f(b@`!#VeeeRjCLZm$lr{%~Zf3mx4-_ zTT3cYS*tcxq*!hd0z~w%5s`8$gn%WY(k2AMgiPk!FKz$r-#z=z%y(wa_s;V?@AJJc z9EOv?W;gpoHZU>*zzAIcj)5J(*vJru)z}aW6T`}6FiaRMCX4m^V`^^3GBr14vCJ&Z z%qsBoxOO~%>9GA9rl0iSFYQ5^s`)Z3kSzlPR{E+ zHh8}46})M4$a|q%c7#W;ckcRdcg)^>`wtvE6niZG)8h#z5|dKX(lau%vUBqC&+!V* z7ZzPA|MK#cipr|$I>EK;H|qa&^V@q3_Zxp`dhla&r?{)TNAjrm@w0*FgFg)okBrKv zreFLrqj)*{N;R)uc&k|?wM%dmm>F!t0kszbo|FC_@p3pU6@vV62?Vw~sQ~F*IRxyE zX+GugD^6A~xoiHR=cVCf%oYyiCmYF&L%CwwA)GTtj7_Xov2ppT`D5xcWp4)O>He9N z5m9Z+gR!_~$2S|5Eo(x?bpgrT6v{_N3LucLRmzIP_$2$Ykdr#+-_(I$w`WTEZ3lyB z@n&54wB45$>nr_n`6oo;2FhJzfKM6aN?$3xEw>3A05!e zJW@{FZO}!f)pBJ`!kUuoEZQYau}Q&Y=y^mEMn(pwkbC}=bQFT5F{BoP?vP9f*0d*S zMX!d4pT`%uDUr$F=mq!@eu+%k8uk$cRytikmV&ks&3PcAO#0on9rXK}5<>D=+m^bh z{mz?Sm7wW`K=3z}l(x;ps6E^kdW2{S5tj|uip5I>UARSZP90g4Tsg-sxlrzu&yFK% z+|t$Tz*=6bJB>+nn~45(Dyg1qfZ#wtP|x+N4G(?(;sn92MPXC2+?w<=?GzSr?80#63|6p>F_d)wsMIPn0gbQ|kjk zhl`BbgP~Tquh82>IS`YjDYQo!88018rO$6D#+5rm(EJ<-+p6=V2W-gP&P1*Wc_-T6 z&8M&KV_?)1H7=a^_K7Nlx4Ns)Vp*tP*d>W#Y+kWOv>P4ixmXAm{I)}I0fL?~a-R@_ z4_;teYYM6SpYJ8c$WIFjP>W?OUrzkOCx>DFeJc>hy*^QD5e z97k$fatEQFzD-QtA+&B~d<3S{3Yic{OYb718~^A<^6u>WId8i-fiqg5Z)T1OuM#3B41;qH;3MJ%b7zt z;2jmCm)kB4ztUExZT~v(^!J!r#Sz$RrxC0Uf{V%W0zHu=TVh`4CiO?yMMv157Gv{4 zv$D5(Yntc1g%oEU*uU=THjz_(KiYtMSSg`Onltsp4hXIm(M7k^654VR0=FTt^%6ZOTCm(r z4ISy8il^&x}t2H}!W^+N3yy{w&*~u|p02?T(MbqzFYhoLfedChPx$k8CTYX?3=WbjQ7i;2~ zZslb*M|N{Rk$j$Q-1=*g*H4A%_E#DbPj5Z4w)u;nr@yf>pXCT~B`F+nq>Fqoa@}*0 O)>(uZoHN`aIPxFQZTfZq diff --git a/test_recorded_images/71.jpg b/test_recorded_images/71.jpg deleted file mode 100644 index 44671ddb6a0e439d89e28cc246064c3ecc43fcc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1982 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 F{SWwk2K@j4 diff --git a/test_recorded_images/73.jpg b/test_recorded_images/73.jpg deleted file mode 100644 index afcee572ffe8b4427626b2e88ef41271582c5d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2007 zcmcgr3tJOc8a_b6-GYK33T6dGDhP5bVkuLVTWN)dMFC+;Rz(q5MdcDin^^(5*9fi) zLM1DyXsa|T(pV7?f<*9PBT$wQ7D9k>6KcYBLMC(e(C$yzXTO;_&&+eadEfVY&-XzI z908`m0iOi`EiC}F&;{TiI0&@0)?#hdUJIJe+DfOx_Ey`vuqAO)N3DG0Ke+ zeuOFBHtnW_nsOIR{w1EUleBAIgHM*S#p4jXF{yK&y?ASAnNwLa>?npHDOnOf>P31m z@-g{M2u_(;L(od63N+aem=E8B!1uZe0wvMJT7}@__Y}i<*S(hvN&J|Y+_3?rN;Ku3 zjM=V&W@KWt}?dImxDJa`8k45#o_d9Qv=M;}9ecBDD~_@?t@-wJA~6 zJkyW=duWB79Fp`84G%lUEtV->_#ki-# z1TEGw@(=^H!qZ8OX{ZH0axIy%=MZsXX$qCUvj|fJdZGD=^!ZrrK=qmuS*;0d9ileO z#n!2-`U{}d9y-Jy{{D^9D|bs#4^l?GGVMWahkGGu3N4;)!64( z(>XUP%c*ZqFZm{JX^C$`?0|q?K=8h`=xN#$J>)lquo#O3}h2qr~Q$VF7>ygx&s;?p4zUwe#?QiTr|M3m7A1h)M`lU1s(dC@4C z>_e#4g}YXAvGJ3=&F@wj8so^tBg~sjMHD9GjtJ&#?huCkaxadPXIanLCCjE57x$F| z{sR4wC7X1w&|u<1qghMz&RGFVUKGR0--;=3S3T;Ko%ykc#F9PqS+^T(CL@x|61;Uv z{V!B~Qm?S#7Ssrcqz5xB>8F14&S{rCveM7+&cy|u1An<9wtalRx^`;wueI{8(%-a6 z=?hZXbpQFGqkj^8-F;|_UZB<3w!dOmUGmd3;jf~X-WSw&^u!DunEAZuC%Y@Q5hap3 z(|qmw9X<{qUAwaSOaGG(rLq5%1fAuv_D<<&XGXpglfI72{%9(T^e6*Q7b<`+>RdAx I-F!IkAG;d|1^@s6 diff --git a/test_recorded_images/74.jpg b/test_recorded_images/74.jpg deleted file mode 100644 index d28dae37441feb1b2f52dbd8cd57df5ce5d65cd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1985 zcmcgr30D(Y7Jf()!eWDfEDF{LiYS|GomP=jk*G{dhQWoFGo%$2Ax9aT)umI@fI*NE zfpI|WCL?hf+g4PdQ4t~piRj@(pfhX@A%K7gW5QY?m3s5A=O@gW`%b-6@4Q>z_ua4V zgPGe)l z#6&bG`&)Dm7|WQ}t9`e#Y$6VuxSY22`>x;y+jYmIhUI^3)2#77@=b=RnVr3Z)h9G2nhU~^TnpkAv;64yLRshi`=*Wz`>}m4#gflc0BGxd_q!kN@`mAnX{Q$7ev_? zb8-ud{&w~6#U7%jk2bf&GJ_*uiHC*QU0s5tGh=% zI5hljWOVHPxOQrKW_E6#)Gfdsz+SWs2h=_YM2?2X#8_8Q5(HU&atLg8Q5zMLMG$Zs zhQyTHzj3m3!FBG>22nCjMsDU)-m31*Xp}3X?RN5eiQfK|S}v}3n2Mb~pFg3TqT5Ci zyQO8dPkN)D*-!XuYFBak^cw}jM9Nb|N+3|L)~GH8iAnA^oRj($AE$kPs83Uf>!SQ< z+2^?CZM_#QGnDw?>OT?j>nK<0B79xvsvP;0GGYL}rT z5SwVtk%ah^)^Jm~ijSm^Z|(?@A5>7*MXN~71;h0t5)@(B5BU0u?= z?tusG5I5HXf#hqgg0@M+sJ+5kx|^us$nv|&WU__qCfrPLww%lrluUB-t`s?DaifXr zE-BMo-!jp2R~nP+1BtdZT7`kEgkU%qS5rjgL4!39S*N;$)4L`Auavt#;RDYgs7#d* zEU|rKqLT;Duld%E$`_v793j{}Ur{4aTaw-;jTJe3+aO#sf@KFYlqvGZ&wpv{d7sMj z&GL&r=~d+v7cYO?IVz|8;wCpiu+!$Hm~_1kL5_rW^q>14f^ySA1+}adf~GcP?=^im z(ZPteZVrE_J+>y$fh zzn&aaWmPw)7JPqncDBNqTnhm+hm_p3Yp>sUsJrgM{jAeb!TGmeb@)GE9rZb#Idxf5 zch;T?7BmpkLq8D%_X(X#K6$<~1Ax7`t9fIuEbRYVBNsIW>xK}l9)bdaI@>@bs1}&Fgb8h-wh^Jr&&jYU zzxS$HgC#BUSlCdZz(^kzb%}3*f6yO*;H{U(^nqOW@?7_O{SFAAI2?kCF=ED--?m?v zjtUYY`G?5E5b%3y=;oK!iYWBbUy-H!Y{l=OJ+Elvys&O6iPw z7^Ot0<+&T?MfmWs4(W#l%wTbFWzQ{*zF=Iq z`t3)`_12hOzeQ!W^kHFa(*2O2`jb;zPK6ej+cN#O9Rme_Ny<}tS&w^o9dDmYZ460S l`Bc8m!KPgrL#Va<$36zzC|tAWE-@7-4E|&a0w!She*jck_UZrt diff --git a/test_recorded_images/75.jpg b/test_recorded_images/75.jpg deleted file mode 100644 index 9fdd1ff3998e7f1f33779a4a739dea6ae8226bfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1945 zcmcgr3tJOc8a_xa+!Pe#V$rdnKt;JJQZ4J0sz_;thvKccHLIcsY&UB`E=n_7z#x|e zg|#3SQc00kt5FegOj%oHq~G+KR)q=5jbz zwpP|Q=0I9$KXYaoK2R@BE8h`9~!imJBl+;sc=^2@)b8^oL z^UmcLl$QPN;@9OBmnv(--_>5N`~HV(ck1sp+-to5_Xq8=j?OOmqwdE)_dV_Z*MM?x zNHaD*@yq1Yv*#~#v--K$^9!WG2#0``*)|+ddms?H(RYYv%Fq-Da#eB&9CuLxikUJ9 z!rR70l-GZ7veM`||7Tj5ij%Qhd6b`eFy|o3l`+mcc*Df-$XmK_T;n=>RG(Ec-9O9p zPVxt()lK(@4?b|2-l%O_6{0c)Bn$Y|dNnDAK=Za%T^K4N!@mgm+_d7AKCr4aT_I{Y z5X8tf!8yFc~;g4%RBNDwSPpKK6KO|60K=6}&z29`^CDnY%<*OsU3J8+<%7n2H zY7=%2*Ib0)xV<|B?QABW&Vj&bqz-~@=M50($kuct1n<3KFu!$m4>4uJxPn@{45cdR ziePNICtu1ei(X9TysJ`Npevdh$C=aA{pUS@Vw4cvQskqOk0pw<-J*K#UvUkFlppCc z#Xi!G+^#o8r&bHpjgrennHh|G>QwNQfJF<5B#eyO#3y(Ex1=KwBn_i#A?OTAhhSA} zl0o`nfcUp+LBNkn{+1TwhebtdZFA^H5ZIYa0U1+_gLK9V5v4Qlv}|X7H(x}^9~)Xy z77RCi8P|mQZV1GG&?y+lbd1_9XkrG5#t>PFvRWoH=5^pU$){_`g5-*s@S^i&Zn@zH ziOU|R^x=Wk!e&nflbeEx-ZeS}P1Zv&QGjbGqJBTUEE-v-F2tD#@&7C3had6L2N2Y! zi3yI#rJe8Y8y(bDd!_#2`uE)+h**#`CTr|TKW@7upXU^cYbUY1ZLI!N@;l8>dxoB; zMF-{v9sGR5UH61U`ICVuITe&Jvju`3j-4XX^D+eaV#aOb{5KHPSdS^Fr9BXI^dfsN znWBhZmM(#@nuK8N1nT~e={o#bb_Q~Tl|tw?5i&19pJ*;D^iv43w@ArKTvLW8DvYbE z*F(_euBLWls1@!`(GJnh#Aq>}@hTzX6+DX1DV~PD6k}N z#Q1xx@2UA1Sae0JBqP^;(uD}$>d3cQyu~lHR6aF4JGDw0iGJzXI0)wa!XP*gL01X6 zR|3HY6PUrCLRJ3H?-FA*XT*7^#nP56A$}2&1F<|21lmKGBUvsxi;@imRhTnQof5;XB z(aNKU08LA`6Cs;yc0psjRnFK9Kv3!fL0(UWKa+K;gj$aLSrY?+eWjL1kuNdQm&Zh0 zU%{iC@wW1zi!G(f7lz8zu&Tf_w=lhqCthwCN3bRcE+lL6Xd+2%WY-FkdUra->|B0E zhRp^&SHGt18KJLnokW3={%Wd_XNSKu?StUS24DTY0-u@!pX(#82%tO)0?9LCE|Ax| zSCD}O2~hcQlDY&keGqwv5cnrwwjZD9E z&NhlTFg#IZi`aweuw+!(Y#U7fLx4B+ufDfAh%Wxj%SYAuPwv+%e_zy<$>n;kE}FX* xxAy72xSrbSnOxzEkd)%T1bEj9njw&lN#l7&pIgLe*(XSN5|#Bv1Cjv;e+9n><@o>r diff --git a/test_recorded_images/76.jpg b/test_recorded_images/76.jpg deleted file mode 100644 index fc8954d0c67bab0238cdefa13f04176246442b38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1919 zcmcgri&qm@8ox*qo)#43VUcM;kphA|6tUE)Rim}lEX7yltf|lN*e+{9z{h4z0l^?^ zL~6mFBEHSihm+{t~P3mhB(a6k*dVXy@(aa)F0S@KZ|-ic?)C$01#Zq@57^`2umr#kfFW@9Zw1@>#x%tBEnBy7x9@m=XY!uC`}QCB_~6lF$4>}S)6%oDPvzw1ojy}g zc)qCkf~e$5`4?Betf;&usg`|HQ(O1#cQ^0XH$3>E@!>xnwJSS1yHwphPk!qEdElRe znjx)zY<%LENyGCOFHJM%*}3@z(qe^L;B2=I2h<)2iu~#O#B)tz76gSODhRx`Q)|`J zV z+I%2}QLe|0Pg~Y7O1d%%*Z+}7TTKNk?C_adp?U&>A3f?Lr%qoRnHOKL9Sv7Qkddho zjKx!N*acjF6@n8U0T8sa84+Cof%j+~1e-2fATW_FxmF0?{*}QZ!|GZwjbL0&ty+pw zHFV`VY^qnJV3zV0lLZ?_)Ma#KQ{y;uhI;s-_s@(5g74KLRPymOsj){|@ANlZk0Iqp z`fbVG#?gEAHePm>P}eBGUV1u@3CK3AGYDC95s{9OyW=v+UH>iV2n6ZFs9Fd*<8vVh zY)Q8$UJerf8d(r#?#}o-EyE8>OLfM_i621VZnLe;GccZt=@3Me%e>XRg?VSblu$jf zG-oYX?uIjdg83c@WS^MSj8`s3?GiRILqub|Qmm;`Dy_vGxNF9lYO*Awa++Iux!k{y zn?hU-r!kCm#*E9qO(o|0e4Js-|Fr5IwRl$ybo8AYh9~**88vwX8ij)O`L<;mHG=#I@c1v3EJgqD~gf zT#_}P@ufCpv=Qd<+r+awge6E!o*T@Ez@R#STtq@=wqZt#oDG5c(miDKgWr46e8>#~ z>58L>08LAeH=&$-?2E>Dql$4Igy2dj1jW61QOvnhVrm)kXJrxu9ugy;B41%-IG@>Z zYdN3t!P_ddSDUYBURosCo4<}e`#okh@ny>_;|SIUL0N{rm?qM7R(6dry>FX$(za!1 zmDo(o3*8*;!4!pC!{lm=jM7mT`R@2D+dc@Mt_e5qD+#SG3B5JyhX5*eLm+=n%trJ3 z_6qZmAR#LMAbA)9zP6G1JdH1DNV4M|GODQ3N4Yey1%ewTOvx>?ig8JQ@bQbD4@&oIUpN%*ZFEZ(T)6$+zF>ua+6%W?yoWXeB@0yl&mz1ov7 z_3qfiCw2vQMALC%ce1wk_PHd%&Ed|KvG0t05nCPg#{DI6slydFT7#cTXk>nIr?6Ww WoAe1%7g7U3_W)_JOR~EKhyDYL+}#8K diff --git a/test_recorded_images/77.jpg b/test_recorded_images/77.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/78.jpg b/test_recorded_images/78.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/79.jpg b/test_recorded_images/79.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/8.jpg b/test_recorded_images/8.jpg index 2391d8db57cbec18a0a97d7991b48591e2b0a446..0d214ccbf09aceb02b8bbe223477447a6e1914a5 100644 GIT binary patch delta 519 zcmV+i0{H#-4yF&VQ3XoK-|$t>+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$ptij6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;V!u3p;J<(JEqpNl0I%&^{{TR=ugzL0qKYV@uXtnrMqNApzoGvC(8Yg6 zRr%xp00sO10Fi6qhy8zQ-}(imernN06j4PLd&3{{GU?y-{SW?zEBY$0&mZ_N-~5YT z3_t6C`&Rz|&@C(TR*ER1iYTkz82FHk%QAHF{Uac2@hd*NT5}E!e{6P=2ZwujTLILlO^qS*7 zCD{Bbu+`v;;U|c7txCk(19L99r$=of%eefivB==A-KQjjl6a^*6E}kGWV*ibP1d0m z)wqUTBkYl*MAHeAc$+^kUoUwDa(4m74Suu#0K?+HWMBFyuz%o_QvU$tYW#eniYTH6 JiYTIr|Jm0)7nuM6 delta 487 zcmV2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$e-wYi=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnrlc>e&we*XaETKHlA0AJd-{()&v~R~q3YUI{{V&UuV=r4B(lGjS6M6_ zWmhhNP8)ItLKqQ-$iWqvMHEp*Uhv2KjJkLIe?$KOf1!&0imUU-{tNg203z4J5BmPq zzw`@A{MDk0D58og_l7^@Wz)aw`XBuaSM*h1o4Q2G3y+!Yq%gp`Ik!`{gy+>V* z)6%{iqKYV@iYvJIJ8keN+%}={cg4OV(`UE5iR_a_(jvJ>Kyt;)%7u9YpgdRVU;I8R d_C@~yqKgOq2{kYNMz6=pD58oeqKYW5|Jm=j2Lb>9 diff --git a/test_recorded_images/80.jpg b/test_recorded_images/80.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/81.jpg b/test_recorded_images/81.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/82.jpg b/test_recorded_images/82.jpg deleted file mode 100644 index af8c7319faaabc5ccb4022f828bddc53c24056c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1902 zcmcgr3s+ND7CuN4o)#43VUgQ{A_e5-BVto;ts1SZrW9X=HD**4f$1<71bj?x3o#g^ zMx<86mQ+%tt<|VtapVyoNW?Byq{tA$KnPIc1EvY#ag*HK(-YgDFl+W*_pEc*+2{Md z{oTEx1`Y%7ZQOUcz{v>!C-eX~05*boPL6P_^Blo&cC1VW!i05e>@zCprg=1HT+~ zreCWc86Ep|-0<|-bJLW0dS-Txv{<1QxH@dZ0ksnXQK0<}@l?afhCn!|g1~1B6|0^s zgMiyQDy72yi<1@B(Aj_3ML9T`w2n_j>-q~*P_B~p+r%Fr28LcWadCaX)Iswp$wcoI z-94Vwuc&OeH;{7Qe`2MvA(%aAi_H{dQBgWl27&%{qwXw6N^(D8e{5U)n>p_5<~+5u zX>UBOT!R}QH?N?T_VO59{}&>CITfmKz-MU%>M;m@_NtAZIDUC>R&wRqP^21y%q&gX z2%B1kox$}NAvo+61VI~<7TXIU@ExjwVEuUu1SYaM&kDhtztLE9L`@5(NgGvD%NC+k zjlFy|Hqj+k&QZ}oL;Wayg1Yyt>+iG%f?H}al6)v#YV4HOx_pl7F;w}1 z9$V5wRP!`{ZHNc0mK(Pt>!O5>2I2X)S8U-7`;Ak;R$iliZT?Wr0F& z3UMXmn3)?_DQXO*F_mpK(Y@59wv)9Gj1}X0im2UVU&uq&>CWQxR@wh6<@+D;;rkHO z=E?|`)W0n&D3TZ7QGKofIUWVB10T+H|7;Kp&RXg#C%nCedBlP>ME zTwa_oKIP*TbwO$As>gi>6&0U0nE=5ip9fMh^a=!G86CKC_A3ag+(y*Yf-VT!yOF(@ zZ99l=hAEA99fx4#2EJt?PB-&3DKMjD#O5(Ay}~u{nFFP5KKpJfZ#j?9TIYv z9D;YoFpC$3RQ}J;(v$QjWksmPa$k9c_*F{wCGn*Y824d57g$0qkToxUMFx_7LU z$(m01Q|mKZ3G?WW#PAKm5+Wf_^%X#1Q0+x7qC%%OV@8Xd34!|DZDjP_KYG!;&jSMK zl7olw^Zb8_&V<7EzE4<%NAKi5v&b@(oB7koygExnbm@f?#;f5n-`r_ zVpH+YbTf7@S`=xGkgG8=Mn|3Hd*Ux_yCHbIBGSCOIJ~Mj{Q6J;0=TpT0{K&7I*#AH zOOTHW5+M1>`;&5g%z`V?wQ`juaFv(c-oZNID1W<)J419B>6yUTRc9~V!Zif zeH5oxC@`y!{3IzWN#hs-3?qDT1;6FJ`RlYip&-VzraGsmG%vV8ru>^Ycx}YNi=7D* zZ;#x2^s<8FWlwe|cU4bJ3PsP^+2=luU0y9{gg`l>Nab6@ZxO>~AEIh9s8cV6p)0We EcS5GtA^-pY diff --git a/test_recorded_images/9.jpg b/test_recorded_images/9.jpg index 2be5ffec9fbbae543da553e8263d253b6c4d260e..fe40c10fed11ce7b8e10f007f1117e6414635ed4 100644 GIT binary patch delta 399 zcmV;A0dW3_53UceQ3XoK-|$t>+YjQ`?2)5*Cimf78dJWzb$*w>+LqEt0Eu8Lw`7Tr z^^Kh8wRoM6{1$7%{{Ui#`$or9`$v?%f0d<;yYcg5HytyYmy@dnFC}qPf5B$HC4a)) z9z~6x{2@EnJG8g^e%~Nx{$4g`&CmP?-n(Cu$pthW6=O^P0D{N(GW$}uvRfTrGfs#z zrZ08_{(dX;Vv~>tgMWDc0KtC$0OVTuVgCSM+PD6JXD7 zEpJk@Xft&#xu->KB1^dNs~nCB;~bJXu4=Tr8k%$Xw@ezgu@0YVFQPXW*Ad9+0tN)T tENad`9hFJ+75d}<01t}&k$>o-!T$h)O-ug(k*o3YiYTIrD58oh|JmA((gFYg delta 377 zcmV-<0fzpr4~Y-3Q3YD({{Z|Khs6FR@Yjbv8b618Lw%>2uXRx=vb%V<;Vp5Uq-PmD zeQT5O=lm8Y!a7HXtTd~eU18+4vWh7m`!qJ@Q~;d)qn<}vx&HtUn($xz`0F3|D_{Od zqm!EjFOmi$e-wYi=DZjG06sd${tDOs0Fo-km;V3-kML#orEg@mI=*I|5NAwY><9e( zSLnrlc>e&we*XaETKHlA0AJd-{()& Date: Fri, 13 Sep 2019 21:29:37 +0200 Subject: [PATCH 28/34] - change --- stable_baselines/a2c/a2c.py | 8 +++++--- stable_baselines/acer/acer_simple.py | 8 ++++---- stable_baselines/ppo1/pposgd_simple.py | 10 +++++----- stable_baselines/ppo2/ppo2.py | 10 ++++++---- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/stable_baselines/a2c/a2c.py b/stable_baselines/a2c/a2c.py index 30c7f567ff..692b01e049 100644 --- a/stable_baselines/a2c/a2c.py +++ b/stable_baselines/a2c/a2c.py @@ -88,12 +88,14 @@ def __init__(self, policy, env, gamma=0.99, n_steps=5, vf_coef=0.25, ent_coef=0. def _get_pretrain_placeholders(self): policy = self.train_model - if self.initial_state is None: - states_ph, snew_ph, dones_ph = None, None, None - else: + if self.policy.recurrent: states_ph = policy.states_ph snew_ph = policy.snew dones_ph = policy.dones_ph + else: + states_ph = None + snew_ph = None + dones_ph = None if isinstance(self.action_space, gym.spaces.Discrete): return policy.obs_ph, self.actions_ph, states_ph, snew_ph, dones_ph, policy.policy diff --git a/stable_baselines/acer/acer_simple.py b/stable_baselines/acer/acer_simple.py index d0a43bc745..034e1b62cf 100644 --- a/stable_baselines/acer/acer_simple.py +++ b/stable_baselines/acer/acer_simple.py @@ -154,13 +154,13 @@ def _get_pretrain_placeholders(self): action_ph = policy.pdtype.sample_placeholder([None]) if self.policy.recurrent: - states_ph = None - snew_ph = None - dones_ph = None - else: states_ph = policy.states_ph snew_ph = policy.snew dones_ph = policy.dones_ph + else: + states_ph = None + snew_ph = None + dones_ph = None if isinstance(self.action_space, Discrete): return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.policy diff --git a/stable_baselines/ppo1/pposgd_simple.py b/stable_baselines/ppo1/pposgd_simple.py index 8ba6f770ff..3e0421f8a2 100644 --- a/stable_baselines/ppo1/pposgd_simple.py +++ b/stable_baselines/ppo1/pposgd_simple.py @@ -86,14 +86,14 @@ def _get_pretrain_placeholders(self): policy = self.policy_pi action_ph = policy.pdtype.sample_placeholder([None]) - if self.initial_state is None: - states_ph = None - snew_ph = None - dones_ph = None - else: + if self.policy.recurrent: states_ph = policy.states_ph snew_ph = policy.snew dones_ph = policy.dones_ph + else: + states_ph = None + snew_ph = None + dones_ph = None if isinstance(self.action_space, gym.spaces.Discrete): return policy.obs_ph, action_ph, states_ph, snew_ph, dones_ph, policy.policy diff --git a/stable_baselines/ppo2/ppo2.py b/stable_baselines/ppo2/ppo2.py index 4442b53d25..73ebc8e891 100644 --- a/stable_baselines/ppo2/ppo2.py +++ b/stable_baselines/ppo2/ppo2.py @@ -101,14 +101,16 @@ def __init__(self, policy, env, gamma=0.99, n_steps=128, ent_coef=0.01, learning def _get_pretrain_placeholders(self): - if self.initial_state is None: - policy = self.act_model - states_ph, snew_ph, dones_ph = None, None, None - else: + if self.policy.recurrent: policy = self.train_model states_ph = policy.states_ph snew_ph = policy.snew dones_ph = policy.dones_ph + else: + policy = self.act_model + states_ph = None + snew_ph = None + dones_ph = None if isinstance(self.action_space, gym.spaces.Discrete): return policy.obs_ph, self.action_ph, states_ph, snew_ph, dones_ph, policy.policy From f11f732c7609562b2faaa0fbd7b6400f402b165a Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Fri, 13 Sep 2019 21:30:48 +0200 Subject: [PATCH 29/34] - change --- test_recorded_images/0.jpg | Bin 1989 -> 0 bytes test_recorded_images/1.jpg | Bin 1935 -> 0 bytes test_recorded_images/10.jpg | Bin 1952 -> 0 bytes test_recorded_images/11.jpg | Bin 1937 -> 0 bytes test_recorded_images/12.jpg | Bin 1962 -> 0 bytes test_recorded_images/13.jpg | Bin 1948 -> 0 bytes test_recorded_images/14.jpg | Bin 1970 -> 0 bytes test_recorded_images/15.jpg | Bin 1955 -> 0 bytes test_recorded_images/2.jpg | Bin 1939 -> 0 bytes test_recorded_images/3.jpg | Bin 1969 -> 0 bytes test_recorded_images/4.jpg | Bin 1975 -> 0 bytes test_recorded_images/5.jpg | Bin 1968 -> 0 bytes test_recorded_images/6.jpg | Bin 1951 -> 0 bytes test_recorded_images/7.jpg | Bin 1970 -> 0 bytes test_recorded_images/8.jpg | Bin 1958 -> 0 bytes test_recorded_images/9.jpg | Bin 1966 -> 0 bytes 16 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test_recorded_images/0.jpg delete mode 100644 test_recorded_images/1.jpg delete mode 100644 test_recorded_images/10.jpg delete mode 100644 test_recorded_images/11.jpg delete mode 100644 test_recorded_images/12.jpg delete mode 100644 test_recorded_images/13.jpg delete mode 100644 test_recorded_images/14.jpg delete mode 100644 test_recorded_images/15.jpg delete mode 100644 test_recorded_images/2.jpg delete mode 100644 test_recorded_images/3.jpg delete mode 100644 test_recorded_images/4.jpg delete mode 100644 test_recorded_images/5.jpg delete mode 100644 test_recorded_images/6.jpg delete mode 100644 test_recorded_images/7.jpg delete mode 100644 test_recorded_images/8.jpg delete mode 100644 test_recorded_images/9.jpg diff --git a/test_recorded_images/0.jpg b/test_recorded_images/0.jpg deleted file mode 100644 index ae56eca0ca5c77e8567565cea86431f2f0e5e40e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1989 zcmcgsYgki98XhDUAasEu6i|qwA}dvph*>W6w1q$s#VUv(NK{yYq&17QiY?|WqM)#v z(kRwgh>D7J=|+%?N|$W77;L2xP=T-*l2AYmHQ{<7hci8KfA0R+AN%Y#XXcsneBbwe zGw(Yyun!Ia$IX$^k-*9d04uTqH~_-IA}fno#zhvRSX)LagiN&IRV%Pm?Sv$4JKLPUuLz)nnI<~$y^2*Q13|A zw6-QIQOPo7^fA&8C{EP3m#_bT=Dd9$-8*}6V1DTpn-w3{C|q`Q8CSCQA3APp=lYJD zyT>Y@)xN)9vmt0B`wzh(;Srq3sE?vI$HnhV*p-;HJ1zZ>8NAE`SvjA5e)vf4(Ju;4 zoGdIlb-MU#@wxM57rwbDxmtPc`i-ia-`%RcQ&->6c=z7@me#iR2g;6zKX&&#dHSrk zuV1az>4$$A86A7^(ljwSH9a$n&CNqKu(8mF06ZRoLidGQbgVBd2Z9rWN(h{z@Br1g z7=lQJUW)ttieQrY6*GTYDEth;;zGFiI!%8;G8x-SxJGaX(1GVmOp%DzZ6a+lPh@yH zL3E7>`sEc(cL$R1zhht-o4nYA<^aA>fWNE3Dk0D=H)=}4q*&x3_NQi#*OTkZn~$iZ ze~+#r6dJp0n8@Thjq+qpoXebQwFo3;J%7s-x3>MFXtpipU_`05X-jpR-pxfPt-D}| zHkCo3kF7sqMu?8)z@8txA;=&e-f8F#3Oy%s?Xt~YH5?t9!41G)2E@|h7jcdB8Fy?F z0^10=u>r|=E6U8;FCe!fZWS*3nVmC?W~>{>AgGY93&}~AHy{R<4#kpo^YB2PL80G< zMUl&Qt0SIFgt4nXA$kT^OB=^ujp)5nks{CF&ZC-qWS>-BL^z*WLO7%S1xln(u5N%p z4S{LvAOuR8q**XuubE{Z(_HG2j3Jq-KAxV9`#Zc1LF*>skykLe7=LrLTFv`C)cZ1$Fngl?}~x$?n2r!vh* zM|ob?UwBt!HV_nLcut zPJIxT1i|rOIVM50V&s5oepv;{iDIb+-^w&Tl-7+dIBs)Aht3KJ9}$+WQs)q-R+k{g zDE6C66381T<%)1_mtrd}L2$Z~aA(bY3&B-eoeFpAgrM!I>UYGCNL|~eWw#~VKNEiO zF&!nWOfdl2;#vOety+Amw$SALVL@z+Xl2dZ41P~3>#jw$3GxNTSLiTesw7l}*cr0~HOP*!Vf&%Frj|h6w+o3V;R1G-jdJUzOxjwVn6py&(rq6{JKO#lFyl* zA;ttbUK)jO;w#WeeKk7tJ!&~^dA-LW7*!^cJnx2Jf|DJGDl(c^p)LRP;+&D<%R_rZ z>l)2M%`zU5x{=qZ!s*YOxc`>LG|tJW5U9@9kOJ02FkFmiCsP>^NIlaappvXTbV-XL zeM&6QyrZ!;*^|qPJ;l1=f7qH3`c3VZhoM7qbYg8@00gpe@-=(EPS&~G_iC~4RatHt z5xFOnkY6FGZ$~*h=kz3^8G=&2wrBy((#%t@3$wa7i??%JzHDVq1isKrFE|i|e)DT& zDkkQy!ArRI$SZRKnZDL^R+$N@lzGrJB7@<$;NKU*T{!% zqxFbFpbiZ;y2x4tUWt7FYlAQS^BPilzn&;L=ve+T#Bi|Uyzv)uCyRGo&UNN2eDgYN zy&&7fR8|DkJadzPHgK@eWd^EIiM`vE_sPzX5@U B`-K1i diff --git a/test_recorded_images/1.jpg b/test_recorded_images/1.jpg deleted file mode 100644 index f51346e066a2f5a573149f6f25a9e778a215d912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1935 zcmcgse_T`L8h`n*jRA#(5Lk$!B1sA|aUtZn1{*FCuQE_kS%@-Z77?jbxN`wx0+$w{ zkTcy?GOVmA4oI=B2{bfu@k4J^)mgVCZ(LUSZtXHJW$bysnC|ZPqJO}G zWg*K$UsN8?MM3o0@;TdhJGQTl+8Sj+?i-dwTEQ>+2uT z>J7%x-^U(|KYV1dPEI|Up22LhPz&4~vLOKHLQono*MN@q$L2$DbVv<>PXZpHnW%<< ztujjSkUtPiGP`8@y}8m45G;8e4_~DlDA`HIwi15vyg_tu_$3P)(feC7Ckw@EaK*srtYYi<6^%qdfu{8PD~ar0)G^dMCCg3%(UqMY!U)` zywco+WIdN)XY9!(uTtGATy%$-KZ<6pn!q49qg=Hvf2XnuF)<7%wj+&?NAgW7<7O;@ zEZ<*F^jc$?7Y`6UL(8Sj6OYG?3)2x%V07n)x*{Y)sudAFl`j!K=s<}Y=~rr-Akac! z*)#-!S|(BC&Nk|1m`8M{dL-jWwx*wNWa8moFF??`p18d*nk**V&QaXt73CBwT$H`Z~w zu8ixH^p%@TlgvjwqP-a2AS?c5MQlEW(*n#J`erBN39TeVXKs;p$j@y zeY^RT+P&xY^c30od z@T?h3e1{gG&6|p{Ss?H{X-`7CTrGUUZ43fKHYwX%bM?r0alsV`T=P-O8niV;*dv|V z5W53{;%Fr%LG;zge$DKnGo&V}mv#82AoESB{K4G3&3@>}r@2Ik7~8AS<`c)3S0LsD z=F^WPl0QMVE8eGFiY++>L0KIUz?l9Lf^&3(2KVlSpzW^adEyo#Z(G0Ul7#m!B8;2Z zQNhTr1|Y9`Mlkbj1HMULY6*U$Bq>q6^s;Rlzp9pXH=z1d<($W7=qO^TBYXuA{C1T_ z#6hqC`QJIXSo*l0oaMlh5~+<(MD_M{=*%gaK`%p}sj99ZWJbShL9(Ldps-e{t?Awf z%H9rZ-diSqQu*bB#)8vg+)r==f;}QTTg|m699N(x&R4crCNr6V3`s2!6g8r>S?(d` zR3%=OfUg&*&`IM(bmV)~F>Qr?#SlDDZzpw5gTTtlOGZ^$ie>1H`wLl>QhaetUyQuj zF4QgJ6X|RDof@1r+`{{>tRS;ZMu9-{>1DEkjS!5MBl^j74+x}znGjG&)o%J`CXzli z7HQww+^{o{$4ENH_&WTM3n2`f+M|p`N0g{_WnlyavI+8U_7AzNGcEL7dFVM=K_Y%lG5fAZz49-IF;lqBLxFg-jEK zh3oJNo+t9yo=T>#44X_PA>qkPOn>X?U4KIK#3}nLaT(_y zDb`>jW8&`AwVd$pO@%SJE3dtFK)>rwKyA^T`}S=Q>+$tr(=2khD`*5gDx6@;)XyNw ILuGK_FKw&eQ2+n{ diff --git a/test_recorded_images/10.jpg b/test_recorded_images/10.jpg deleted file mode 100644 index 0e63b7847660bb91171f3ee011eaede32b42ee14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1952 zcmcgse^e7!7JmFl0)&c`LID?1RA8kFlF}4mnXQr_qPP}B1tkk8L1{}VR;blXkuGQ` z&0;L9p_)Q!wUsp$1E_S9MZlmdW&tS>7D5t=QNnH#kPKupuM_vr-9LMJ-TwPsUsT3;p#Y1yn8{O7yxzXwScE4#YBlm;T?jC-x z`UeEA3k?hZ?fTba-eA5NyLoFOi=DJBd3##=o{YWw_GjiDI-JifIC8Y)*oVhU%RV|$ z@#&u`tInL|pA(+{qOSfg7eq~xuP=Xd=)Vz6w6td7eS76G1WVh@!8d9~E3(MgF2XO7Glq^$tT3|?t-mF2?xest zWFh*ei$)cfI&O_+-Fel>FmMFvgW(DDcj#em<5rw)9 z0yPBYo#PNFr6PIJQme+wJf&$E6d8~L)d*M5#3Q|4hM+5fc(^i_Y$no{tk4EQz%Tj( z1cFnNV6#PDbihs&^8b%koa+#@ac28W`h~FXO+=&F>#k_xsyswA9k*MucI~|!?>fzN z@5Ph-pK%+dZV*(Ni9XJJvO{d%YY;4k2rx9*I0QkWP>EP|DhSSn|LRfe3%#(73gh@y zP3M&!Q-jiD@ZpVb3*Ir&ms8P!-_6Xbv8@EX+;mO1x5vv1kFCKOf<97}U zALe-0jitOx3s4u&$1Iv5@VsD4Mf+XNT*7S{0$l+~+Yb8`#BjRoCIqe}sQGoYE0i}V zo_{NTKLn>^6_^Oo3XvnKrB##G(d1xLIf}tzJ#F3U8lmm`yl8ZQY|AMAhPa+Ro{y^pAZr0 zDZSN<0wDm!LTjP*yB2(>w$dE3r6M&&u=d8{0)AU59cV$d845f7&*&6lmJq&$5d8Bt zjo1o7Ao9yO(y?rVmYn6FiVE=}mxy^h+^aF|QH^=&hK;q7vQVq`Kwz4@<3nD(LR~ko z4V?XBMEjw$g6B0~K4~qxD8T&+??RAUWn(MTZAs_l=ogo3I?Qu<%piuSo(PVaR4kf* zL`)e9yfz6>DC|V%^v&qxUs1=jog6+5!4u^^lIKhaEUe-*v@>764!!%Ym8=>uzB+C= zPS$SYX;yKG>^Hc5Dx5aa!TF!8VAGE1(5KQqA?OZk;0&!3t1Qe3B`@VT8 zq)&-O+um+($qM2yQqM5Hi9GH?@FM1O74hh#0<~;783loKmi(LjUMB6!3~%CxH%ZI# z2=>7^LeWT4--ELDEb2)_8w9n5+A2GGRI^06%sbl8dSy4u_v5Z$OY~FCbGsK&8L_lp zstU#;HF!106PdAPkm(yD<}ye~e)zQse-fZRm8@n!=QnZs_wdR{26$xWnOF`49CbTU zeuN{E?RMa1o0RxxcS`LjDSIQI;9s*`Bj_|+8t!M8$PlMYJkHqXy;lXI>`~qRJ%Qfw^A^Z1IN82lj?;DJ{}WZ*M5JDB>bL*^ diff --git a/test_recorded_images/11.jpg b/test_recorded_images/11.jpg deleted file mode 100644 index c565af030a6d2572452e004a6ec7e26c92e989bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1937 zcmcgsZCDdm7QT^u5-K1QP@W&te_7D5OjXxPmJ2m_hS-HH2i_vb!)=9&A0YIZJ0LMTKSVMD!V_oA2x|3sN(CJQeCWFa*db2oeCX2&j zGTB@<$Jr6olMC0`#qk3F47hBN3Q}n_cK~~UKLyTsib*m2J7{a1=nN){>g7@e&2AK@ zlM}_nplGP-lT;qi-5KjP?|zx-k(|Q{C|Vy@R$a&5^2*Il&o>9mTX_dRIK^@Hde+-# z!?wWfLBHDZLimgPUq|eTi50}f?@f3$B{ePmt&IJdxrg4#6XhR1QvBi3W5-KQ{J#9- zPbw-;pQ-vndj89r+CN^9)hn)C{kq}W^>3PPshV3_f4JS&)!oy3N7Hxr=fR=-4}KXQ z8Pyr4jMEQi9?i}@#w-hqOV(w4WfkfG+aVhQh*StFeC$o=>_}8G1RsxUAn=GMLbdZ! z2;w@8aw6~_2rgUQVtwCU@gahz>=6>X^rPijRBbou6)PM=$0jynafrd&lDkkUF+H%5 z12cuA>dWmvjAgYwYvP&P{rKay&;oHG@w^^aKw#Kx)}M`%<8dGG-?MG_=fdtw9mlou zpAs6#PQCLLT!MKmp(3Tb;7@`^odjeYnRo_E+1YzRvfPvSyVz<&`)iFoMsLq4xvJKb zfYm@?Olm%EL&(04u%RCVAjl){-f9^Pk328&8sHRdn@)(#6NVCxLz9@PYlLQ&)dydI zfD@}Ww;*}X#M^iW3#m_$c8fRtm0vuK=IxrtA-JsGwWl~s-GZ2SQz*VaQ$&P`Or6Hp z@px){Zxwmp62)(PmmC`3E^nQGGGp}1Mk;+H`cLS~kQ}+LlJq#Yk@P@E%QeV|TGs-B z4gzf7I0PD{tfO$XS-;FbslPZRn?>@qBO)W82ytBpL3cEH&o6=+Cd8JYHuyqNRrm%3 zl9LL5%+gW#ww)}f`Y&Dyzk{GfINxtJTDO01ChIWQF4@GjjsV$AWU^xG);l@wHTs#p zOQi#!it3bX2r4nMU$~gyFkAdQ1S15_4$v_X$)15=DxZ?=HG2axd#dCX1oUDQdjahZ6c5Q4 zUyj-j!Knx}E<+4bWazJ+s`8A zc>dEv5+<6b?27g1mE&73LU2Yw`tYn@K~T?`(h~0d5cE9It|fm)R6Ws~zLyCpg` zRJGc~`b{D-`$bW|mS9b^3;(0b-@Kw^K%o8XCS_nV1k+WBVIi9ff!sG20tThpUC-P^ zDyPB2Y;U$UW%&wuNvC;Vha7Vv#ledQ)lulA8nx^!4TV5CPyNkaQYrg0gX*h->XjwA zWZZ#BQe8($--`;;R*V#)4T9(wCD(J?9Hw93eM6u1Hi@SvbY2p$}0WmdsCY}R#t8Q3skX)86h48W~R0u7T2*e&%G_CHNs9*leJ2T?h zy)6dLgyOq9b92JA$$|rBQzm`Yem;7~k8Q0(eh(Rh^^Hbp{940L)fpe%W4_M;mzU-| z@M3GITSO~fhtaOEOPf({Cdhj3kiFsRiL~`;->!QcyfbgmdaNtv=*HWcm%Kd&)!C>4 a6E=m|*JmK+gzKm!Tpay$SZZDrj{XakSK)F1 diff --git a/test_recorded_images/12.jpg b/test_recorded_images/12.jpg deleted file mode 100644 index 1556cd623d9ed410830eaf28a91255d98343b161..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1962 zcmcgse^gUP79NBoK(L4u3M!(gK&2{@#w^16+R6_pg)RlDVkJeCL{m#C73nVKEz*KU zZI+_2#!42b)fQ|j2B^}KB4E&pDWC;HA%swfHSFdEBoFfPW+(2SyMONKeP`ypIrrZ0 z-ub?nfrD@iEO|99Ar3e>0pNr_0EfYLu*k__j(L&8T$~*zpTh~n}Z*EO$PYxjAh*Swaq@BQO$?!M3Y z`7c`+91{Bc`WLxdcz=l8x;-W~E`CSCtEp)_)8E{+J0pAlfgFMG;Gz5vjuad%{P52u zAAMX}cH*Su(~7g_Dy#l}URGQ8`K2!|U-|N@#_P(a=9X`7+`QG%*>zjpedlgp|AU7= z4-5`z_2Y(#Uni%GkA5R8GqX?TtmOOx)B;xrZ5W`^ASm^>H{!;@=zIu18c{>w9Z!X8 zrYj(bYd6TL;D2JIY+=pZd-l=~Ffw&3pW3J!D%pc#J80h+{xCi~x}1o^^nRA?nIfs_ zp@r_9%pFoyw|+ak=jL-Jj=6OuZ^RZZ66aDc=*T(<^sCLfQ_*rV?tR{2+p>SnY`)lb zR3raB;WFK>bN`%_624Dxfx;{HAF&NuDcE&rbTN^-q3gWV+L`!nOu4@GwT4cEpU=2l zS!GHfDj_f=HyyQMbaz`s|93$UQlGlbLCY_-59e zKRE+|Ta3!wjO8qjw{iC6qODYPh*#a`dMKs#P1e=I>E8V*9<}eMq#szKc@6K-{Uagrmg&cnhLxFESwLjZhq_`cORg=Wz0WMCz44(EH8!Zy zHbbC=fJhpFK&_Cqj6_vV=tTu#Bw zy%qPeJSvA153~HWd9&Pk0s@cowq(55g%HrLlMsvx5pA#8FJs2zh1Vf)$;XKo@s40| zzkK%P=-m(;k5rK|OkaT=)GVy3Mx3;-&{0W&<~wrblzqwTzWCTDxpc6U+^^B*((@jQ>|U zEG@D76h~MAKwgDaWc{jF2Ls(Y^G?mM=lFoBysj|Vs()))YFq0Oag|D2 z*|!6nd^@aV|4HeSGoMX06<(B5zM@+Y>?^aysncxnXWQ^|m(H{jGugZVj;x9f5ZR_w`zpRWsBd1nJ z4MZthY+~Ii0iC%;(4(PPqpke^$_g~kD;N-HKDmYjY=U4yg6U^6*$~JBvLRp~*6#RZ zCnBGkjIh1Y(zqvp&q+SP`C?OnGc69A-KUDi$5gmwLs2*cifQzky`)t1WQ5jALTeR; z*>v3AC|Xs6sPDpKcg`CSq78y_k-p51AJQ!_E{PBI#y*=8>+_e6Kug3U-4nYfT^hEq zUZDvjH|eNTd=KogEghwA2%AYqkdn~)Q9lGwm5izx@!8G%-kst?#DExeo$t zWPNzT3IjKFJh{RaJt#~`GGDk|{rrO?YYJ+G+#X-HurlCk<>D3h6W<-&eERL`!l@Ir zSA|t6yG2{7t~W1Ter4qTR`5ghxdrr^dP?l&xUse!(Vc`iFRv#oPd8mF34=rb25%bi Ae*gdg diff --git a/test_recorded_images/13.jpg b/test_recorded_images/13.jpg deleted file mode 100644 index c973f2aa2ea353c5d22c0b700d514a059653ba9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1948 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 Fe*=6D^UMGM diff --git a/test_recorded_images/15.jpg b/test_recorded_images/15.jpg deleted file mode 100644 index 77bf16704d7a96c00cc63fd3e4d9133df0de9b76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1955 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 diff --git a/test_recorded_images/2.jpg b/test_recorded_images/2.jpg deleted file mode 100644 index bbd96f15efd51121aa24fd422c495889886fcc10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1939 zcmcgsZCDdm7QRS6fY3!sprOHk?};s@Pgricp~ zYqJy!HC9uhRxR38e}uLLr1u#2RWQi7=4K+`VCcc7N`(=RR|vJI^`i zeb0H%oq>aJ3@m;tAt?bkIRW5=7J$QGBUt3*Fvq^gVGL)-&SWs087wA?weYZAU07^a zHjCxLadCBX7&^Ig+}s^6@LRxf0qG#!$;lJIPQXRr%mqxu@E>zp+F zEm;w~GUT_bUW6(RxC`^aq?U#)_Q~Of>h%KT}R79=Tkqr>&mzi{@Vr68)0scPQl4q8+=M_gZ zvVSIBrd2w(&q)d4^Bfn-J>x%%zowOdZF@&wAkx-!ot4aXCjTX_THpTmwN8Vt_qeRN z&X`2hLSRT~Iby@;ZbfAOKLR1hr|;ct?Td;zBk}2VEnYE^6q7HApni@>VWlq;nAkIZ zqy+-kIHjo-%YPx!#@khdTB+#}1$@shnZWbIrb!4cD8ts3WGh=SBX1lhw`U2dNTE?> z*i0s(@_n1>2j*D*wRh8F#1r8!uYe{|2gx^gU6rmdpAPQOBX;X@T_Y*49f zg+L1dv1tSXwOpzwns3p~@{j7y^-HI)0?nY%z^B4JUWA}yJ$-*^G%610f5Lr~D&T+dqF zWcT^9-VcNq>WxAKOn`Y>k>DAaFlxOTl{?gphWbgkZb?$@aGWGB$Or^dw?l9&T1iSVeGRrpGaqmPX`*^nM{VMo?#Y@T+ZS*4!N)!34yN+up&mIUmA8LL>e}^@9t`GQHDtMm` zO;7GV#Ve=*ptxqXaQ4e4YLmW_2z;X=C0P=5V{V4JrIzT|pC_%Oxlv=v zIpPs!%2ZO-iPZW+6>c$H!^f`Uj@wo?a14US>TO8pEC|f;#c8-IU$Fwe^W)O^(=uvV z%s@+5N!}t7wW6*_+H&S^O9(9Z~RNC@!s!saLtiVbkFS`bYL~9>eWuBzevf~FTd|$ox$A2l-gnhrY^g8M1wxjm$f&H8P)EiQNRc8jO zv%-Fr=7@T=-1o1Gyh_a-+m8l6OMUOBCJS~jD0~0$XQ=~u2d(m|g-*p*S>-z1_^mYa zTw_@r@$7@uEuZ|tAJIOMGQ5U^hf;dJ>Ti7Yvn`?=*8rjS{2>TD#P(`@s$PY3-Gs!g PZY0bL-PMaj;n2SU+P372 diff --git a/test_recorded_images/3.jpg b/test_recorded_images/3.jpg deleted file mode 100644 index b86fd24061e099266205e345492dc664f2f29efa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1969 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 z 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 diff --git a/test_recorded_images/8.jpg b/test_recorded_images/8.jpg deleted file mode 100644 index 0d214ccbf09aceb02b8bbe223477447a6e1914a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1958 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 B@jn0n From d8685e45f8eb41adf9fa2ad80025cda5ea498d38 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 14 Sep 2019 11:01:32 +0200 Subject: [PATCH 30/34] - fix model save --- stable_baselines/gail/dataset/dataset.py | 57 +++++++++++++----------- tests/test_gail.py | 8 ++-- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 53bc478f4d..57494c667f 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -12,14 +12,6 @@ class Dataset(object): - def __init__(self, expert_path=None, traj_data=None): - - if traj_data is not None and expert_path is not None: - raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") - if traj_data is None and expert_path is None: - raise ValueError("Must specify one of 'traj_data' or 'expert_path'") - if traj_data is None: - self.traj_data = np.load(expert_path) def __del__(self): del self.dataloader, self.train_loader, self.val_loader @@ -39,6 +31,23 @@ def log_info(self): logger.log("Average returns: {}".format(self.avg_ret)) logger.log("Std for returns: {}".format(self.std_ret)) + def check_traj_data(self, expert_path=None, traj_data=None): + """ + Sanity check expert_path and load traj_data. + :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. + :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. + :return: traj_data + """ + + if traj_data is not None and expert_path is not None: + raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") + if traj_data is None and expert_path is None: + raise ValueError("Must specify one of 'traj_data' or 'expert_path'") + if traj_data is None: + traj_data = np.load(expert_path) + + return traj_data + def get_next_batch(self, split=None): """ Get the batch from the dataset. @@ -96,18 +105,16 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, randomize=True, verbose=1, sequential_preprocessing=False): - self.traj_data = traj_data - - super(ExpertDataset, self).__init__(expert_path=expert_path, traj_data=traj_data) + traj_data = self.check_traj_data(expert_path=expert_path, traj_data=traj_data) if verbose > 0: - for key, val in self.traj_data.items(): + for key, val in traj_data.items(): print(key, val.shape) # Array of bool where episode_starts[i] = True for each new episode - episode_starts = self.traj_data['episode_starts'] + episode_starts = traj_data['episode_starts'] - traj_limit_idx = len(self.traj_data['obs']) + traj_limit_idx = len(traj_data['obs']) if traj_limitation > 0: n_episodes = 0 @@ -118,8 +125,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if n_episodes == (traj_limitation + 1): traj_limit_idx = idx - 1 - observations = self.traj_data['obs'][:traj_limit_idx] - actions = self.traj_data['actions'][:traj_limit_idx] + observations = traj_data['obs'][:traj_limit_idx] + actions = traj_data['actions'][:traj_limit_idx] mask = episode_starts[:traj_limit_idx] # obs, actions: shape (N * L, ) + S @@ -150,7 +157,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.actions = actions self.mask = mask - self.returns = self.traj_data['episode_returns'][:traj_limit_idx] + self.returns = traj_data['episode_returns'][:traj_limit_idx] self.avg_ret = sum(self.returns) / len(self.returns) self.std_ret = np.std(np.array(self.returns)) self.verbose = verbose @@ -230,21 +237,19 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, verbose=1, envs_per_batch=1, sequential_preprocessing=False): - self.traj_data = traj_data - - super(ExpertDatasetLSTM, self).__init__(expert_path=expert_path, traj_data=traj_data) + traj_data = self.check_traj_data(expert_path=expert_path, traj_data=traj_data) if verbose > 0: - for key, val in self.traj_data.items(): + for key, val in traj_data.items(): print(key, val.shape) envs_per_batch = int(envs_per_batch) use_batch_size = batch_size * envs_per_batch # Array of bool where episode_starts[i] = True for each new episode - episode_starts = self.traj_data['episode_starts'] + episode_starts = traj_data['episode_starts'] - traj_limit_idx = len(self.traj_data['obs']) + traj_limit_idx = len(traj_data['obs']) if traj_limitation > 0: n_episodes = 0 @@ -255,8 +260,8 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, if n_episodes == (traj_limitation + 1): traj_limit_idx = idx - 1 - observations = self.traj_data['obs'][:traj_limit_idx] - actions = self.traj_data['actions'][:traj_limit_idx] + observations = traj_data['obs'][:traj_limit_idx] + actions = traj_data['actions'][:traj_limit_idx] mask = episode_starts[:traj_limit_idx] start_index_list = [] @@ -349,7 +354,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, self.actions = actions self.mask = mask - self.returns = self.traj_data['episode_returns'][:traj_limit_idx] + self.returns = traj_data['episode_returns'][:traj_limit_idx] self.avg_ret = sum(self.returns) / len(self.returns) self.std_ret = np.std(np.array(self.returns)) self.verbose = verbose diff --git a/tests/test_gail.py b/tests/test_gail.py index e01fd75d16..1a5073c72e 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -11,8 +11,10 @@ from stable_baselines.common.vec_env import VecFrameStack, DummyVecEnv from stable_baselines.gail import ExpertDataset, ExpertDatasetLSTM, generate_expert_traj -EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" -EXPERT_PATH_DISCRETE = "stable_baselines/gail/dataset/expert_cartpole.npz" +#EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" +#EXPERT_PATH_DISCRETE = "stable_baselines/gail/dataset/expert_cartpole.npz" +EXPERT_PATH_PENDULUM = "expert_pendulum.npz" +EXPERT_PATH_DISCRETE = "expert_cartpole.npz" @pytest.mark.parametrize("expert_env", [('Pendulum-v0', EXPERT_PATH_PENDULUM, True), @@ -117,7 +119,7 @@ def test_pretrain_images(): [DQN, 1, False, "CartPole-v1", 32, 1], [GAIL, 1, False, "CartPole-v1", 32, 1], [PPO1, 1, False, "CartPole-v1", 32, 1], - [PPO2, 1, False, "CartPole-v1", 32, 1], + [PPO2, 1, False, "CartPole-v1", 32, 1], [TRPO, 1, False, "CartPole-v1", 32, 1], [A2C, 4, True, "Pendulum-v0", 32, 4], [PPO2, 8, True, "Pendulum-v0", 16, 2], From e03be1df28824d232887e162864611cb96c2ca74 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 14 Sep 2019 11:07:27 +0200 Subject: [PATCH 31/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 2 +- tests/test_gail.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 57494c667f..c0d6bd2717 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -31,7 +31,7 @@ def log_info(self): logger.log("Average returns: {}".format(self.avg_ret)) logger.log("Std for returns: {}".format(self.std_ret)) - def check_traj_data(self, expert_path=None, traj_data=None): + def check_data(self, expert_path=None, traj_data=None): """ Sanity check expert_path and load traj_data. :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. diff --git a/tests/test_gail.py b/tests/test_gail.py index 1a5073c72e..b5fbce4316 100644 --- a/tests/test_gail.py +++ b/tests/test_gail.py @@ -11,10 +11,8 @@ from stable_baselines.common.vec_env import VecFrameStack, DummyVecEnv from stable_baselines.gail import ExpertDataset, ExpertDatasetLSTM, generate_expert_traj -#EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" -#EXPERT_PATH_DISCRETE = "stable_baselines/gail/dataset/expert_cartpole.npz" -EXPERT_PATH_PENDULUM = "expert_pendulum.npz" -EXPERT_PATH_DISCRETE = "expert_cartpole.npz" +EXPERT_PATH_PENDULUM = "stable_baselines/gail/dataset/expert_pendulum.npz" +EXPERT_PATH_DISCRETE = "stable_baselines/gail/dataset/expert_cartpole.npz" @pytest.mark.parametrize("expert_env", [('Pendulum-v0', EXPERT_PATH_PENDULUM, True), From 2f6da05e2d89daab188b68b45183ef6d700b3547 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 14 Sep 2019 11:17:27 +0200 Subject: [PATCH 32/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index c0d6bd2717..6530755540 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -31,23 +31,6 @@ def log_info(self): logger.log("Average returns: {}".format(self.avg_ret)) logger.log("Std for returns: {}".format(self.std_ret)) - def check_data(self, expert_path=None, traj_data=None): - """ - Sanity check expert_path and load traj_data. - :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. - :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. - :return: traj_data - """ - - if traj_data is not None and expert_path is not None: - raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") - if traj_data is None and expert_path is None: - raise ValueError("Must specify one of 'traj_data' or 'expert_path'") - if traj_data is None: - traj_data = np.load(expert_path) - - return traj_data - def get_next_batch(self, split=None): """ Get the batch from the dataset. @@ -78,6 +61,23 @@ def plot(self): plt.hist(self.returns) plt.show() +def check_traj_data(expert_path=None, traj_data=None): + """ + Sanity check expert_path and load traj_data. + :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. + :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. + :return: traj_data + """ + + if traj_data is not None and expert_path is not None: + raise ValueError("Cannot specify both 'traj_data' and 'expert_path'") + if traj_data is None and expert_path is None: + raise ValueError("Must specify one of 'traj_data' or 'expert_path'") + if traj_data is None: + traj_data = np.load(expert_path) + + return traj_data + class ExpertDataset(Dataset): """ @@ -105,7 +105,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, randomize=True, verbose=1, sequential_preprocessing=False): - traj_data = self.check_traj_data(expert_path=expert_path, traj_data=traj_data) + traj_data = check_traj_data(expert_path=expert_path, traj_data=traj_data) if verbose > 0: for key, val in traj_data.items(): @@ -237,7 +237,7 @@ def __init__(self, expert_path=None, traj_data=None, train_fraction=0.7, batch_size=64, traj_limitation=-1, verbose=1, envs_per_batch=1, sequential_preprocessing=False): - traj_data = self.check_traj_data(expert_path=expert_path, traj_data=traj_data) + traj_data = check_traj_data(expert_path=expert_path, traj_data=traj_data) if verbose > 0: for key, val in traj_data.items(): From 570b8d91ec5e111ae54833ec058e49ef493aab01 Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 14 Sep 2019 11:20:05 +0200 Subject: [PATCH 33/34] -fix syntax --- stable_baselines/gail/dataset/dataset.py | 1 + 1 file changed, 1 insertion(+) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 6530755540..0ef748237a 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -64,6 +64,7 @@ def plot(self): def check_traj_data(expert_path=None, traj_data=None): """ Sanity check expert_path and load traj_data. + :param expert_path: (str) The path to trajectory data (.npz file). Mutually exclusive with traj_data. :param traj_data: (dict) Trajectory data, in format described above. Mutually exclusive with expert_path. :return: traj_data From e0bb12036da6e07bcbb0f54336903c2dc6eb41eb Mon Sep 17 00:00:00 2001 From: XMaster96 Date: Sat, 14 Sep 2019 13:45:24 +0200 Subject: [PATCH 34/34] -fix pickle load --- stable_baselines/gail/dataset/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stable_baselines/gail/dataset/dataset.py b/stable_baselines/gail/dataset/dataset.py index 0ef748237a..260151c64b 100644 --- a/stable_baselines/gail/dataset/dataset.py +++ b/stable_baselines/gail/dataset/dataset.py @@ -75,7 +75,7 @@ def check_traj_data(expert_path=None, traj_data=None): if traj_data is None and expert_path is None: raise ValueError("Must specify one of 'traj_data' or 'expert_path'") if traj_data is None: - traj_data = np.load(expert_path) + traj_data = np.load(expert_path, allow_pickle=True) return traj_data