(7-3-03)TRPO算法核心知识与应用实践:综合实战:基于矩阵低秩分解的TRPO优化(3)

7.3.8  评估TRPO在MountainCarContinuous-v0环境中的性能

编写文件main_mountaincar.py,用于训练和评估 TRPO 算法在 MountainCarContinuous-v0 环境中的性能,并保存训练结果以备将来使用。主要实现代码如下所示。

import pickle
import gym

from src.models import PolicyNetwork, PolicyLR, ValueNetwork, ValueLR
from src.agents import TRPOGaussianNN
from src.algorithms import Trainer
from src.utils import Discretizer


if __name__ == "__main__":
    res_nn, res_lr = [], []
    env = gym.make("MountainCarContinuous-v0")
    for _ in range(100):
        # NN
        actor = PolicyNetwork(2, [8], 1).double()
        critic = ValueNetwork(2, [8], 1).double()

        agent = TRPOGaussianNN(
            actor,
            critic,
            gamma=0.99,
            delta=0.01,
            tau=0.9,
            cg_dampening=0.05,
            cg_tolerance=1e-10,
            cg_iteration=10,
        )

        trainer = Trainer(actor_opt='sgd', critic_opt='sgd')
        agent, totals, timesteps = trainer.train(
            env,
            agent,
            epochs=300,
            max_steps=10000,
            update_freq=15000,
            initial_offset=10,
        )
        res_nn.append(totals)

        # LR
        discretizer = Discretizer(
            min_points=[-1.2, -0.07],
            max_points=[0.6, 0.07],
            buckets=[4, 4],
            dimensions=[[0], [1]]
        )

        actor = PolicyLR(4, 4, 1, 0.1).double()
        critic = ValueLR(4, 4, 1, 1.0).double()

        agent = TRPOGaussianNN(
            actor,
            critic,
            discretizer,
            discretizer,
            gamma=0.99,
            delta=0.01,
            tau=0.9,
            cg_dampening=0.05,
            cg_tolerance=1e-10,
            cg_iteration=10,
        )

        trainer = Trainer(actor_opt='sgd', critic_opt='sgd')
        _, totals, _ = trainer.train(
            env,
            agent,
            epochs=300,
            max_steps=10000,
            update_freq=15000,
            initial_offset=10,
        )
        res_lr.append(totals)

    with open('results/mount_nn.pkl','wb') as f:
        pickle.dump(res_nn, f)

    with open('results/mount_lr.pkl','wb') as f:
        pickle.dump(res_lr, f)

对上述代码的具体说明如下:

(1)创建两个空列表 res_nn 和 res_lr,用于存储训练结果。

(2)创建 MountainCarContinuous-v0 环境:使用 gym.make 创建 MountainCarContinuous-v0 环境。

(3)循环训练代理:在循环中,首先创建一个使用神经网络的代理(agent),具体说明如下:

  1. 创建 PolicyNetwork 和 ValueNetwork 实例,并设置网络结构。
  2. 创建 TRPOGaussianNN 代理对象,指定网络、算法参数等。
  3. 创建 Trainer 训练器对象。

然后调用 trainer.train 函数,对代理在环境中进行训练,具体说明如下:

  1. epochs=300:执行 300 个训练周期。
  2. max_steps=10000:每个周期最多执行 10000 步。
  3. update_freq=15000:每 15000 步执行一次策略更新。
  4. initial_offset=10:初始偏移值。

最后,将每个周期的总奖励添加到 res_nn 或 res_lr 中,具体取决于代理类型。

(4)使用 pickle 模块将训练结果保存到文件中:分别将 res_nn 和 res_lr 保存到两个不同的 pickle 文件中,以供后续分析和可视化使用。

7.3.9  评估TRPO在CustomPendulumEnv环境中的性能

编写文件main_pendulum.py,用于训练和评估 TRPO 算法在 CustomPendulumEnv 环境中的性能,并保存训练结果以供后续分析和可视化使用。具体实现代码如下所示。

import pickle

from src.environments import CustomPendulumEnv
from src.models import PolicyNetwork, PolicyLR, ValueNetwork, ValueLR
from src.agents import TRPOGaussianNN
from src.algorithms import Trainer
from src.utils import Discretizer

if __name__ == "__main__":
    res_nn, res_lr = [], []
    env = CustomPendulumEnv()
    for _ in range(100):
        # NN
        actor = PolicyNetwork(2, [16, 16], 1).double()
        critic = ValueNetwork(2, [16, 16], 1).double()

        agent = TRPOGaussianNN(
            actor,
            critic,
            gamma=0.99,
            delta=0.05,
            tau=0.9,
            cg_dampening=0.1,
            cg_tolerance=1e-10,
            cg_iteration=10,
        )

        trainer = Trainer(actor_opt='sgd', critic_opt='sgd')
        _, totals, _ = trainer.train(
            env,
            agent,
            epochs=2000,
            max_steps=1000,
            update_freq=15000,
            initial_offset=-1,
        )
        res_nn.append(totals)

        # LR
        discretizer = Discretizer(
            min_points=[-1, -5],
            max_points=[1, 5],
            buckets=[16, 16],
            dimensions=[[0], [1]]
        )

        actor = PolicyLR(16, 16, 4, 1.0).double()
        critic = ValueLR(16, 16, 4, 1.0).double()

        agent = TRPOGaussianNN(
            actor,
            critic,
            discretizer,
            discretizer,
            gamma=0.99,
            delta=0.05,
            tau=0.9,
            cg_dampening=0.1,
            cg_tolerance=1e-10,
            cg_iteration=10,
        )

        trainer = Trainer(actor_opt='sgd', critic_opt='sgd')
        _, totals, _ = trainer.train(
            env,
            agent,
            epochs=2000,
            max_steps=1000,
            update_freq=15000,
            initial_offset=-1,
        )
        res_lr.append(totals)

    with open('results/pend_nn.pkl','wb') as f:
        pickle.dump(res_nn, f)

    with open('results/pend_lr.pkl','wb') as f:
        pickle.dump(res_lr, f)

对上述代码的具体说明如下:

(1)创建两个空列表 res_nn 和 res_lr,用于存储训练结果。

(2)创建 CustomPendulumEnv 环境:使用 CustomPendulumEnv 创建自定义 Pendulum 环境。

(3)循环训练代理:在循环中,首先创建一个使用神经网络的代理(agent),具体说明如下:

  1. 创建 PolicyNetwork 和 ValueNetwork 实例,并设置网络结构。
  2. 创建 TRPOGaussianNN 代理对象,指定网络、算法参数等。
  3. 创建 Trainer 训练器对象。

然后,调用 trainer.train 函数,对代理在环境中进行训练,具体说明如下:

  1. epochs=2000:执行 2000 个训练周期。
  2. max_steps=1000:每个周期最多执行 1000 步。
  3. update_freq=15000:每 15000 步执行一次策略更新。
  4. initial_offset=-1:初始偏移值。

最后,将每个周期的总奖励添加到 res_nn 或 res_lr 中,具体取决于代理类型。

(4)使用 pickle 模块将训练结果保存到文件中:分别将 res_nn 和 res_lr 保存到两个不同的 pickle 文件中,以备将来使用。

7.3.10  性能可视化

编写文件plot.py,用于生成图表以可视化展示在不同环境下(Pendulum、Acrobot 和 Mountain Car)使用不同的 TRPO 算法(NN-TRPO 和 TRLRPO)训练的代理的性能。文件plot.py的具体实现代码如下所示。

import pickle
import numpy as np
import matplotlib.pyplot as plt

res_nn_pend = pickle.load(open('results/pend_nn.pkl','rb'))
res_lr_pend = pickle.load(open('results/pend_lr.pkl','rb'))
res_nn_acro = pickle.load(open('results/acro_nn.pkl','rb'))
res_lr_acro = pickle.load(open('results/acro_lr.pkl','rb'))
res_nn_mount = pickle.load(open('results/mount_nn.pkl','rb'))
res_lr_mount = pickle.load(open('results/mount_lr.pkl','rb'))

with plt.style.context(['science'], ['ieee']):
    fig, axes = plt.subplots(3, 1, figsize=(8, 12))
    plt.rc('legend', fontsize=16)    # legend fontsize
    axes = axes.flatten()

    # Pendulum
    axes[0].plot(np.median(res_nn_pend, axis=0), label='NN-TRPO - 674 params.')
    axes[0].fill_between(
        np.arange(len(res_nn_pend[0])),
        np.percentile(res_nn_pend, 25, axis=0),
        np.percentile(res_nn_pend, 75, axis=0), color='b', alpha=0.2)

    axes[0].plot(np.median(res_lr_pend, axis=0), label='TRLRPO - 256 params.')
    axes[0].fill_between(
        np.arange(len(res_nn_pend[0])),
        np.percentile(res_lr_pend, 25, axis=0),
        np.percentile(res_lr_pend, 75, axis=0), color='orange', alpha=0.2)
    
    axes[0].set_ylabel('(a) Return', fontsize=18)
    axes[0].set_xlabel('Episodes', fontsize=18)
    axes[0].set_xlim(0, len(res_nn_pend[0]))
    axes[0].set_xticks([0, 500, 1000, 1500, 2000])
    axes[0].set_yticks([-8000, -6000, -4000, -2000, 0])
    axes[0].tick_params(axis='both', which='major', labelsize=14)
    axes[0].grid()
    axes[0].legend(loc='lower right')

    # Acrobot
    axes[1].plot(np.median(res_nn_acro, axis=0), label='NN-TRPO - 194 params.')
    axes[1].fill_between(
        np.arange(len(res_nn_acro[0])),
        np.percentile(res_nn_acro, 25, axis=0),
        np.percentile(res_nn_acro, 75, axis=0), color='b', alpha=0.2)

    axes[1].plot(np.median(res_lr_acro, axis=0), label='TRLRPO - 32 params.')
    axes[1].fill_between(
        np.arange(len(res_nn_acro[0])),
        np.percentile(res_lr_acro, 25, axis=0),
        np.percentile(res_lr_acro, 75, axis=0), color='orange', alpha=0.2)

    axes[1].set_ylabel('(b) Return', fontsize=18)
    axes[1].set_xlabel('Episodes', fontsize=18)
    axes[1].set_xlim(0, 10000)
    axes[1].set_ylim(-1000, 50)
    axes[1].set_xticks([0, 2500, 5000, 7500, 10000])
    axes[1].set_yticks([-1000, -750, -500, -250, 0])
    axes[1].tick_params(axis='both', which='major', labelsize=14)
    axes[1].grid()
    axes[1].legend(loc='lower right')

    # Mountain Car
    axes[2].plot(np.median(res_nn_mount, axis=0), label='NN-TRPO - 66 params.')
    axes[2].fill_between(
        np.arange(len(res_nn_mount[0])),
        np.percentile(res_nn_mount, 25, axis=0),
        np.percentile(res_nn_mount, 75, axis=0), color='b', alpha=0.2)

    axes[2].plot(np.median(res_lr_mount, axis=0), label='TRLRPO - 16 params.')
    axes[2].fill_between(
        np.arange(len(res_nn_mount[0])),
        np.percentile(res_lr_mount, 25, axis=0),
        np.percentile(res_lr_mount, 75, axis=0), color='orange', alpha=0.2)

    axes[2].set_ylabel('(c) Return', fontsize=18)
    axes[2].set_xlabel('Episodes', fontsize=18)
    axes[2].set_xlim(0, len(res_nn_mount[0]))
    axes[2].set_ylim(-700, 100)
    axes[2].set_xticks([0, 75, 150, 225, 300])
    axes[2].set_yticks([-600, -450, -300, -150, 0])
    axes[2].tick_params(axis='both', which='major', labelsize=14)
    axes[2].grid()
    axes[2].legend(loc='lower right')

    plt.tight_layout()
    fig.savefig('figures/res.png', dpi=300)

对上述代码的具体说明如下:

(1)导入必要的模块和类:

  1. pickle:用于反序列化保存的训练结果。
  2. numpy 和 matplotlib.pyplot:用于数据处理和图表绘制。

(2)使用 pickle 从文件中加载保存的训练结果:

  1. res_nn_pend、res_lr_pend:Pendulum 环境中 NN-TRPO 和 TRLRPO 代理的训练结果。
  2. res_nn_acro、res_lr_acro:Acrobot 环境中 NN-TRPO 和 TRLRPO 代理的训练结果。
  3. res_nn_mount、res_lr_mount:Mountain Car 环境中 NN-TRPO 和 TRLRPO 代理的训练结果。

(3)使用 matplotlib 创建一个包含三个子图的图表:

  1. 每个子图表示一个不同的环境(Pendulum、Acrobot 和 Mountain Car)。
  2. plt.style.context(['science'], ['ieee']):设置图表样式,使其符合科学绘图风格。

(4)对于每个环境,绘制代理的性能曲线和置信区间:

  1. 使用 np.median 计算性能的中位数曲线。
  2. 使用 np.percentile 计算置信区间。
  3. 设置图例和标签。

(5)配置每个子图的标题、轴标签、刻度和样式。

(6)使用 plt.tight_layout() 调整子图的布局。

(7)保存图表为 figures/res.png 文件,并指定 dpi(每英寸点数)为 300。

上述代码的主要目的是生成可视化图表,以便直观地比较不同环境和代理的性能结果。生成的图表 res.png 将显示在当前工作目录中,如图12-1所示。

图12-1  可视化图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农三叔

感谢鼓励

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

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

打赏作者

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

抵扣说明:

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

余额充值