(9-3)离线强化学习:基于不确定性的方法

9.3  基于不确定性的方法

基于不确定性的方法是离线强化学习中的一种重要策略优化框架,旨在通过量化或利用策略在不同状态-动作对上的不确定性来优化学习过程。例如,集成学习方法(如REM,Random Ensemble Mixture)通过构建多个Q网络并利用它们的输出差异来量化不确定性,选择具有最低不确定性(即最高置信度)的动作。

9.3.1  常用的基于不确定性的方法介绍

基于不确定性的方法的核心思想是识别出那些模型或策略不够确定的区域,从而避免对未见或数据稀疏的状态-动作对进行过度自信的估计。以下是几种常用的基于不确定性的方法。

1. REM(Random Ensemble Mixture

REM是一种基于集成学习的方法,通过构建多个Q网络来量化不确定性。每个Q网络独立训练,使用不同的初始条件或训练数据的子集。通过聚合这些网络的预测结果,REM可以计算出状态-动作对的均值和方差,从而量化不确定性。这种方法特别适用于需要高鲁棒性的任务,如医学图像诊断或自主导航,但其缺点是训练和存储多个模型的计算成本较高。

2. BRL(Pessimistic Bootstrapping

PBRL是一种悲观引导的策略优化方法,通过维护多个独立更新的Q函数来量化不确定性。不确定性通过这些Q函数的标准差来衡量,即:

其中 K 是Q函数的数量。PBRL在Q值更新中引入悲观惩罚,通过降低OOD(Out-of-Distribution)动作的Q值来避免过度乐观的策略更新。这种方法在离线强化学习中表现出色,能够有效缓解分布偏移问题。

3. EDE(Ensemble Distribution Estimation

EDE是一种基于分布鲁棒性优化的框架,通过集成网络来建模认知不确定性。EDE创建了多个具有不同初始参数的网络头,每个网络头输出一个Q值,从而形成一个Q值分布。通过优化这个分布,EDE能够量化并分离随机不确定性和认知不确定性,从而提高策略的鲁棒性。这种方法特别适用于需要在线风险感知调整的场景,能够有效处理不确定性。

总之,这些基于不确定性的方法通过量化和利用策略在不同“状态-动作”对上的不确定性,优化学习过程,提高策略的鲁棒性和泛化能力。

9.3.2  综合实战:比较三种基于不确定性方法的性能

请看下面的实例,展示了在Lunar Lander环境中应用和比较三种基于不确定性的强化学习方法(REM、BRL和EDE)的过程。本实例的功能比较强大,涵盖了从环境设置、神经网络模型定义,到经验回放缓冲区的实现,再到三种方法的训练、评估和结果可视化。通过训练和评估这些方法,展示了它们在处理数据稀疏性和分布偏移问题时的表现,并通过可视化不确定性,揭示了这些方法在决策过程中的保守性和鲁棒性。

实例9-2:Lunar Lander环境中比较三种基于不确定性方法的性能(源码路径:codes\9\Bu.py

实例文件Bu.py的具体实现流程如下所示。

(1)定义函数 gym_api_compatibility,功能是检查Gym环境的API版本,并返回与之兼容的 reset 和 step 函数。通过尝试调用新版本API的 reset(seed=42) 方法来判断版本,如果失败则使用旧版本API的 reset 和 step 方法。这确保了代码在不同版本的Gym库中都能正常运行。

# 检查Gym API版本
def gym_api_compatibility(env):
    try:
        env.reset(seed=42)

        def reset_fn(env):
            obs, _ = env.reset(seed=int(time.time() % 1000))
            return obs

        def step_fn(env, action):
            obs, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            return obs, reward, done

        return reset_fn, step_fn
    except:
        def reset_fn(env):
            return env.reset()

        def step_fn(env, action):
            obs, reward, done, _ = env.step(action)
            return obs, reward, done

        return reset_fn, step_fn

(2)下面代码块的功能是创建Lunar Lander环境并获取其状态维度和动作维度。同时,调用 函数gym_api_compatibility获取与当前Gym版本兼容的 reset 和 step 函数,以便在后续的训练和评估中使用。

# 创建LunarLander环境
env = gym.make('LunarLander-v2')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.n
reset_env, step_env = gym_api_compatibility(env)

(3)定义类 QNetwork,功能是实现一个用于Q值估计的神经网络模型。该网络由多个全连接层组成,输入是状态,输出是每个动作的Q值。通过ReLU激活函数和线性层实现非线性映射,为强化学习算法提供价值估计。

# 神经网络模型 - 用于Q值估计
class QNetwork(nn.Module):
    def __init__(self, state_dim, action_dim, hidden_dim=128):
        super(QNetwork, self).__init__()
        self.layers = nn.Sequential(
            nn.Linear(state_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, action_dim)
        )

    def forward(self, state):
        return self.layers(state)

(4)定义类 ReplayBuffer,功能是实现一个经验回放缓冲区,用于存储和采样智能体与环境交互的经验。缓冲区具有固定的容量,当达到容量时,新的经验会覆盖旧的经验。通过随机采样批量数据,为训练过程提供多样化的数据支持。

# 经验回放缓冲区
class ReplayBuffer:
    def __init__(self, capacity=100000):
        self.capacity = capacity
        self.buffer = []
        self.position = 0

    def add(self, state, action, reward, next_state, done):
        if len(self.buffer) < self.capacity:
            self.buffer.append(None)
        self.buffer[self.position] = (state, action, reward, next_state, done)
        self.position = (self.position + 1) % self.capacity

    def sample(self, batch_size):
        batch = random.sample(self.buffer, batch_size)
        state, action, reward, next_state, done = map(np.stack, zip(*batch))
        return state, action, reward, next_state, done

    def __len__(self):
        return len(self.buffer)

(5)定义类 REM,功能是实现基于随机集成混合(Random Ensemble Mixture)的强化学习方法。该方法通过维护多个Q网络来量化不确定性,并在动作选择时随机选择一个网络进行决策。通过训练多个网络并软更新目标网络,REM能够提高策略的鲁棒性和泛化能力。

class REM:
    def __init__(self, state_dim, action_dim, ensemble_size=5, lr=1e-3, gamma=0.99):
        self.ensemble_size = ensemble_size
        self.gamma = gamma

        # 创建多个Q网络
        self.q_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.target_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.optimizers = [optim.Adam(q.parameters(), lr=lr) for q in self.q_networks]

        # 初始化目标网络
        for i in range(ensemble_size):
            self.target_networks[i].load_state_dict(self.q_networks[i].state_dict())
            self.target_networks[i].eval()

        self.replay_buffer = ReplayBuffer()

    def select_action(self, state, epsilon=0.1):
        if random.random() < epsilon:
            return random.randrange(action_dim)

        state_tensor = torch.FloatTensor(state).unsqueeze(0)

        # 随机选择一个网络进行动作选择
        idx = random.randint(0, self.ensemble_size - 1)
        with torch.no_grad():
            q_values = self.q_networks[idx](state_tensor)
        return q_values.argmax().item()

    def train(self, batch_size=64, target_update=100):
        if len(self.replay_buffer) < batch_size:
            return

        state, action, reward, next_state, done = self.replay_buffer.sample(batch_size)

        state_tensor = torch.FloatTensor(state)
        action_tensor = torch.LongTensor(action)
        reward_tensor = torch.FloatTensor(reward)
        next_state_tensor = torch.FloatTensor(next_state)
        done_tensor = torch.FloatTensor(done)

        # 训练每个网络
        for i in range(self.ensemble_size):
            # 计算目标Q值
            with torch.no_grad():
                next_q_values = self.target_networks[i](next_state_tensor)
                target_q_values = reward_tensor + (1 - done_tensor) * self.gamma * next_q_values.max(1)[0]

            # 当前Q值
            current_q_values = self.q_networks[i](state_tensor)
            action_q_values = current_q_values.gather(1, action_tensor.unsqueeze(1)).squeeze(1)

            # 计算损失
            loss = nn.MSELoss()(action_q_values, target_q_values)

            # 优化
            self.optimizers[i].zero_grad()
            loss.backward()
            self.optimizers[i].step()

        # 软更新目标网络
        for i in range(self.ensemble_size):
            for target_param, param in zip(self.target_networks[i].parameters(), self.q_networks[i].parameters()):
                target_param.data.copy_(0.005 * param.data + (0.995 * target_param.data))

(6)定义类 BRL,功能是实现基于悲观引导(Pessimistic Bootstrapping)的强化学习方法。该方法通过维护多个Q网络来量化不确定性,并在动作选择时考虑悲观惩罚,即选择Q值减去不确定性的最大值对应的动作。这种方法能够有效避免过度乐观的策略更新,提高策略的稳定性。

class BRL:
    def __init__(self, state_dim, action_dim, ensemble_size=5, lr=1e-3, gamma=0.99, beta=0.5):
        self.ensemble_size = ensemble_size
        self.gamma = gamma
        self.beta = beta  # 悲观系数

        # 创建多个Q网络
        self.q_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.target_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.optimizers = [optim.Adam(q.parameters(), lr=lr) for q in self.q_networks]

        # 初始化目标网络
        for i in range(ensemble_size):
            self.target_networks[i].load_state_dict(self.q_networks[i].state_dict())
            self.target_networks[i].eval()

        self.replay_buffer = ReplayBuffer()

    def select_action(self, state, epsilon=0.1):
        if random.random() < epsilon:
            return random.randrange(action_dim)

        state_tensor = torch.FloatTensor(state).unsqueeze(0)

        # 计算所有网络的Q值
        all_q_values = []
        for i in range(self.ensemble_size):
            with torch.no_grad():
                q_values = self.q_networks[i](state_tensor)
                all_q_values.append(q_values)

        # 计算平均Q值和不确定性
        all_q_values = torch.stack(all_q_values, dim=0)
        mean_q = all_q_values.mean(0)
        std_q = all_q_values.std(0)

        # 悲观主义:选择Q值减去不确定性的最大值对应的动作
        pessimistic_q = mean_q - self.beta * std_q
        return pessimistic_q.argmax().item()

    def train(self, batch_size=64, target_update=100):
        if len(self.replay_buffer) < batch_size:
            return

        state, action, reward, next_state, done = self.replay_buffer.sample(batch_size)

        state_tensor = torch.FloatTensor(state)
        action_tensor = torch.LongTensor(action)
        reward_tensor = torch.FloatTensor(reward)
        next_state_tensor = torch.FloatTensor(next_state)
        done_tensor = torch.FloatTensor(done)

        # 训练每个网络
        for i in range(self.ensemble_size):
            # 计算目标Q值
            with torch.no_grad():
                next_q_values = self.target_networks[i](next_state_tensor)
                target_q_values = reward_tensor + (1 - done_tensor) * self.gamma * next_q_values.max(1)[0]

            # 当前Q值
            current_q_values = self.q_networks[i](state_tensor)
            action_q_values = current_q_values.gather(1, action_tensor.unsqueeze(1)).squeeze(1)

            # 计算损失
            loss = nn.MSELoss()(action_q_values, target_q_values)

            # 优化
            self.optimizers[i].zero_grad()
            loss.backward()
            self.optimizers[i].step()

        # 软更新目标网络
        for i in range(self.ensemble_size):
            for target_param, param in zip(self.target_networks[i].parameters(), self.q_networks[i].parameters()):
                target_param.data.copy_(0.005 * param.data + (0.995 * target_param.data))

(7)定义类 EDE,功能是实现基于集成分布估计(Ensemble Distribution Estimation)的强化学习方法。该方法通过维护多个Q网络来量化不确定性,并在动作选择时考虑不确定性奖励,即选择Q值加上不确定性的最大值对应的动作。这种方法能够有效平衡探索和利用,提高策略的性能。

class EDE:
    def __init__(self, state_dim, action_dim, ensemble_size=5, lr=1e-3, gamma=0.99, kappa=1.0):
        self.ensemble_size = ensemble_size
        self.gamma = gamma
        self.kappa = kappa  # 不确定性惩罚系数

        # 创建多个Q网络
        self.q_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.target_networks = [QNetwork(state_dim, action_dim) for _ in range(ensemble_size)]
        self.optimizers = [optim.Adam(q.parameters(), lr=lr) for q in self.q_networks]

        # 初始化目标网络
        for i in range(ensemble_size):
            self.target_networks[i].load_state_dict(self.q_networks[i].state_dict())
            self.target_networks[i].eval()

        self.replay_buffer = ReplayBuffer()

    def select_action(self, state, epsilon=0.1):
        if random.random() < epsilon:
            return random.randrange(action_dim)

        state_tensor = torch.FloatTensor(state).unsqueeze(0)

        # 计算所有网络的Q值
        all_q_values = []
        for i in range(self.ensemble_size):
            with torch.no_grad():
                q_values = self.q_networks[i](state_tensor)
                all_q_values.append(q_values)

        # 计算平均Q值和不确定性
        all_q_values = torch.stack(all_q_values, dim=0)
        mean_q = all_q_values.mean(0)
        std_q = all_q_values.std(0)

        # 选择Q值加上不确定性奖励的最大值对应的动作
        exploration_q = mean_q + self.kappa * std_q
        return exploration_q.argmax().item()

    def train(self, batch_size=64, target_update=100):
        if len(self.replay_buffer) < batch_size:
            return

        state, action, reward, next_state, done = self.replay_buffer.sample(batch_size)

        state_tensor = torch.FloatTensor(state)
        action_tensor = torch.LongTensor(action)
        reward_tensor = torch.FloatTensor(reward)
        next_state_tensor = torch.FloatTensor(next_state)
        done_tensor = torch.FloatTensor(done)

        # 训练每个网络
        for i in range(self.ensemble_size):
            # 计算目标Q值
            with torch.no_grad():
                next_q_values = self.target_networks[i](next_state_tensor)
                target_q_values = reward_tensor + (1 - done_tensor) * self.gamma * next_q_values.max(1)[0]

            # 当前Q值
            current_q_values = self.q_networks[i](state_tensor)
            action_q_values = current_q_values.gather(1, action_tensor.unsqueeze(1)).squeeze(1)

            # 计算损失
            loss = nn.MSELoss()(action_q_values, target_q_values)

            # 优化
            self.optimizers[i].zero_grad()
            loss.backward()
            self.optimizers[i].step()

        # 软更新目标网络
        for i in range(self.ensemble_size):
            for target_param, param in zip(self.target_networks[i].parameters(), self.q_networks[i].parameters()):
                target_param.data.copy_(0.005 * param.data + (0.995 * target_param.data))

(8)定义函数 train_agent,功能是训练强化学习代理。该函数通过与环境交互,收集经验并存储到经验回放缓冲区中。然后,通过采样批量数据并更新Q网络,训练代理以优化策略。同时,通过衰减探索率,逐渐减少随机探索的频率,提高策略的性能。

# 训练函数
def train_agent(agent, env, num_episodes=1000, max_steps=1000, epsilon_start=1.0, epsilon_end=0.1, epsilon_decay=0.995):
    rewards_history = []
    epsilon = epsilon_start

    for episode in tqdm(range(num_episodes), desc="Training"):
        state = reset_env(env)
        episode_reward = 0

        for step in range(max_steps):
            # 选择动作
            action = agent.select_action(state, epsilon)

            # 执行动作
            next_state, reward, done = step_env(env, action)

            # 存储经验
            agent.replay_buffer.add(state, action, reward, next_state, done)

            # 训练代理
            agent.train()

            state = next_state
            episode_reward += reward

            if done:
                break

        # 衰减探索率
        epsilon = max(epsilon_end, epsilon * epsilon_decay)

        rewards_history.append(episode_reward)

        # 打印进度
        if (episode + 1) % 100 == 0:
            avg_reward = np.mean(rewards_history[-100:])
            print(f"Episode {episode + 1}, Average Reward: {avg_reward:.2f}, Epsilon: {epsilon:.3f}")

    return rewards_history

(9)定义函数 evaluate_agent,功能是评估强化学习代理的性能。该函数通过在多个测试回合中运行代理,计算其平均奖励。同时,可以选择是否渲染环境,以便直观观察代理的行为。最终,返回代理的平均奖励值,用于评估其性能。

# 评估函数
def evaluate_agent(agent, env, num_episodes=10, render=False):
    total_rewards = []

    for episode in range(num_episodes):
        state = reset_env(env)
        episode_reward = 0
        done = False

        while not done:
            if render:
                env.render()

            # 确定性策略评估
            action = agent.select_action(state, epsilon=0.0)
            next_state, reward, done = step_env(env, action)

            state = next_state
            episode_reward += reward

        total_rewards.append(episode_reward)
        print(f"Evaluation Episode {episode + 1}, Reward: {episode_reward:.2f}")

    avg_reward = np.mean(total_rewards)
    print(f"Average Evaluation Reward: {avg_reward:.2f}")
    return avg_reward

(10)定义函数 visualize_uncertainty,功能是可视化代理在特定环境中的不确定性变化。该函数通过计算多个Q网络的Q值标准差来量化不确定性,并在每个时间步记录不确定性值。最终,通过绘制不确定性随时间的变化曲线,直观展示代理在不同状态下的不确定性变化情况。

# 可视化不确定性
def visualize_uncertainty(agent, env, num_episodes=5):
    for episode in range(num_episodes):
        state = reset_env(env)
        done = False
        uncertainty_history = []

        while not done:
            state_tensor = torch.FloatTensor(state).unsqueeze(0)

            # 计算所有网络的Q值
            all_q_values = []
            for i in range(agent.ensemble_size):
                with torch.no_grad():
                    q_values = agent.q_networks[i](state_tensor)
                    all_q_values.append(q_values)

            # 计算不确定性
            all_q_values = torch.stack(all_q_values, dim=0)
            std_q = all_q_values.std(0).mean().item()
            uncertainty_history.append(std_q)

            # 选择动作
            action = agent.select_action(state, epsilon=0.0)
            state, _, done = step_env(env, action)

        # 绘制不确定性变化
        plt.figure(figsize=(10, 6))
        plt.plot(uncertainty_history)
        plt.title(f"Episode {episode + 1} Uncertainty Change")
        plt.xlabel("Step")
        plt.ylabel("Q-value Standard Deviation (Uncertainty)")
        plt.grid(True)
        plt.show()

(11)定义主函数 main,功能是执行整个实验流程。首先,分别训练REM、BRL和EDE三种基于不确定性的强化学习代理。然后,通过绘制学习曲线和计算移动平均值,比较不同方法的学习效果。接着,评估各代理的性能,并通过柱状图对比其最终性能。最后,可视化BRL代理的不确定性变化,展示其在决策过程中的保守性和鲁棒性。

# 主函数
def main():
    # 训练REM代理
    print("Training REM agent...")
    rem_agent = REM(state_dim, action_dim)
    rem_rewards = train_agent(rem_agent, env, num_episodes=500)

    # 训练BRL代理
    print("\nTraining BRL agent...")
    brl_agent = BRL(state_dim, action_dim)
    brl_rewards = train_agent(brl_agent, env, num_episodes=500)

    # 训练EDE代理
    print("\nTraining EDE agent...")
    ede_agent = EDE(state_dim, action_dim)
    ede_rewards = train_agent(ede_agent, env, num_episodes=500)

    # 可视化学习曲线
    plt.figure(figsize=(14, 8))
    plt.plot(rem_rewards, label='REM (Random Ensemble Mixture)', alpha=0.7)
    plt.plot(brl_rewards, label='BRL (Pessimistic Bootstrapping)', alpha=0.7)
    plt.plot(ede_rewards, label='EDE (Ensemble Distribution Estimation)', alpha=0.7)

    # 计算移动平均
    rem_smooth = np.convolve(rem_rewards, np.ones(20) / 20, mode='valid')
    brl_smooth = np.convolve(brl_rewards, np.ones(20) / 20, mode='valid')
    ede_smooth = np.convolve(ede_rewards, np.ones(20) / 20, mode='valid')

    plt.plot(range(19, len(rem_rewards)), rem_smooth, label='REM Moving Average', linewidth=2)
    plt.plot(range(19, len(brl_rewards)), brl_smooth, label='BRL Moving Average', linewidth=2)
    plt.plot(range(19, len(ede_rewards)), ede_smooth, label='EDE Moving Average', linewidth=2)

    plt.title('Comparison of Uncertainty-Based RL Methods (Lunar Lander)', fontsize=16)
    plt.xlabel('Training Episodes', fontsize=14)
    plt.ylabel('Reward', fontsize=14)
    plt.legend(fontsize=12)
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.show()

    # 评估各代理
    print("\nEvaluating REM agent...")
    rem_avg_reward = evaluate_agent(rem_agent, env, num_episodes=10)

    print("\nEvaluating BRL agent...")
    brl_avg_reward = evaluate_agent(brl_agent, env, num_episodes=10)

    print("\nEvaluating EDE agent...")
    ede_avg_reward = evaluate_agent(ede_agent, env, num_episodes=10)

    # 可视化最终性能对比
    plt.figure(figsize=(10, 6))
    methods = ['REM', 'BRL', 'EDE']
    rewards = [rem_avg_reward, brl_avg_reward, ede_avg_reward]

    plt.bar(methods, rewards, color=['#1f77b4', '#ff7f0e', '#2ca02c'])
    plt.title('Average Evaluation Rewards Comparison', fontsize=16)
    plt.ylabel('Average Reward', fontsize=14)
    plt.ylim(-500, 300)  # Lunar Lander reward range is typically between -500 and 300
    plt.grid(True, alpha=0.3)

    # Display values on the bar chart
    for i, v in enumerate(rewards):
        plt.text(i, v + 10, f'{v:.2f}', ha='center', fontsize=12)

    plt.tight_layout()
    plt.show()

    # 可视化不确定性
    print("\nVisualizing BRL agent uncertainty...")
    visualize_uncertainty(brl_agent, env, num_episodes=3)


if __name__ == "__main__":
    main()

执行本实例后,会绘制如下所示的可视化图。

  1. 学习曲线图:包含REM、BRL和EDE的奖励变化曲线及其移动平均值,如图9-1所示。
  2. 最终性能对比图:通过一个柱状图比较三种方法的平均奖励值,如图9-2所示。
  3. 不确定性变化图:绘制3张图,每张图展示BRL代理在一个回合中的不确定性变化。如图9-3所示。

图9-1  学习曲线图

图9-2  最终性能对比图

图9-3  不确定性变化图

在我电脑中执行后会打印输出下面的结果。

Training REM agent...
Training:  20%|██        | 100/500 [01:08<05:32,  1.20it/s]Episode 100, Average Reward: -140.12, Epsilon: 0.606
Training:  40%|████      | 200/500 [04:18<22:03,  4.41s/it]Episode 200, Average Reward: -54.12, Epsilon: 0.367
Training:  60%|██████    | 300/500 [14:13<19:19,  5.80s/it]Episode 300, Average Reward: 15.46, Epsilon: 0.222
Training:  80%|████████  | 400/500 [28:42<06:58,  4.19s/it]Episode 400, Average Reward: 92.68, Epsilon: 0.135
Training: 100%|██████████| 500/500 [39:10<00:00,  4.70s/it]
Episode 500, Average Reward: 148.04, Epsilon: 0.100

Training BRL agent...
Training:  20%|██        | 100/500 [01:43<05:18,  1.26it/s]Episode 100, Average Reward: -121.95, Epsilon: 0.606
Training:  40%|████      | 200/500 [05:29<29:48,  5.96s/it]Episode 200, Average Reward: -83.11, Epsilon: 0.367
Training:  60%|██████    | 300/500 [16:37<15:57,  4.79s/it]Episode 300, Average Reward: 8.66, Epsilon: 0.222
Training:  80%|████████  | 400/500 [36:17<09:53,  5.94s/it]Episode 400, Average Reward: 200.68, Epsilon: 0.135
Training: 100%|██████████| 500/500 [41:02<00:00,  4.92s/it]
Episode 500, Average Reward: 205.58, Epsilon: 0.100

Training EDE agent...
Training:  20%|██        | 100/500 [01:08<04:09,  1.60it/s]Episode 100, Average Reward: -123.50, Epsilon: 0.606
Training:  40%|████      | 200/500 [05:33<50:05, 10.02s/it]  Episode 200, Average Reward: -65.16, Epsilon: 0.367
Training:  60%|██████    | 300/500 [25:17<26:33,  7.97s/it]Episode 300, Average Reward: 10.51, Epsilon: 0.222
Training:  80%|████████  | 400/500 [34:29<05:05,  3.06s/it]Episode 400, Average Reward: 122.06, Epsilon: 0.135
Training: 100%|██████████| 500/500 [41:13<00:00,  4.95s/it]
Episode 500, Average Reward: 216.28, Epsilon: 0.100

Evaluating REM agent...
Evaluation Episode 1, Reward: 110.51
Evaluation Episode 2, Reward: 95.85
Evaluation Episode 3, Reward: -196.51
Evaluation Episode 4, Reward: 117.46
Evaluation Episode 5, Reward: -314.25
Evaluation Episode 6, Reward: -8.29
Evaluation Episode 7, Reward: -235.01
Evaluation Episode 8, Reward: -194.48
Evaluation Episode 9, Reward: -290.49
Evaluation Episode 10, Reward: -286.87
Average Evaluation Reward: -120.21

Evaluating BRL agent...
Evaluation Episode 1, Reward: -72.41
Evaluation Episode 2, Reward: -72.41
Evaluation Episode 3, Reward: -72.41
Evaluation Episode 4, Reward: -72.41
Evaluation Episode 5, Reward: -72.41
Evaluation Episode 6, Reward: -72.41
Evaluation Episode 7, Reward: 193.32
Evaluation Episode 8, Reward: 193.32
Evaluation Episode 9, Reward: -43.43
Evaluation Episode 10, Reward: 265.86
Average Evaluation Reward: 17.46

Evaluating EDE agent...
Evaluation Episode 1, Reward: 268.62
Evaluation Episode 2, Reward: 268.62
Evaluation Episode 3, Reward: 238.02
Evaluation Episode 4, Reward: 238.02
Evaluation Episode 5, Reward: 238.02
Evaluation Episode 6, Reward: 238.02
Evaluation Episode 7, Reward: 238.02
Evaluation Episode 8, Reward: 238.02
Evaluation Episode 9, Reward: -96.49
Evaluation Episode 10, Reward: -88.10
Average Evaluation Reward: 178.07

Visualizing BRL agent uncertainty...

从您提供的训练和评估结果来看,三种基于不确定性的强化学习方法(REM、BRL和EDE)在Lunar Lander环境中的表现各有特点。以下是详细的分析。

1. 训练结果分析

(1)REM(Random Ensemble Mixture)训练过程

  1. 初始阶段(前100个episode),平均奖励为-140.12,表现较差。
  2. 随着训练的进行,平均奖励逐渐提高,到第500个episode时,平均奖励达到148.04。
  3. 训练过程中,探索率(epsilon)逐渐衰减,从0.606降至0.100。

(2)BRL(Pessimistic Bootstrapping)训练过程

  1. 初始阶段(前100个episode),平均奖励为-121.95,表现稍好于REM。
  2. 随着训练的进行,平均奖励逐渐提高,到第500个episode时,平均奖励达到205.58。
  3. 在训练过程中,探索率(epsilon)逐渐衰减,从0.606降至0.100。

(3)EDE(Ensemble Distribution Estimation)训练过程

  1. 初始阶段(前100个episode),平均奖励为-123.50,表现与REM相近。
  2. 随着训练的进行,平均奖励逐渐提高,到第500个episode时,平均奖励达到216.28。
  3. 训练过程中,探索率(epsilon)逐渐衰减,从0.606降至0.100。

2. 评估结果分析

(1)REM评估结果

10个评估episode的平均奖励为-120.21,表现较差。其中,有多个episode的奖励为负值,说明在某些情况下,REM代理的表现不稳定。

(2)BRL评估结果

10个评估episode的平均奖励为17.46,表现中等。其中,有部分episode的奖励较高(如193.32和265.86),但也有多个episode的奖励为-72.41,说明BRL代理的表现也存在一定的波动。

(3)EDE评估结果

10个评估episode的平均奖励为178.07,表现最好。其中,有多个episode的奖励较高(如268.62和238.02),但也有部分episode的奖励为负值(如-96.49和-88.10),说明EDE代理在某些情况下也存在不稳定的情况。

3. 总结

  1. 训练结果:三种方法在训练过程中都表现出了一定的学习能力,随着训练的进行,平均奖励逐渐提高。EDE在训练结束时的平均奖励最高(216.28),其次是BRL(205.58),REM(148.04)。
  2. 评估结果:在评估阶段,EDE的平均奖励最高(178.07),表现最为稳定。BRL的平均奖励为17.46,表现中等。REM的平均奖励为-120.21,表现较差,且存在较大的波动。
  3. 确定性可视化:通过可视化BRL代理的不确定性,可以进一步了解其在不同状态下的决策保守性。

4. 改进建议

  1. REM:虽然训练表现较好,但在评估阶段表现不稳定。可以尝试调整集成网络的数量或训练策略,以提高其在评估阶段的稳定性。
  2. BRL:虽然在训练和评估阶段表现中等,但存在较大的波动。可以尝试调整悲观系数(beta)或探索率(epsilon)的衰减策略,以提高其稳定性和性能。
  3. EDE:虽然在评估阶段表现最好,但仍然存在一定的波动。可以尝试进一步优化不确定性惩罚系数(kappa)或训练策略,以提高其稳定性和性能。

总体来看,EDE在评估阶段的表现最为出色,但三种方法都存在一定的改进空间。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值