CrossQLoss¶
- class torchrl.objectives.CrossQLoss(*args, **kwargs)[來源]¶
CrossQ 損失的 TorchRL 實作。
於 “CROSSQ: BATCH NORMALIZATION IN DEEP REINFORCEMENT LEARNING FOR GREATER SAMPLE EFFICIENCY AND SIMPLICITY” 中介紹 https://openreview.net/pdf?id=PczQtTsTIX
此類別具有三個損失函數,這些函數將由 forward 方法依序呼叫:
qvalue_loss()
、actor_loss()
和alpha_loss()
。 或者,它們可以由使用者依此順序呼叫。- 參數:
actor_network (ProbabilisticActor) – 隨機 actor
qvalue_network (TensorDictModule) –
Q(s, a) 參數模型。 此模組通常輸出一個
"state_action_value"
條目。 如果提供了 qvalue_network 的單個實例,它將被複製num_qvalue_nets
次。 如果傳遞了模組清單,它們的參數將會堆疊,除非它們共享相同的識別碼(在這種情況下,原始參數將會展開)。警告
如果傳遞了參數清單,它將 __不會__ 與策略參數進行比較,並且所有參數都將被視為未綁定。
- 關鍵字引數:
num_qvalue_nets (integer, optional) – 使用的 Q 值網路數量。 預設值為
2
。loss_function (str, optional) – 與值函數損失一起使用的損失函數。 預設值為 “smooth_l1”。
alpha_init (float, optional) – 初始熵乘數。 預設值為 1.0。
min_alpha (float, optional) – alpha 的最小值。 預設值為 None(無最小值)。
max_alpha (float, optional) – alpha 的最大值。 預設值為 None(無最大值)。
action_spec (TensorSpec, optional) – 行動張量規格。如果未提供,且目標熵為
"auto"
,則將從 actor 檢索。fixed_alpha (bool, optional) – 如果
True
,alpha 將固定為其初始值。否則,將優化 alpha 以匹配 'target_entropy' 值。預設值為False
。target_entropy (float 或 str, optional) – 隨機策略的目標熵。預設值為 "auto",其中目標熵計算為
-prod(n_actions)
。priority_key (str, optional) – [已棄用,請改用 .set_keys(priority_key=priority_key)] 要寫入優先權的 Tensordict 鍵(用於優先權重播緩衝區)。預設為
"td_error"
。separate_losses (bool, optional) – 如果
True
,策略和 critic 之間的共享參數將僅在策略損失上進行訓練。預設值為False
,也就是說,梯度會傳播到策略和 critic 損失的共享參數。reduction (str, optional) – 指定要應用於輸出的縮減方式:
"none"
|"mean"
|"sum"
。"none"
:不應用任何縮減,"mean"
:輸出的總和將除以輸出中的元素數量,"sum"
:輸出將被加總。預設值:"mean"
。
範例
>>> 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.crossq import CrossQLoss >>> 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) >>> class ValueClass(nn.Module): ... def __init__(self): ... super().__init__() ... self.linear = nn.Linear(n_obs + n_act, 1) ... def forward(self, obs, act): ... return self.linear(torch.cat([obs, act], -1)) >>> module = ValueClass() >>> qvalue = ValueOperator( ... module=module, ... in_keys=['observation', 'action']) >>> loss = CrossQLoss(actor, qvalue) >>> 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={ alpha: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), entropy: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_actor: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_alpha: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.float32, is_shared=False), loss_qvalue: 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 和 qvalue 網路的 in_keys。返回值是一個張量元組,順序如下:["loss_actor", "loss_qvalue", "loss_alpha", "alpha", "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 import CrossQLoss >>> _ = 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) >>> class ValueClass(nn.Module): ... def __init__(self): ... super().__init__() ... self.linear = nn.Linear(n_obs + n_act, 1) ... def forward(self, obs, act): ... return self.linear(torch.cat([obs, act], -1)) >>> module = ValueClass() >>> qvalue = ValueOperator( ... module=module, ... in_keys=['observation', 'action']) >>> loss = CrossQLoss(actor, qvalue) >>> batch = [2, ] >>> action = spec.rand(batch) >>> loss_actor, loss_qvalue, _, _, _ = loss( ... 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_observation=torch.zeros(*batch, n_obs), ... next_reward=torch.randn(*batch, 1)) >>> loss_actor.backward()
也可以使用
CrossQLoss.select_out_keys()
方法過濾輸出鍵。範例
>>> _ = loss.select_out_keys('loss_actor', 'loss_qvalue') >>> loss_actor, loss_qvalue = loss( ... 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_observation=torch.zeros(*batch, n_obs), ... next_reward=torch.randn(*batch, 1)) >>> loss_actor.backward()
- actor_loss(tensordict: TensorDictBase) Tuple[Tensor, Dict[str, Tensor]] [source]¶
計算 actor 損失。
actor 損失應在
qvalue_loss()
之後以及 ~.alpha_loss 之前計算,後者需要此方法傳回的 metadata 的 log_prob 欄位。- 參數:
tensordict (TensorDictBase) – 損失的輸入資料。檢查類別的 in_keys 以查看計算此值所需哪些欄位。
傳回:一個可微分的張量,帶有 alpha 損失以及一個元資料字典,其中包含採樣動作的分離 “log_prob”。
- alpha_loss(log_prob: Tensor) Tensor [source]¶
計算熵損失。
熵損失應最後計算。
- 參數:
log_prob (torch.Tensor) – 由
actor_loss()
計算並在 metadata 中傳回的對數機率。
傳回:具有熵損失的可微分張量。
- forward(tensordict: TensorDictBase = None) TensorDictBase [source]¶
前向方法。
連續計算
qvalue_loss()
、actor_loss()
和alpha_loss()
,並傳回一個 tensordict,其中包含這些值以及 “alpha” 值和 “entropy” 值(分離)。若要查看輸入 tensordict 中預期哪些鍵以及預期哪些鍵作為輸出,請檢查類別的 “in_keys” 和 “out_keys” 屬性。
- load_state_dict(state_dict: Mapping[str, Any], strict: bool = True, assign: bool = False)¶
將參數和緩衝區從
state_dict
複製到此模組及其子代中。如果
strict
為True
,則state_dict
的鍵必須與此模組的state_dict()
函數傳回的鍵完全匹配。警告
如果
assign
為True
,則必須在呼叫load_state_dict
之後建立最佳化器,除非get_swap_module_params_on_conversion()
為True
。- 參數:
state_dict (dict) – 包含參數和持久性緩衝區的字典。
strict (bool, optional) – 是否嚴格要求
state_dict
中的鍵與此模組的state_dict()
函數傳回的鍵匹配。預設值:True
assign (bool, optional) – 當
False
時,會保留目前模組中張量的屬性,而當True
時,會保留 state dict 中張量的屬性。 唯一的例外是requires_grad
欄位預設值: ``False`
- 傳回值:
- missing_keys 是一個字串列表,其中包含此模組預期的但遺失在提供的
state_dict
中的所有鍵。 此模組預期的但遺失在提供的
state_dict
中的所有鍵。
- missing_keys 是一個字串列表,其中包含此模組預期的但遺失在提供的
- unexpected_keys 是一個字串列表,其中包含此模組預期外的,但存在於提供的
state_dict
中的所有鍵。 此模組預期外的,但存在於提供的
state_dict
中的所有鍵。
- unexpected_keys 是一個字串列表,其中包含此模組預期外的,但存在於提供的
- 傳回類型:
具有
missing_keys
和unexpected_keys
欄位的NamedTuple
注意
如果參數或緩衝區註冊為
None
且其對應的鍵存在於state_dict
中,則load_state_dict()
將引發RuntimeError
。
- make_value_estimator(value_type: Optional[ValueEstimators] = None, **hyperparams)[原始碼]¶
值函數建構子。
如果需要非預設值函數,則必須使用此方法建立。
- 參數:
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)
- qvalue_loss(tensordict: TensorDictBase) Tuple[Tensor, Dict[str, Tensor]] [source]¶
計算 q-value 損失。
q-value 損失應該在
actor_loss()
之前計算。- 參數:
tensordict (TensorDictBase) – 損失的輸入資料。檢查類別的 in_keys 以查看計算此值所需哪些欄位。
- 回傳:一個可微分的 tensor,包含 qvalue 損失,以及一個包含以下資訊的中繼資料字典:
分離的 (detached) “td_error”,用於優先採樣。
- state_dict(*args, destination=None, prefix='', keep_vars=False)¶
傳回一個字典,其中包含對模組整個狀態的參考。
包含參數和持久性緩衝區(例如,滾動平均值)。鍵是對應的參數和緩衝區名稱。設定為
None
的參數和緩衝區不包含在內。注意
傳回的物件是淺複製。它包含對模組的參數和緩衝區的參考。
警告
目前
state_dict()
也接受位置引數,依序對應於destination
、prefix
和keep_vars
。但是,這種用法已被棄用,未來版本將強制使用關鍵字引數。警告
請避免使用引數
destination
,因為它並非為終端使用者設計。- 參數:
destination (dict, optional) – 如果提供,模組的狀態將更新到字典中,並傳回相同的物件。否則,將建立並傳回
OrderedDict
。預設值:None
。prefix (str, optional) – 添加到參數和緩衝區名稱的前綴,用於構成 state_dict 中的鍵。預設值:
''
。keep_vars (bool, optional) – 預設情況下,state dict 中傳回的
Tensor
會從 autograd 分離。如果設定為True
,則不會執行分離。預設值:False
。
- 傳回值:
一個字典,其中包含模組的整個狀態
- 傳回類型:
dict
範例
>>> # xdoctest: +SKIP("undefined vars") >>> module.state_dict().keys() ['bias', 'weight']
- property target_entropy_buffer¶
目標熵。
這個值可以透過建構函式中的 target_entropy kwarg 控制。