ProbabilisticActor¶
- class torchrl.modules.tensordict_module.ProbabilisticActor(*args, **kwargs)[原始碼]¶
RL 中機率性 Actor 的通用類別。
Actor 類別帶有 out_keys([“action”])的預設值,並且如果提供了 spec 但不是作為 Composite 物件,它將自動轉換為
spec = Composite(action=spec)
- 參數:
module (nn.Module) – 用於將輸入映射到輸出參數空間的
torch.nn.Module
。in_keys (str 或 str 的可迭代物件 或 dict) – 將從輸入 TensorDict 中讀取並用於建構分佈的鍵。重要的是,如果它是一個字串的可迭代物件或一個字串,這些鍵必須與感興趣的分佈類別所使用的關鍵字相符,例如 Normal 分佈的
"loc"
和"scale"
等。如果 in_keys 是一個字典,則鍵是分佈的鍵,而值是 tensordict 中將與相應分佈鍵相匹配的鍵。out_keys (str 或 str 的可迭代物件) – 將寫入採樣值的鍵。重要的是,如果在輸入 TensorDict 中找到這些鍵,則將跳過採樣步驟。
spec (TensorSpec, optional) – 僅限關鍵字的參數,包含輸出張量的規格。如果模組輸出多個輸出張量,則 spec 表徵第一個輸出張量的空間。
safe (bool) – 僅限關鍵字參數。如果
True
,則會根據輸入規格檢查輸出的值。由於探索策略或數值下溢/溢位問題,可能會發生超出範圍的取樣。如果此值超出範圍,它將使用TensorSpec.project
方法投影回所需的空間。預設值為False
。default_interaction_type (str, optional) –
僅限關鍵字參數。用於檢索輸出值的預設方法。 應為以下其中之一:'InteractionType.MODE'、'InteractionType.DETERMINISTIC'、'InteractionType.MEDIAN'、'InteractionType.MEAN' 或 'InteractionType.RANDOM' (在這種情況下,該值是從分佈中隨機取樣)。 TorchRL 的
ExplorationType
類別是InteractionType
的代理。預設值為 'InteractionType.DETERMINISTIC'。注意
當抽取樣本時,
ProbabilisticActor
實例將首先尋找由interaction_type()
全域函數指示的互動模式。如果此函數傳回 None (其預設值),則將使用 ProbabilisticTDModule 實例的 default_interaction_type。請注意,DataCollectorBase
實例預設將使用 set_interaction_type 到tensordict.nn.InteractionType.RANDOM
。distribution_class (Type, optional) –
僅限關鍵字參數。 用於取樣的
torch.distributions.Distribution
類別。預設值為tensordict.nn.distributions.Delta
。注意
如果
distribution_class
的類型為CompositeDistribution
,則將從該分佈的distribution_map
/name_map
關鍵字參數推斷鍵。 如果此分佈與另一個建構函式(例如,partial 或 lambda 函數)一起使用,則需要明確提供 out_keys。另請注意,動作將 __不會__ 以"action"
鍵作為前綴,請參閱下面的範例,了解如何使用ProbabilisticActor
實現此目的。distribution_kwargs (dict, optional) – 僅限關鍵字參數。要傳遞給分佈的關鍵字參數對。
return_log_prob (bool, optional) – 僅限關鍵字參數。 如果
True
,則分佈樣本的對數機率將使用鍵 ‘sample_log_prob’ 寫入 tensordict 中。預設值為False
。cache_dist (bool, optional) – 僅限關鍵字參數。實驗性:如果
True
,則分佈的參數(即模組的輸出)將與樣本一起寫入 tensordict 中。 這些參數可用於稍後重新計算原始分佈(例如,計算用於對動作進行取樣的分佈與 PPO 中更新的分佈之間的差異)。預設值為False
。n_empirical_estimate (int, optional) – 僅限關鍵字參數。在無法使用經驗平均值時,用於計算經驗平均值的樣本數。 預設值為 1000。
範例
>>> import torch >>> from tensordict import TensorDict >>> from tensordict.nn import TensorDictModule >>> from torchrl.data import Bounded >>> from torchrl.modules import ProbabilisticActor, NormalParamExtractor, TanhNormal >>> td = TensorDict({"observation": torch.randn(3, 4)}, [3,]) >>> action_spec = Bounded(shape=torch.Size([4]), ... low=-1, high=1) >>> module = nn.Sequential(torch.nn.Linear(4, 8), NormalParamExtractor()) >>> tensordict_module = TensorDictModule(module, in_keys=["observation"], out_keys=["loc", "scale"]) >>> td_module = ProbabilisticActor( ... module=tensordict_module, ... spec=action_spec, ... in_keys=["loc", "scale"], ... distribution_class=TanhNormal, ... ) >>> td = td_module(td) >>> td TensorDict( fields={ action: Tensor(shape=torch.Size([3, 4]), device=cpu, dtype=torch.float32, is_shared=False), loc: Tensor(shape=torch.Size([3, 4]), device=cpu, dtype=torch.float32, is_shared=False), observation: Tensor(shape=torch.Size([3, 4]), device=cpu, dtype=torch.float32, is_shared=False), scale: Tensor(shape=torch.Size([3, 4]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([3]), device=None, is_shared=False)
機率性 Actor 也透過
tensordict.nn.CompositeDistribution
類別支援複合動作。此分佈採用 tensordict 作為輸入(通常是 “params”)並將其作為一個整體讀取:此 tensordict 的內容是複合分佈中包含的分佈的輸入。範例
>>> from tensordict import TensorDict >>> from tensordict.nn import CompositeDistribution, TensorDictModule >>> from torchrl.modules import ProbabilisticActor >>> from torch import nn, distributions as d >>> import torch >>> >>> class Module(nn.Module): ... def forward(self, x): ... return x[..., :3], x[..., 3:6], x[..., 6:] >>> module = TensorDictModule(Module(), ... in_keys=["x"], ... out_keys=[("params", "normal", "loc"), ... ("params", "normal", "scale"), ... ("params", "categ", "logits")]) >>> actor = ProbabilisticActor(module, ... in_keys=["params"], ... distribution_class=CompositeDistribution, ... distribution_kwargs={"distribution_map": { ... "normal": d.Normal, "categ": d.Categorical}} ... ) >>> data = TensorDict({"x": torch.rand(10)}, []) >>> actor(data) TensorDict( fields={ categ: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.int64, is_shared=False), normal: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False), params: TensorDict( fields={ categ: TensorDict( fields={ logits: Tensor(shape=torch.Size([4]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False), normal: TensorDict( fields={ loc: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False), scale: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False), x: Tensor(shape=torch.Size([10]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False)
可以使用以下範例程式碼來實現將機率性 Actor 與複合分佈一起使用
範例
>>> import torch >>> from tensordict import TensorDict >>> from tensordict.nn import CompositeDistribution >>> from tensordict.nn import TensorDictModule >>> from torch import distributions as d >>> from torch import nn >>> >>> from torchrl.modules import ProbabilisticActor >>> >>> >>> class Module(nn.Module): ... def forward(self, x): ... return x[..., :3], x[..., 3:6], x[..., 6:] ... >>> >>> module = TensorDictModule(Module(), ... in_keys=["x"], ... out_keys=[ ... ("params", "normal", "loc"), ("params", "normal", "scale"), ("params", "categ", "logits") ... ]) >>> actor = ProbabilisticActor(module, ... in_keys=["params"], ... distribution_class=CompositeDistribution, ... distribution_kwargs={"distribution_map": {"normal": d.Normal, "categ": d.Categorical}, ... "name_map": {"normal": ("action", "normal"), ... "categ": ("action", "categ")}} ... ) >>> print(actor.out_keys) [('params', 'normal', 'loc'), ('params', 'normal', 'scale'), ('params', 'categ', 'logits'), ('action', 'normal'), ('action', 'categ')] >>> >>> data = TensorDict({"x": torch.rand(10)}, []) >>> module(data) >>> print(actor(data)) TensorDict( fields={ action: TensorDict( fields={ categ: Tensor(shape=torch.Size([]), device=cpu, dtype=torch.int64, is_shared=False), normal: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False), params: TensorDict( fields={ categ: TensorDict( fields={ logits: Tensor(shape=torch.Size([4]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False), normal: TensorDict( fields={ loc: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False), scale: Tensor(shape=torch.Size([3]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False), x: Tensor(shape=torch.Size([10]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([]), device=None, is_shared=False)