"AttributeError: 'dict' object has no attribute 'flatten'".
I get this error when I run the following code:
import math
from gym import Env
from gym.spaces import Discrete, Box, Dict, Tuple, MultiBinary, MultiDiscrete
from stable_baselines3 import PPO
screen_width = 900
class GameEnv(Env):
def __init__(self):
self.action_space = Discrete(5)
observation_positions = Box(low=0, high=screen_width, shape=(2,))
self.observation_space = Dict({'observation_positions': observation_positions})
self.state = self.observation_space.sample()
def step(self, action):
self.state = self.observation_space.sample()
def render(self):
pass
def reset(self):
return self.state
env = GameEnv()
model = PPO('MlpPolicy', env, verbose=1,)
model.learn(total_timesteps=1000)
What do I have to change?
You may have to use MultiInputPolicy instead of MlpPolicy as the first parameter to the PPO class when using a Dict observation space:
model = PPO('MultiInputPolicy', env, verbose=1,)
Related
I am training a stable_baselines3 PPO agent and want to perform some task on every step. To do this, I'm using a callback CustomCallback with _on_step method defined.
But it appears that _on_step is called only on every PPO.n_steps, so if n_steps param is 1024, then CustomCallback._on_step appears to be called only on every 1024 steps.
How can you do something on every 1 step, insted of on every PPO.n_steps steps?
from stable_baselines3 import PPO
from stable_baselines3.common.env_util import make_vec_env
from stable_baselines3.common.callbacks import BaseCallback
class CustomCallback(BaseCallback):
def __init__(self, freq, verbose=0):
super().__init__(verbose)
self.freq = freq
def _on_step(self):
if self.n_calls % self.freq == 0:
print('do something')
return True
env = make_vec_env("CartPole-v1", n_envs=1)
model = PPO("MlpPolicy", env, n_steps=1024)
model.learn(
total_timesteps=25000,
callback=CustomCallback(freq=123),
)
I have this codes python
image_formats = [('xz','xz'), ('gz','gz')]
config.image_format = ConfigSelection(default = "xz", choices = image_formats)
mounted_devices = getmDevices()
class1(Screen):
def __init__(self, session):
config.device_path = ConfigSelection(choices = mounted_devices)
self.createSetup()
def createSetup(self):
self.list.append(getConfigListEntry(('Path to store Full Backup'), config.device_path
self.list.append(getConfigListEntry(('Select Format to Compress BackUp'), config.image_format
self['config'].list = self.list
self['config'].l.setList(self.list)
def configsSave(self):
for x in self['config'].list:
x[1].save()
configfile.save()
class2(Screen):
def __init__(self, session):
self.doBackUp()
def doBackUp(self, target):
self.configsSave()
image_name = target
device_path = self['config'].list[0][1].getText()
print("device_path ****************", device_path)
image_formats = self['config'].list[1][1].getText()
print("image_formats ****************", image_formats)
And I have got this error
self.configsSave()
~~~~^^^^^^^^^^
KeyError: 'configsSave'
device_path = self['config'].list[0][1].getText()
~~~~^^^^^^^^^^
image_formats = self['config'].list[0][1].getText()
~~~~^^^^^^^^^^
KeyError: 'config'
So How can I import from class1 complete configsSave function and config list from createSetup function to class2 and solve the error ?!!
If you want both class to share mothod you can tell class2 to inherit from class1 one with this syntax:
class class1(Screen):
enter code here
# class1 one declaration
# Making class 2 inherit from class one
class class2(class1):
super().__init__()
def __init__(self, session):
self.doBackUp()
def doBackUp(self, target):
self.configsSave()
image_name = target
device_path = self['config'].list[0][1].getText()
print("device_path ****************", device_path)
image_formats = self['config'].list[1][1].getText()
print("image_formats ****************", image_formats)
After that you can use class1 methods on class2 objects.
I need to have 100 of those similar python scripts that have MyData class from MyData_1 to MyData_100.
import torch
import numpy as np
from torch_geometric.data import InMemoryDataset, Data
from torch_geometric.utils import to_undirected
class MyData_1(InMemoryDataset):
def __init__(self, root, transform=None):
super(MyData_1, self).__init__(root, transform)
self.data, self.slices = torch.load(self.processed_paths[0])
#property
def raw_file_names(self):
return "mydata_1.npz"
#property
def processed_file_names(self):
return "data_1.pt"
def process(self):
raw_data = np.load(self.raw_paths[0])
cluster_data = torch.load('./raw/total_clusters.pt')
x = torch.from_numpy(raw_data['x'])
y = torch.from_numpy(raw_data['y'])
pos = torch.stack([x,y], dim=-1)
cp = torch.from_numpy(raw_data['cp'])
data_list = []
for i in range(cp.size(0)):
data = Data(x=cp[i].view(-1,1),pos=pos.view(-1,2), cluster=cluster_data[0])
data_list.append(data)
torch.save(self.collate(data_list), self.processed_paths[0])
I'm trying to do this because each MyData class calls different mydata_1,2,...100.npz to generate dataset.
Is there any way to make this fast?
Thanks in advance!
I didn't fully understand the reason why you need to create 100 different classes.
Is it because you need to return mydata_1.npz to mydata_100.npz? If then, You can create a single class like this:
class Myclass:
def __init__(self, index):
self.index = index
def raw_file_names(self):
return "mydata_{}.npz".format(self.index)
Then, at another script like main.py, you can create/assign it like:
for i in range(100):
exec('dataset_{} = MyData_{}({})'.format(i, i, i))
I believe you can build your own code that fits your problem with above examples.
You can achieve this by creating Metaclass(subclass ) below is a example how to pass dynamic name of class in subclass magicfunction
MyDynamicSubclass
class MyClass:
def __init_subclass__(cls, my_name):
print(f"Subclass created and my name is {my_name}")
print(cls, cls.__class__.__name__)
MyDynamicSubclass = type("MyDynamicSubclass", (MyClass,), {}, my_name="Ellis")
output:
<class 'main.MyDynamicSubclass'> type
I'm making a game using the pygame module and I have a player class:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle, walk = None, jump = None):
pygame.sprite.Sprite.__init__(self)
self.name = name
self.idle = idle
self.walk = walk
self.jump = jump
self.image = self.idle[0]
self.movment = movment
self.left, self.right = axsis
self.pos = vec(position[0],position[1])
I am adding my characters using json data type and trying to add animations after calling the class but i can't do it
Sample code
class Game():
def __init__(self,json_file):
self.player_attribute = json_file
def character(self):
self.npc = []
for i in self.player_attribute:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment']))
self.animation()
return self.npc
def add_animation(self):
for i in self.npc:
i.idle = "images\ghost.png"
def main_loop()
self.character
when i try this i get an error
self.image = self.idle[0]
TypeError: init() missing 1 required positional argument: 'idle'
how can i add the variables of the class after calling the class
It is not clear what the 'idle' parameter is supposed to represent in your code. However, the reason for the exception is that you are not passing any argument for 'idle' when constructing the Player object. You need something like:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment'],
i['idle']))
You can either do that or alternatively you can pass a default argument to the Player constructor so that, when initializing you do not need to explicitly pass idle:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle=[1], walk = None, jump = None):
You can modify its content at a later time, however I suggest you are careful what you instantiate that object attribute as, because it might come bite you back later (type error or value error).
If it were me, I would move this out of init, or not build the object until all values and their types are known (see Builder Design Pattern).
Hope this helped :) Cheers!
I want to create a game in which there is a lead time in the actions of the player and the rewards/consequences, therefore, I would like to not share the observation completely with the player, but still persist it because it's need for future. Is there a way we can do that?
If I create a variable in init and update it, it's visible to every instance of the game, so a player already knows a lot more than I'd have them know.
A rough example for your requirement on Cartpole would be something like this:
import gym
from gym.utils import seeding
import numpy as np
class myEnv(gym.Env):
def __init__(self, *args, **kwargs):
"""
Define all the necessary stuff here
"""
self.env = gym.make('CartPole-v1') # add stuff here to define game params
self.action_space = self.env.action_space
self.observation_space = self.env.observation_space
self.past_actions = []
self.delay = 2 # to have a delay of two timesteps
def reset(self):
"""
Define the reset
"""
self.observation = self.env.reset()
return self.observation
def step(self, action):
"""
Add the delay of actions here
"""
self.past_actions.append(action) # to keep track of actions
reward = 0; done = 0; info = {} # reward, done and info are 0,0,{} for first two timesteps
if len(self.past_actions) > self.delay:
present_action = self.past_actions.pop(0)
# change observation, reward, done, info
# according to the action 'delay' timesteps ago
self.observation, reward, done, info = self.env.step(present_action)
return self.observation, reward, done, info
def seed(self, seed=0):
"""
Define seed method here
"""
self.np_random, seed = seeding.np_random(seed)
return self.env.seed(seed=seed)
def render(self, mode="human", *args, **kwargs):
"""
Define rendering method here
"""
return self.env.render(*args, **kwargs)
def close(self):
"""
Define close method here
"""
return self.env.close()