强化学习—PPO代码实现及个人详解4(python)

下面是关于智能体训练的过程

四、定义训练

import copy


def train(cfg, env, agent):
    ''' 训练
    '''
    print("开始训练!")
    rewards = []  # 记录所有回合的奖励
    steps = []
    best_ep_reward = 0  # 记录最大回合奖励
    output_agent = None  # 用于储存表现最好的智能体
    for i_ep in range(cfg.train_eps):
        ep_reward = 0  # 记录一回合内的奖励
        ep_step = 0
        state = env.reset()  # 重置环境,返回初始状态
        for _ in range(cfg.max_steps):
            ep_step += 1
            action = agent.sample_action(state)  # 选择动作
            next_state, reward, done, _ = env.step(action)  # 更新环境,返回transition
            agent.memory.push((state, action, agent.log_probs, reward, done))  # 保存transition
            state = next_state  # 更新下一个状态
            agent.update()  # 更新智能体
            ep_reward += reward  # 累加奖励
            if done:
                break
        if (i_ep + 1) % cfg.eval_per_episode == 0:
            sum_eval_reward = 0
            for _ in range(cfg.eval_eps):
                eval_ep_reward = 0
                state = env.reset()
                for _ in range(cfg.max_steps):
                    action = agent.predict_action(state)  # 选择动作
                    next_state, reward, done, _ = env.step(action)  # 更新环境,返回transition
                    state = next_state  # 更新下一个状态
                    eval_ep_reward += reward  # 累加奖励
                    if done:
                        break
                sum_eval_reward += eval_ep_reward
            mean_eval_reward = sum_eval_reward / cfg.eval_eps
            if mean_eval_reward >= best_ep_reward:
                best_ep_reward = mean_eval_reward
                output_agent = copy.deepcopy(agent)
                print(
                    f"回合:{i_ep + 1}/{cfg.train_eps},奖励:{ep_reward:.2f},评估奖励:{mean_eval_reward:.2f},最佳评估奖励:{best_ep_reward:.2f},更新模型!")
            else:
                print(
                    f"回合:{i_ep + 1}/{cfg.train_eps},奖励:{ep_reward:.2f},评估奖励:{mean_eval_reward:.2f},最佳评估奖励:{best_ep_reward:.2f}")
        steps.append(ep_step)
        rewards.append(ep_reward)
    print("完成训练!")
    env.close()
    return output_agent, {'rewards': rewards}


def test(cfg, env, agent):
    print("开始测试!")
    rewards = []  # 记录所有回合的奖励
    steps = []
    for i_ep in range(cfg.test_eps):
        ep_reward = 0  # 记录一回合内的奖励
        ep_step = 0
        state = env.reset()  # 重置环境,返回初始状态
        for _ in range(cfg.max_steps):
            ep_step += 1
            action = agent.predict_action(state)  # 选择动作
            next_state, reward, done, _ = env.step(action)  # 更新环境,返回transition
            state = next_state  # 更新下一个状态
            ep_reward += reward  # 累加奖励
            if done:
                break
        steps.append(ep_step)
        rewards.append(ep_reward)
        print(f"回合:{i_ep + 1}/{cfg.test_eps},奖励:{ep_reward:.2f}")
    print("完成测试")
    env.close()
    return {'rewards': rewards}

可以看出,该代码也是分为了两部分,一部分是训练,另一部分是测试,只不过训练的步骤更为完善。

1.训练部分

这段代码是一个训练循环。rewards = [] 和 steps = []:初始化两个空列表,用于记录每个回合(ep)的奖励和步数。初始化变量 best_ep_reward 为 0,用于记录最大回合奖励;output_agent 初始化为 None,用于存储表现最好的智能体。

最外面那个循环是让一回合一回合的运行,然后每个回合里面还有很多步数,所以下面又有一个循环for _ in range(cfg.max_steps):,每个步数里面都是:根据当前状态选择动作—用env.step(action)让智能体动作与环境交互,并返回下一个状态、奖励、是否结束等信息—保存上一步返回的信息—更新状态、更新智能体参数计算这个回合的累加奖励

然后这句话:(i_ep+1)%cfg.eval_per_episode == 0:是设定每过几个回合(cfg.eval_per_episode)就要进行评估,也就是看看现在的智能体咋样,评估流程与上面的一样,只不过要算一下所有回合的总奖励(sum_eval_reward)。之后计算每回合平均奖励。然后拿去与当前最好回合奖励去比较,谁更好用谁。

记录每回合的步数和奖励到 steps 和 rewards 列表中。最后打印训练完成消息,关闭环境,返回最优的智能体和奖励数据。

2.测试部分

rewards = [] 和 steps = []:初始化两个空列表,用于记录每个回合的奖励和步数。

for i_ep in range(cfg.test_eps)::开始测试循环,循环次数由配置参数 cfg.test_eps 决定。

ep_reward = 0 和 ep_step = 0:初始化变量 ep_reward 和 ep_step,用于记录每个回合内的奖励和步数。state = env.reset():重置环境,获取初始状态。

内部循环:通过循环根据当前状态选择动作、执行动作并更新状态,直到回合结束。

在每一步中,记录奖励、更新状态,并累加奖励。

记录步数和奖励到 steps 和 rewards 列表中。打印测试完成消息,关闭环境,返回奖励数据。这段代码实现了一个简单的测试函数,用于对训练好的智能体在环境中进行测试,记录测试过程中的奖励信息并返回。

注意:

(1)训练时,前面的第一次训练在选择动作时用的是agent.sample_action,而评估的时候用的是agent.predict_action,两者区别就是,前者会进行探索,而后者不会。因为sample_action里面会有关于梯度的计算,而另一个没有,有梯度计算就意味着会进行策略更新,而策略更新中是有探索部分的,所以可以简单理解为选择了sample_action,就是里面会进行探索,进而更新策略。predict_action通常用于在评估阶段直接根据当前的策略网络预测最优的动作,而不会涉及到梯度计算和策略更新,因此通常不包含额外的探索行为。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值