LastAction#
- class torchrl.envs.transforms.LastAction(in_keys: Sequence[NestedKey] | NestedKey | None = None, out_keys: Sequence[NestedKey] | NestedKey | None = None, *, default: Literal['zeros', 'nan'] | float | int | Tensor = 'zeros', reset_key: NestedKey | None = None)[source]#
Copies the last action into the next observation.
This is the action analogue of
CatFrames: the policy can condition on the action taken at the previous step (delayed control, recurrent policies, residual action heads). On eachstep()the action at timetis written underout_keysin the"next"tensordict; onreset()the same keys are filled with a default value (zeros, NaN, or a user-provided fill). On a batch-unlocked parent the default is expanded by the runtime reset batch, preserving the action feature shape.out_keysare registered asUnboundedobservation specs with the action’s shape, dtype and device, so reset fills (zeros on a one-hot action, NaN on a bounded action) remain in-spec.- Parameters:
in_keys (NestedKey or sequence of NestedKey, optional) – keys pointing to the actions to remember. Defaults to the parent environment’s
action_keyswhen the transform is attached, or["action"]otherwise.out_keys (NestedKey or sequence of NestedKey, optional) – destination keys written into the observation. Defaults to each
in_keysentry with its last component replaced by"last_action"(e.g."action"->"last_action",("agents", "action")->("agents", "last_action")).
- Keyword Arguments:
default (str, number or torch.Tensor, optional) – value used to fill
out_keysonreset()."zeros"(default) writes zeros matching the action spec;"nan"writes NaNs (floating-point action specs only); a scalar is broadcast withfill_(); a tensor is broadcast to the action spec shape on the spec’s device and dtype. Defaults to"zeros".reset_key (NestedKey, optional) – the reset key to be used as a partial-reset indicator. Must be unique. If not provided, defaults to the only reset key of the parent environment (if it has only one) and raises an exception otherwise.
Examples
>>> from torchrl.envs import GymEnv, TransformedEnv >>> from torchrl.envs.transforms import LastAction >>> env = TransformedEnv(GymEnv("Pendulum-v1"), LastAction()) >>> td = env.reset() >>> td["last_action"] tensor([0.]) >>> rollout = env.rollout(3) >>> (rollout["next", "last_action"] == rollout["action"]).all() tensor(True)
See also
CatFramesfor stacking past observations,InitTrackerfor marking episode starts, andLastActionConfigfor the Hydra configuration.- forward(tensordict: TensorDictBase) TensorDictBase[source]#
Reads the input tensordict, and for the selected keys, applies the transform.
By default, this method:
calls directly
_apply_transform().does not call
_step()or_call().
This method is not called within env.step at any point. However, is is called within
sample().Note
forwardalso works with regular keyword arguments usingdispatchto cast the args names to the keys.Examples
>>> class TransformThatMeasuresBytes(Transform): ... '''Measures the number of bytes in the tensordict, and writes it under `"bytes"`.''' ... def __init__(self): ... super().__init__(in_keys=[], out_keys=["bytes"]) ... ... def forward(self, tensordict: TensorDictBase) -> TensorDictBase: ... bytes_in_td = tensordict.bytes() ... tensordict["bytes"] = bytes ... return tensordict >>> t = TransformThatMeasuresBytes() >>> env = env.append_transform(t) # works within envs >>> t(TensorDict(a=0)) # Works offline too.
- transform_observation_spec(observation_spec: TensorSpec) TensorSpec[source]#
Transforms the observation spec such that the resulting spec matches transform mapping.
- Parameters:
observation_spec (TensorSpec) – spec before the transform
- Returns:
expected spec after the transform