OrnsteinUhlenbeckProcessWrapper¶
- class torchrl.modules.tensordict_module.OrnsteinUhlenbeckProcessWrapper(*args, **kwargs)[source]¶
Ornstein-Uhlenbeck 探索策略包装器。
在“使用深度强化学习进行连续控制”中提出,https://arxiv.org/pdf/1509.02971.pdf。
OU 探索用于连续控制策略,并引入自相关的探索噪声。这使得可以进行一种“结构化”的探索。
噪声方程
\[noise_t = noise_{t-1} + \theta * (mu - noise_{t-1}) * dt + \sigma_t * \sqrt{dt} * W\]Sigma 方程
\[\sigma_t = max(\sigma^{min, (-(\sigma_{t-1} - \sigma^{min}) / (n^{\text{steps annealing}}) * n^{\text{steps}} + \sigma))\]为了跟踪样本到样本的步骤和噪声,将在输入/输出张量字典中写入
"ou_prev_noise{id}"
和"ou_steps{id}"
键。预计张量字典将在重置时清零,表示正在收集新的轨迹。否则,如果将相同的张量字典用于连续轨迹,则步数将在整个 rollout 中不断增加。请注意,收集器类会在重置时负责清零张量字典。注意
一旦环境被包装到
OrnsteinUhlenbeckProcessWrapper
中,务必在训练循环中包含对step()
的调用以更新探索因子。由于很难捕获此遗漏,因此如果省略,将不会发出警告或引发异常!- 参数:
policy (TensorDictModule) – 策略
- 关键字参数:
eps_init (标量) – 初始 epsilon 值,决定要添加的噪声量。默认值:1.0
eps_end (标量) – 最终 epsilon 值,决定要添加的噪声量。默认值:0.1
annealing_num_steps (int) – epsilon 达到 eps_end 值所需步数。默认值:1000
theta (标量) – 噪声方程中的 theta 因子。默认值:0.15
mu (标量) – OU 平均值(噪声方程中的 mu)。默认值:0.0
sigma (标量) – sigma 方程中的 sigma 值。默认值:0.2
dt (标量) – 噪声方程中的 dt。默认值:0.01
x0 (张量, ndarray, 可选) – 过程的初始值。默认值:0.0
sigma_min (数字, 可选) – sigma 方程中的 sigma_min。默认值:None
n_steps_annealing (int) – sigma 退火的步数。默认值:1000
action_key (嵌套键, 可选) – 要修改的动作的键。默认值:“action”
is_init_key (嵌套键, 可选) – 用于查找用于重置噪声步数的 is_init 标志的键。默认值:“is_init”
spec (TensorSpec, 可选) – 如果提供,则采样的动作将在探索后投影到有效的动作空间中。如果没有提供,则探索包装器将尝试从策略中恢复它。
safe (bool) – 如果为
True
,则给定动作规范超出范围的动作将在给定TensorSpec.project
启发式的情况下投影到空间中。默认值:True
示例
>>> import torch >>> from tensordict import TensorDict >>> from torchrl.data import BoundedTensorSpec >>> from torchrl.modules import OrnsteinUhlenbeckProcessWrapper, Actor >>> torch.manual_seed(0) >>> spec = BoundedTensorSpec(-1, 1, torch.Size([4])) >>> module = torch.nn.Linear(4, 4, bias=False) >>> policy = Actor(module=module, spec=spec) >>> explorative_policy = OrnsteinUhlenbeckProcessWrapper(policy) >>> td = TensorDict({"observation": torch.zeros(10, 4)}, batch_size=[10]) >>> print(explorative_policy(td)) TensorDict( fields={ _ou_prev_noise: Tensor(torch.Size([10, 4]), dtype=torch.float32), _ou_steps: Tensor(torch.Size([10, 1]), dtype=torch.int64), action: Tensor(torch.Size([10, 4]), dtype=torch.float32), observation: Tensor(torch.Size([10, 4]), dtype=torch.float32)}, batch_size=torch.Size([10]), device=None, is_shared=False)