From 786bfae90bf709f9d70a86c3200fac289f1e9f34 Mon Sep 17 00:00:00 2001 From: sp Date: Mon, 18 Sep 2023 09:29:15 +0200 Subject: [PATCH] checkpoint commit --- all_positions_v2.pickle | Bin 0 -> 296036 bytes evaluate.py | 118 ++++++++++++++++++ init.png | Bin 0 -> 1065 bytes install.sh | 9 ++ query_sample_factory_checkpoint.py | 69 +++++++++++ rom_evaluate.py | 189 +++++++++++++++++++++++++++++ 6 files changed, 385 insertions(+) create mode 100644 all_positions_v2.pickle create mode 100644 evaluate.py create mode 100644 init.png create mode 100755 install.sh create mode 100644 query_sample_factory_checkpoint.py create mode 100644 rom_evaluate.py diff --git a/all_positions_v2.pickle b/all_positions_v2.pickle new file mode 100644 index 0000000000000000000000000000000000000000..79d3f0c130e99be4e4bbb844e3fe72babc3dbcf6 GIT binary patch literal 296036 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 5: + if standstillcounter >= 8: + print("!!!!!!!!!! no more x updates!!!!!!!!!!!") + y_update = 0 + elif ski_position in [1, 14]: + y_update = 4 + + if ski_position in [1, 14]: + standstillcounter += 1 + return y_update + +def update_ski_position(ski_position, action): + if action == 0: + return ski_position + elif action == 1: + return min(ski_position+1, 14) + elif action == 2: + return max(ski_position-1, 1) + +approx_x_coordinate = 80 +ski_position = 8 + +#scheduler = parse_scheduler(scheduler_file) +j = 0 +for _ in range(1000000): + j += 1 + #action = env.action_space.sample() # agent policy that uses the observation and info + #action = int(repr(readchar.readchar())[1]) + #action = string_to_action(scheduler.get(State(approx_x_coordinate, y, ski_position), "noop")) + action = 0 + #ski_position = update_ski_position(ski_position, action) + #y_update = update_y(y, ski_position) + #y += y_update if y_update else 0 + + #old_x = deepcopy(approx_x_coordinate) + #approx_x_coordinate = int(np.mean(np.where(observation[:,:,1] == 92)[1])) + #print(f"Action: {action},\tski position: {ski_position},\ty_update: {y_update},\ty: {y},\tx: {approx_x_coordinate},\tx_update:{approx_x_coordinate - old_x}") + observation, reward, terminated, truncated, info = env.step(action) + if terminated or truncated: + observation, info = env.reset() + break + + img = Image.fromarray(observation) + img.save(f"images/{j:05}.png") + #observation, reward, terminated, truncated, info = env.step(0) + #observation, reward, terminated, truncated, info = env.step(0) + #observation, reward, terminated, truncated, info = env.step(0) + #observation, reward, terminated, truncated, info = env.step(0) +env.close() diff --git a/init.png b/init.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8ebdee37899d791cd602f9a3c97f48557f4190 GIT binary patch literal 1065 zcmeAS@N?(olHy`uVBq!ia0vp^3xN0%2NRHVa*x@-z`*>$)5S5QV$R#U2McFANH{$7 zJ*H}~N`dv~lF3~GtaeM7L?=%6vs)q)zF=X8jD)d-n2Nj8n|=Rl+54G{4%Thvj;nk! zMa8rAm*Musxwq5jwZFS!;#>Cny!!n1d1nq3=ts{#aJc8$iifIcJG5^tWjAfQ?Vl;I zwc6mW9E*CvmW7qd=S1cv`5!H|X#Bmh;r6-E&KhxYx(x@;@xilV^7}i znx`FEur7r)HNk@Uu%yJf0|jht#s+g5AM)^|V+x5Iet253N2Wh|{?W-UJThK84*b2r zYt)g<$|qE+5%3`MF2`PGRzJ^)G{;6r<3ovGpMf_!*PZSQTgCN0 zyer`{4Q%I@S(V2nu|qh08lSj@-z~o#2QErL9PruJN};B|Zvj>}U~v{rgjn|9|6aTs z>V&;HwM@HCAG*5zF$XkwVzzI;{`vOn%7>i)DkC}m@6ow=Xzvzfi9>=iQ?LeJ#{P?i zJ7azw-+edlu(2kK`Uiuz1>PUdl(NrryXvvFG2dUhMy7f)Yxrx9cWzHUS@2nBwP*3( zF?<;6cM)5ZEM>VTZ}+Xezp6iejS|!PziazvZrfa&@OoX=;{(@XZy#$sUtbqm`{z@x zz3c6Y(A(^OW^uuSjgx!BgS`^g9zlxb=h6!uf4F5hBE|jbq94^2Zy0%b(jPpsDHD+1 zp};?X{^Z7wJTZ&d`BIq=|4d?T(KlnkNHVYLw%=U2bN=`C*Jd}L2Z)y`G|pc3lI!c- zU%D@|FTOK0eJ+yN^={Tz`Q?`G|KGeao9{N?`i_yUQz=K|+ZkL zYH~Qc(2uO1H)m|5-u*AU@yU_tev$87zH3jzopr0C0fU2LJ#7 literal 0 HcmV?d00001 diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..100a2f3 --- /dev/null +++ b/install.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# aptitude dependencies +sudo apt install python3.8-venv python3-tk +python3 -m pip install --user virtualenv +python3 -m venv env + +source env/bin/activate +which python3 diff --git a/query_sample_factory_checkpoint.py b/query_sample_factory_checkpoint.py new file mode 100644 index 0000000..97d9520 --- /dev/null +++ b/query_sample_factory_checkpoint.py @@ -0,0 +1,69 @@ +import time +from collections import deque +from typing import Dict, Tuple + +import gymnasium as gym +import numpy as np +import torch +from torch import Tensor + +from sample_factory.algo.learning.learner import Learner +from sample_factory.algo.sampling.batched_sampling import preprocess_actions +from sample_factory.algo.utils.action_distributions import argmax_actions +from sample_factory.algo.utils.env_info import extract_env_info +from sample_factory.algo.utils.make_env import make_env_func_batched +from sample_factory.algo.utils.misc import ExperimentStatus +from sample_factory.algo.utils.rl_utils import make_dones, prepare_and_normalize_obs +from sample_factory.algo.utils.tensor_utils import unsqueeze_tensor +from sample_factory.cfg.arguments import load_from_checkpoint +from sample_factory.huggingface.huggingface_utils import generate_model_card, generate_replay_video, push_to_hf +from sample_factory.model.actor_critic import create_actor_critic +from sample_factory.model.model_utils import get_rnn_size +from sample_factory.utils.attr_dict import AttrDict +from sample_factory.utils.typing import Config, StatusCode +from sample_factory.utils.utils import debug_log_every_n, experiment_dir, log + +from sf_examples.atari.train_atari import parse_atari_args, register_atari_components + +class SampleFactoryNNQueryWrapper: + def setup(self): + register_atari_components() + cfg = parse_atari_args() + actor_critic = create_actor_critic(cfg, gym.spaces.Dict({"obs": gym.spaces.Box(0, 255, (4, 84, 84), np.uint8)}), gym.spaces.Discrete(3)) # TODO + actor_critic.eval() + + device = torch.device("cpu") # ("cpu" if cfg.device == "cpu" else "cuda") + actor_critic.model_to_device(device) + + policy_id = 0 #cfg.policy_index + #name_prefix = dict(latest="checkpoint", best="best")[cfg.load_checkpoint_kind] + name_prefix = "best" + checkpoints = Learner.get_checkpoints(Learner.checkpoint_dir(cfg, policy_id), f"{name_prefix}_*") + checkpoint_dict = Learner.load_checkpoint(checkpoints, device) # torch.load(...) + actor_critic.load_state_dict(checkpoint_dict["model"]) + + rnn_states = torch.zeros([1, get_rnn_size(cfg)], dtype=torch.float32, device=device) + + self.rnn_states = rnn_states + self.actor_critic = actor_critic + + def __init__(self): + self.setup() + + + def query(self, obs): + with torch.no_grad(): + normalized_obs = prepare_and_normalize_obs(self.actor_critic, obs) + policy_outputs = self.actor_critic(normalized_obs, self.rnn_states) + + # sample actions from the distribution by default + actions = policy_outputs["actions"] + + action_distribution = self.actor_critic.action_distribution() + actions = argmax_actions(action_distribution) + + if actions.ndim == 1: + actions = unsqueeze_tensor(actions, dim=-1) + + rnn_states = policy_outputs["new_rnn_states"] + return actions[0][0].item() diff --git a/rom_evaluate.py b/rom_evaluate.py new file mode 100644 index 0000000..bb4b420 --- /dev/null +++ b/rom_evaluate.py @@ -0,0 +1,189 @@ +import sys +from random import randrange +from ale_py import ALEInterface, SDL_SUPPORT, Action +from colors import * +from PIL import Image +from matplotlib import pyplot as plt +import cv2 +import pickle +import queue + +from copy import deepcopy + +import numpy as np + +import readchar + +from sample_factory.algo.utils.tensor_dict import TensorDict +from query_sample_factory_checkpoint import SampleFactoryNNQueryWrapper + +import time + + +def input_to_action(char): + if char == "0": + return Action.NOOP + if char == "1": + return Action.RIGHT + if char == "2": + return Action.LEFT + if char == "3": + return "reset" + if char == "4": + return "set_x" + if char == "5": + return "set_vel" + if char in ["w", "a", "s", "d"]: + return char + +ski_position_counter = {1: (Action.LEFT, 40), 2: (Action.LEFT, 35), 3: (Action.LEFT, 30), 4: (Action.LEFT, 10), 5: (Action.NOOP, 1), 6: (Action.RIGHT, 10), 7: (Action.RIGHT, 30), 8: (Action.RIGHT, 40) } + +def run_single_test(ale, nn_wrapper, x,y,ski_position, duration=200): + print(f"Running Test from x: {x:04}, y: {y:04}, ski_position: {ski_position}") + for i, r in enumerate(ramDICT[y]): + ale.setRAM(i,r) + ski_position_setting = ski_position_counter[ski_position] + for i in range(0,ski_position_setting[1]): + ale.act(ski_position_setting[0]) + ale.setRAM(14,0) + ale.setRAM(25,x) + ale.setRAM(14,180) + + all_obs = list() + for i in range(0,duration): + resized_obs = cv2.resize(ale.getScreenGrayscale() , (84,84), interpolation=cv2.INTER_AREA) + all_obs.append(resized_obs) + if len(all_obs) >= 4: + stack_tensor = TensorDict({"obs": np.array(all_obs[-4:])}) + action = nn_wrapper.query(stack_tensor) + ale.act(input_to_action(str(action))) + else: + ale.act(Action.NOOP) + time.sleep(0.005) + +ale = ALEInterface() + + +if SDL_SUPPORT: + ale.setBool("sound", True) + ale.setBool("display_screen", True) + +# Load the ROM file +rom_file = "/home/spranger/research/Skiing/env/lib/python3.8/site-packages/AutoROM/roms/skiing.bin" +ale.loadROM(rom_file) + +# Get the list of legal actions + +with open('all_positions_v2.pickle', 'rb') as handle: + ramDICT = pickle.load(handle) +#ramDICT = dict() +#for i,r in enumerate(ramDICT[235]): +# ale.setRAM(i,r) + +y_ram_setting = 60 +x = 70 + + +nn_wrapper = SampleFactoryNNQueryWrapper() +#run_single_test(ale, nn_wrapper, 70,61,5) +#input("") +run_single_test(ale, nn_wrapper, 30,61,5,duration=1000) +run_single_test(ale, nn_wrapper, 114,170,7) +run_single_test(ale, nn_wrapper, 124,170,5) +run_single_test(ale, nn_wrapper, 134,170,2) +run_single_test(ale, nn_wrapper, 120,185,1) +run_single_test(ale, nn_wrapper, 134,170,8) +run_single_test(ale, nn_wrapper, 85,195,8) +velocity_set = False +for episode in range(10): + total_reward = 0 + j = 0 + while not ale.game_over(): + if not velocity_set: ale.setRAM(14,0) + j += 1 + a = input_to_action(repr(readchar.readchar())[1]) + #a = Action.NOOP + + if a == "w": + y_ram_setting -= 1 + if y_ram_setting <= 61: + y_ram_setting = 61 + for i, r in enumerate(ramDICT[y_ram_setting]): + ale.setRAM(i,r) + ale.setRAM(25,x) + ale.act(Action.NOOP) + elif a == "s": + y_ram_setting += 1 + if y_ram_setting >= 1950: + y_ram_setting = 1945 + for i, r in enumerate(ramDICT[y_ram_setting]): + ale.setRAM(i,r) + ale.setRAM(25,x) + ale.act(Action.NOOP) + elif a == "a": + x -= 1 + if x <= 0: + x = 0 + ale.setRAM(25,x) + ale.act(Action.NOOP) + elif a == "d": + x += 1 + if x >= 144: + x = 144 + ale.setRAM(25,x) + ale.act(Action.NOOP) + + + elif a == "reset": + ram_pos = input("Ram Position:") + for i, r in enumerate(ramDICT[int(ram_pos)]): + ale.setRAM(i,r) + ale.act(Action.NOOP) + # Apply an action and get the resulting reward + elif a == "set_x": + x = int(input("X:")) + ale.setRAM(25, x) + ale.act(Action.NOOP) + elif a == "set_vel": + vel = input("Velocity:") + ale.setRAM(14, int(vel)) + ale.act(Action.NOOP) + velocity_set = True + else: + reward = ale.act(a) + ram = ale.getRAM() + #if j % 2 == 0: + # y_pixel = int(j*1/2) + 55 + # ramDICT[y_pixel] = ram + # print(f"saving to {y_pixel:04}") + # if y_pixel == 126 or y_pixel == 235: + # input("") + + int_old_ram = list(map(int, oldram)) + int_ram = list(map(int, ram)) + difference = list() + for o, r in zip(int_old_ram, int_ram): + difference.append(r-o) + + oldram = deepcopy(ram) + #print(f"player_x: {ram[25]},\tclock_m: {ram[104]},\tclock_s: {ram[105]},\tclock_ms: {ram[106]},\tscore: {ram[107]}") + print(f"player_x: {ram[25]},\tplayer_y: {y_ram_setting}") + #print(f"y_0: {ram[86]}, y_1: {ram[87]}, y_2: {ram[88]}, y_3: {ram[89]}, y_4: {ram[90]}, y_5: {ram[91]}, y_6: {ram[92]}, y_7: {ram[93]}, y_8: {ram[94]}") + + #for i, r in enumerate(ram): + # print('{:03}:{:02x} '.format(i,r), end="") + # if i % 16 == 15: print("") + #print("") + #for i, r in enumerate(difference): + # string = '{:02}:{:03} '.format(i%100,r) + # if r != 0: + # print(color(string, fg='red'), end="") + # else: + # print(string, end="") + # if i % 16 == 15: print("") + print("Episode %d ended with score: %d" % (episode, total_reward)) + input("") + + with open('all_positions_v2.pickle', 'wb') as handle: + pickle.dump(ramDICT, handle, protocol=pickle.HIGHEST_PROTOCOL) + ale.reset_game()