I’m trying to make a Flappy Bird AI, using the flappy_bird_gym repository using Tensorflow. I have created an environment using conda in WSL2, tensorflow version 2.17, with keras-rl2 and keras 3, python 3.10.14.
But when I try to build my DQN error I get this error.
Here’s the code snippet,
import flappy_bird_gym
env = flappy_bird_gym.make("FlappyBird-v0")
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from keras.optimizers import Adam
from rl.agents import DQNAgent
from rl.memory import SequentialMemory
from rl.policy import LinearAnnealedPolicy, EpsGreedyQPolicy
def build_model(input, actions):
model = Sequential()
model.add(Flatten(input_shape=(1, input)))
model.add(Dense(64, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Flatten(input_shape=(1, input)))
model.add(Dense(actions, activation='linear'))
model.summary()
return model
obs = env.observation_space.shape[0]
actions = env.action_space.n
model = build_model(obs, actions)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ flatten (Flatten) │ (None, 2) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense) │ (None, 64) │ 192 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 128) │ 8,320 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 256) │ 33,024 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 64) │ 16,448 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_4 (Dense) │ (None, 128) │ 8,320 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten_1 (Flatten) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_5 (Dense) │ (None, 2) │ 258 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 66,562 (260.01 KB)
Trainable params: 66,562 (260.01 KB)
Non-trainable params: 0 (0.00 B)
def build_agent(model, actions):
policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=0.5, value_min=.0001, value_test=.0, nb_steps=6000000)
memory = SequentialMemory(limit=100000, window_length=1)
dqn = DQNAgent(model=model, memory=memory, policy=policy,
enable_dueling_network=True, dueling_type='avg',
nb_actions=actions, nb_steps_warmup=500)
return dqn
model.compile(optimizer=Adam(learning_rate=0.0025), loss='mse')
dqn = build_agent(model, actions)
**Error: **
ValueError Traceback (most recent call last)
Cell In[7], line 9
7 return dqn
8 model.compile(optimizer=Adam(learning_rate=0.0025), loss='mse')
----> 9 dqn = build_agent(model, actions)
Cell In[7], line 4, in build_agent(model, actions)
2 policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=0.5, value_min=.0001, value_test=.0, nb_steps=6000000)
3 memory = SequentialMemory(limit=100000, window_length=1)
----> 4 dqn = DQNAgent(model=model, memory=memory, policy=policy,
5 enable_dueling_network=True, dueling_type='avg',
6 nb_actions=actions, nb_steps_warmup=500)
7 return dqn
File ~/miniconda3/envs/env/lib/python3.10/site-packages/rl/agents/dqn.py:106, in DQNAgent.__init__(self, model, policy, test_policy, enable_double_dqn, enable_dueling_network, dueling_type, *args, **kwargs)
103 super().__init__(*args, **kwargs)
105 # Validate (important) input.
--> 106 if list(model.output.shape) != list((None, self.nb_actions)):
107 raise ValueError(f'Model output "{model.output}" has invalid shape. DQN expects a model that has one dimension for each action, in this case {self.nb_actions}.')
109 # Parameters.
File ~/miniconda3/envs/env/lib/python3.10/site-packages/keras/src/ops/operation.py:266, in Operation.output(self)
256 @property
257 def output(self):
258 """Retrieves the output tensor(s) of a layer.
259
260 Only returns the tensor(s) corresponding to the *first time*
(...)
264 Output tensor or list of output tensors.
265 """
--> 266 return self._get_node_attribute_at_index(0, "output_tensors", "output")
File ~/miniconda3/envs/env/lib/python3.10/site-packages/keras/src/ops/operation.py:285, in Operation._get_node_attribute_at_index(self, node_index, attr, attr_name)
269 """Private utility to retrieves an attribute (e.g. inputs) from a node.
270
271 This is used to implement the properties:
(...)
282 The operation's attribute `attr` at the node of index `node_index`.
283 """
284 if not self._inbound_nodes:
--> 285 raise ValueError(
286 f"The layer {self.name} has never been called "
287 f"and thus has no defined {attr_name}."
288 )
289 if not len(self._inbound_nodes) > node_index:
290 raise ValueError(
291 f"Asked to get {attr_name} at node "
292 f"{node_index}, but the operation has only "
293 f"{len(self._inbound_nodes)} inbound nodes."
294 )
ValueError: The layer sequential has never been called and thus has no defined output.