Here is a loss module:
loss_module = ClipPPOLoss(
actor_network = policy_module,
critic_network = critic,
clip_epsilon = clip_epsilon,
entropy_bonus = bool(entropy_eps),
entropy_coeff = entropy_eps,
# these keys match by default but we set this for completeness
critic_coeff = 1.0,
loss_critic_type = "smooth_l1",
)
and in training loop:
for _ in range(frames_per_batch // minibatch_size):
subdata = replay_buffer.sample(minibatch_size)
print(subdata)
loss_vals = loss_module(subdata.to(device)) # <-- ERR unbatched !
Here is the result of print(subdata):
TensorDict(
fields={
action: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.int64, is_shared=False),
action_log_prob: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
action_mask: Tensor(shape=torch.Size([12, 1, 4]), device=cpu, dtype=torch.bool, is_shared=False),
advantage: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
angle: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
bid: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
collector: TensorDict(
fields={
traj_ids: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.int64, is_shared=False)},
batch_size=torch.Size([12]),
device=cpu,
is_shared=False),
done: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.bool, is_shared=False),
logits: Tensor(shape=torch.Size([12, 4]), device=cpu, dtype=torch.float32, is_shared=False),
next: TensorDict(
fields={
action_mask: Tensor(shape=torch.Size([12, 1, 4]), device=cpu, dtype=torch.bool, is_shared=False),
angle: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
bid: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
done: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.bool, is_shared=False),
observation: Tensor(shape=torch.Size([12, 6]), device=cpu, dtype=torch.float32, is_shared=False),
params: TensorDict(
fields={
a: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
b: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.int64, is_shared=False),
dt: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
h: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
k: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False)},
batch_size=torch.Size([12]),
device=cpu,
is_shared=False),
posA: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
posV: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
reward: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
solde: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
state_value: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
step_count: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.int64, is_shared=False),
t: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
terminated: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.bool, is_shared=False)},
batch_size=torch.Size([12]),
device=cpu,
is_shared=False),
observation: Tensor(shape=torch.Size([12, 6]), device=cpu, dtype=torch.float32, is_shared=False),
params: TensorDict(
fields={
a: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
b: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.int64, is_shared=False),
dt: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
h: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False),
k: Tensor(shape=torch.Size([12]), device=cpu, dtype=torch.float32, is_shared=False)},
batch_size=torch.Size([12]),
device=cpu,
is_shared=False),
posA: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
posV: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
solde: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
state_value: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
step_count: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.int64, is_shared=False),
t: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False),
terminated: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.bool, is_shared=False),
value_target: Tensor(shape=torch.Size([12, 1]), device=cpu, dtype=torch.float32, is_shared=False)},
batch_size=torch.Size([12]),
device=cpu,
is_shared=False)
and here is the traceback error:
Traceback (most recent call last):
File "/home/fauche/Documents/RenforcementLearning/CosPPO2.py", line 220, in <module>
loss_vals = loss_module(subdata.to(device)) # <-- ERR unbatched !
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1751, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1857, in _call_impl
return inner()
^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1805, in inner
result = forward_call(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torchrl/objectives/common.py", line 54, in new_forward
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/tensordict/nn/common.py", line 328, in wrapper
return func(_self, tensordict, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torchrl/objectives/ppo.py", line 1174, in forward
log_weight, dist, kl_approx = self._log_weight(
^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torchrl/objectives/ppo.py", line 681, in _log_weight
log_prob, dist, is_composite = self._get_cur_log_prob(tensordict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torchrl/objectives/ppo.py", line 647, in _get_cur_log_prob
log_prob = dist.log_prob(action)
^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torchrl/modules/distributions/discrete.py", line 362, in log_prob
result = -torch.nn.functional.cross_entropy(logits, value, reduce=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/fauche/Documents/IAvenv/lib/python3.11/site-packages/torch/nn/functional.py", line 3494, in cross_entropy
return torch._C._nn.cross_entropy_loss(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Expected target size [12, 12], got [12, 1]
why expected target size is [12, 12] ? minibatch_size = 12
For more info here is the policy_module:
policy_module = ProbabilisticActor(
module = policy_module,
spec = env.action_spec,
in_keys={"logits": "logits", "mask": "action_mask"},
out_keys=["action"],
distribution_class = MaskedCategorical,
return_log_prob = True
)