Issue
I tried implementing a Deep Reinforcement Learning Network but I get the same error every time I try to run it,
class Atari(object):
"""Wrapper for the environment provided by gym"""
def __init__(self, envName, no_op_steps=10, agent_history_length=4):
self.env = gym.make(envName)
self.process_frame = FrameProcessor()
self.state = None
self.last_lives = 0
self.no_op_steps = no_op_steps
self.agent_history_length = agent_history_length
def reset(self, sess, evaluation=False):
"""
Args:
sess: A Tensorflow session object
evaluation: A boolean saying whether the agent is evaluating or training
Resets the environment and stacks four frames ontop of each other to
create the first state
"""
frame = self.env.reset()
self.last_lives = 0
terminal_life_lost = True # Set to true so that the agent starts
# with a 'FIRE' action when evaluating
if evaluation:
for _ in range(random.randint(1, self.no_op_steps)):
frame, _, _, _ = self.env.step(1) # Action 'Fire'
processed_frame = self.process_frame(sess, frame) # (★★★)
self.state = np.repeat(processed_frame, self.agent_history_length, axis=2)
return terminal_life_lost
The line where I am getting the error is at `processed_frame = self.process_frame(sess, frame)
class FrameProcessor(object):
"""Resizes and converts RGB Atari frames to grayscale"""
def __init__(self, frame_height=84, frame_width=84):
self.frame_height = frame_height
self.frame_width = frame_width
self.frame = tf.compat.v1.placeholder(shape=[210, 160, 3], dtype=tf.uint8)
self.processed = tf.image.rgb_to_grayscale(self.frame)
self.processed = tf.image.crop_to_bounding_box(self.processed, 34, 0, 160, 160)
self.processed = tf.image.resize(self.processed,
[self.frame_height, self.frame_width],
method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
def __call__(self, session, frame):
return session.run(self.processed, feed_dict={self.frame:frame})
Solution
(See my comment under OP for context)
The error message "FrameProcessor" object is not callable
means what it says on the tin: there is an object of type "FrameProcessor", and your code is trying to call this object despite the fact that this object cannot be called.
(Remember that to call something is to treat it as a function and to try to run this function, much like how you might call a parent at a grocery store and tell them to buy you a snack.)
Where does your code try to call this FrameProcessor
object? Well, you yourself pointed out the line:
processed_frame = self.process_frame(sess, frame)
.
In Python, any time you write an expression of the form something(arg1, arg2, ...)
, the Python interpreter treats the expression as a function call, which, from your error message, we know we’re not allowed to do if the something
happens to be a FrameProcessor
.
And we know from the earlier line self.process_frame = FrameProcessor()
that self.process_frame
is a FrameProcessor
. So the problem is that you’re trying to call self.process_frame
like a function when it really oughtn’t be called in that way.
So, how can this be fixed?
Look up the documentation for FrameProcessor
, wherever that happens to be, so that you can know how FrameProcessors
ought to be used. With that knowledge, you can revise the lines processed_frame = self.process_frame(sess, frame)
and maybe self.process_frame = FrameProcessor()
to match the intended usage, whatever that may be. At that point it’s just a matter of reading and applying the relevant documentation.
EDIT:
Looking at the code for FrameProcessor
, it seems the issue is caused by an extra indent before __call__
is defined. Indents determine scope in Python, and the extra indent is causing __call__
to be defined in the local scope of the __init__
function. That means that __call__
has no meaning outside the body of __init__
, which is not what we want. Try removing the extra indent before __call__
and see if that solves the issue.
Answered By – Asker
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0