A2CLoss¶
- class torchrl.objectives.A2CLoss(*args, **kwargs)[原始碼]¶
A2C 損失的 TorchRL 實作。
A2C (優勢演員評論家) 是一種無模型、線上 RL 演算法,它使用 n 步的平行展開來更新策略,依賴於 REINFORCE 估計器來計算梯度。它還將熵項添加到目標函數中,以改進探索。
有關 A2C 的更多詳細資訊,請參閱:「深度強化學習的非同步方法」,https://arxiv.org/abs/1602.01783v2
- 參數:
actor_network (ProbabilisticTensorDictSequential) – 策略運算子。
critic_network (ValueOperator) – 數值運算子。
entropy_bonus (bool) – 如果
True
,則會將熵獎勵添加到損失中,以支持探索性策略。samples_mc_entropy (int) – 如果從策略運算子檢索的分佈沒有熵的閉合形式公式,則將使用蒙地卡羅估計。
samples_mc_entropy
將控制用於計算此估計的樣本數量。預設為1
。entropy_coef (float) – 熵損失的權重。預設為 0.01`。
critic_coef (float) – 評論家損失的權重。預設為
1.0
。如果None
,則不會包含評論家損失,且 in-keys 將會遺失評論家輸入。loss_critic_type (str) – 值差異的損失函數。可以是 “l1”、“l2” 或 “smooth_l1” 之一。預設為
"smooth_l1"
。separate_losses (bool, optional) – 如果
True
,策略和評論家之間的共享參數將僅在策略損失上進行訓練。預設為False
,即梯度會傳播到策略和評論家損失的共享參數。advantage_key (str) – [已棄用,請改用 set_keys(advantage_key=advantage_key)] 輸入 tensordict 金鑰,期望在其中寫入優勢。預設值:「advantage」
value_target_key (str) – [已棄用,請改用 set_keys()] 輸入 tensordict 金鑰,期望在其中寫入目標狀態值。預設值為
"value_target"
。functional (bool, optional) – 模組是否應進行函數化。函數化允許諸如元 RL 之類的特性,但使得無法使用分散式模型(DDP、FSDP、…),並且會產生一些成本。預設為
True
。reduction (str, optional) – 指定要套用至輸出的縮減方式:
"none"
|"mean"
|"sum"
。"none"
:不套用任何縮減;"mean"
:輸出的總和將除以輸出中的元素數量;"sum"
:輸出將被加總。預設值:"mean"
。clip_value (float, optional) – 如果提供此值,將用於計算相對於輸入值估計的裁剪版本的值預測,並使用它來計算值損失。裁剪的目的是限制極端值預測的影響,幫助穩定訓練並防止大型更新。但是,如果值估計是由當前版本的值估計器完成的,則它將沒有影響。預設值為
None
。
範例
>>> import torch >>> from torch import nn >>> from torchrl.data import Bounded >>> from torchrl.modules.distributions import NormalParamExtractor, TanhNormal >>> from torchrl.modules.tensordict_module.actors import ProbabilisticActor, ValueOperator >>> from torchrl.modules.tensordict_module.common import SafeModule >>> from torchrl.objectives.a2c import A2CLoss >>> from tensordict import TensorDict >>> n_act, n_obs = 4, 3 >>> spec = Bounded(-torch.ones(n_act), torch.ones(n_act), (n_act,)) >>> net = nn.Sequential(nn.Linear(n_obs, 2 * n_act), NormalParamExtractor()) >>> module = SafeModule(net, in_keys=["observation"], out_keys=["loc", "scale"]) >>> actor = ProbabilisticActor( ... module=module, ... in_keys=["loc", "scale"], ... spec=spec, ... distribution_class=TanhNormal) >>> module = nn.Linear(n_obs, 1) >>> value = ValueOperator( ... module=module, ... in_keys=["observation"]) >>> loss = A2CLoss(actor, value, loss_critic_type="l2") >>> batch = [2, ] >>> action = spec.rand(batch) >>> data = TensorDict({ ... "observation": torch.randn(*batch, n_obs), ... "action": action, ... ("next", "done"): torch.zeros(*batch, 1, dtype=torch.bool), ... ("next", "terminated"): torch.zeros(*batch, 1, dtype=torch.bool), ... ("next", "reward"): torch.randn(*batch, 1), ... ("next", "observation"): torch.randn(*batch, n_obs), ... }, batch) >>> loss(data) TensorDict( fields={ entropy: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_critic: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_entropy: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_objective: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False)
此類別也與非 tensordict 基礎的模組相容,並且可以在不使用任何 tensordict 相關的原始元件的情況下使用。在這種情況下,預期的關鍵字參數為:
["action", "next_reward", "next_done", "next_terminated"]
+ actor 和 critic 的 in_keys。傳回值是一個 tensors 的元組,順序如下:["loss_objective"]
+ 如果 critic_coef 不是 None,則加上["loss_critic"]
+ 如果 entropy_bonus 為 True 且 critic_coef 不是 None,則加上["entropy", "loss_entropy"]
範例
>>> import torch >>> from torch import nn >>> from torchrl.data import Bounded >>> from torchrl.modules.distributions import NormalParamExtractor, TanhNormal >>> from torchrl.modules.tensordict_module.actors import ProbabilisticActor, ValueOperator >>> from torchrl.modules.tensordict_module.common import SafeModule >>> from torchrl.objectives.a2c import A2CLoss >>> _ = torch.manual_seed(42) >>> n_act, n_obs = 4, 3 >>> spec = Bounded(-torch.ones(n_act), torch.ones(n_act), (n_act,)) >>> net = nn.Sequential(nn.Linear(n_obs, 2 * n_act), NormalParamExtractor()) >>> module = SafeModule(net, in_keys=["observation"], out_keys=["loc", "scale"]) >>> actor = ProbabilisticActor( ... module=module, ... in_keys=["loc", "scale"], ... spec=spec, ... distribution_class=TanhNormal) >>> module = nn.Linear(n_obs, 1) >>> value = ValueOperator( ... module=module, ... in_keys=["observation"]) >>> loss = A2CLoss(actor, value, loss_critic_type="l2") >>> batch = [2, ] >>> loss_obj, loss_critic, entropy, loss_entropy = loss( ... observation = torch.randn(*batch, n_obs), ... action = spec.rand(batch), ... next_done = torch.zeros(*batch, 1, dtype=torch.bool), ... next_terminated = torch.zeros(*batch, 1, dtype=torch.bool), ... next_reward = torch.randn(*batch, 1), ... next_observation = torch.randn(*batch, n_obs)) >>> loss_obj.backward()
也可以使用
SACLoss.select_out_keys()
方法來篩選輸出鍵。範例
>>> loss.select_out_keys('loss_objective', 'loss_critic') >>> loss_obj, loss_critic = loss( ... observation = torch.randn(*batch, n_obs), ... action = spec.rand(batch), ... next_done = torch.zeros(*batch, 1, dtype=torch.bool), ... next_terminated = torch.zeros(*batch, 1, dtype=torch.bool), ... next_reward = torch.randn(*batch, 1), ... next_observation = torch.randn(*batch, n_obs)) >>> loss_obj.backward()
注意
關於與非 tensordict 基礎模組的相容性有一個例外。如果 actor 網路是機率性的,並且使用
CompositeDistribution
,則此類別必須與 tensordicts 一起使用,並且不能作為獨立於 tensordict 的模組運作。這是因為複合動作空間本質上依賴於 tensordicts 提供的結構化資料表示來處理它們的動作。- forward(tensordict: TensorDictBase = None) TensorDictBase [source]¶
它旨在讀取輸入 TensorDict 並傳回另一個具有名為“loss*”的損失鍵的 tensordict。
然後,訓練器可以使用將損失分成各個組成部分的方式,在整個訓練過程中記錄各種損失值。輸出 tensordict 中存在的其他純量也會被記錄。
- 參數:
tensordict – 一個輸入 tensordict,其中包含計算損失所需的值。
- 傳回:
一個新的 tensordict,沒有批次維度,包含各種損失純量,這些純量將被命名為“loss*”。 必須以這個名稱傳回損失,因為它們會在反向傳播之前被訓練器讀取。
- property functional¶
模組是否為函數式。
除非經過特別設計為非函數式,否則所有損失都是函數式的。
- loss_critic(tensordict: TensorDictBase) Tuple[Tensor, float] [source]¶
傳回 critic 的損失值,如果
critic_coef
不是None
,則乘以critic_coef
。傳回損失和裁剪比例。
- make_value_estimator(value_type: Optional[ValueEstimators] = None, **hyperparams)[source]¶
數值函數建構子。
如果需要非預設的數值函數,則必須使用此方法建構。
- 參數:
value_type (ValueEstimators) – 一個
ValueEstimators
枚舉類型,指示要使用的數值函數。 如果沒有提供,將使用儲存在default_value_estimator
屬性中的預設值。 生成的數值估計器類別將在self.value_type
中註冊,允許將來進行改進。**hyperparams – 用於價值函數的超參數。 如果未提供,將使用
default_value_kwargs()
指示的值。
範例
>>> from torchrl.objectives import DQNLoss >>> # initialize the DQN loss >>> actor = torch.nn.Linear(3, 4) >>> dqn_loss = DQNLoss(actor, action_space="one-hot") >>> # updating the parameters of the default value estimator >>> dqn_loss.make_value_estimator(gamma=0.9) >>> dqn_loss.make_value_estimator( ... ValueEstimators.TD1, ... gamma=0.9) >>> # if we want to change the gamma value >>> dqn_loss.make_value_estimator(dqn_loss.value_type, gamma=0.9)