tensorflow2 tf2 PG算法 强化学习玩乒乓球

博主分享了在TensorFlow2中实现策略梯度算法来玩乒乓球游戏的经验。经过调试和优化,最终成功实现模型收敛。文章详细介绍了模型构建、前向传播、反向传播的过程,并提供了训练时的资源占用对比和部分训练日志。代码已上传至GitHub,可供参考学习。
摘要由CSDN通过智能技术生成

使用确定性策略梯度玩乒乓球,网上很多案例抄写下来,实际使用发现都无法收敛,花了很多时间纠错,然后从parl提供的代码作为核心参考,收集了其他案例中的优点,自己在tensorflow2中实现了算法,并测试成功收敛

0.99累计奖励 + 0.01 最新奖励 = -1.0 时的训练结果图片

环境:

CPU: AMD Ryzen 9 5900X

GPU: NVIDIA GeForce RTX 3090

备注: 实际上本次测试对设备性能要求并不高,在本人3070ti笔记本和3090差距不大,这就像请一个书法家抄书不会比一个小学生快多少一样,每次学习数据量是非常少的,时间都消耗在运行游戏收集数据上了

常态CPU占用对比

 训练时CPU占用对比

 常态时GPU占用对比

训练时GPU占用对比

版本:

python 3.9

tensorflow-gpu 2.6.0

除上述代码意外,其他环境准备

# 解决 tensorflow2 加载模型时报错的问题
# pip install keras==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

# 游戏环境完善
# pip install gym -i https://pypi.tuna.tsinghua.edu.cn/simple
# pip install ale-py  -i https://pypi.tuna.tsinghua.edu.cn/simple
# pip install gym[accept-rom-license] -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装后会报一些错,但测试已经可以运行
# pip install gym[all] -i https://pypi.tuna.tsinghua.edu.cn/simple

部分训练日志:

......

此处使用的是蒙特卡洛法,积累一定数据以后在更新数据,更多信息注释在代码中

代码核心

from tensorflow.keras import layers, optimizers, Model
import tensorflow as tf

# 1. 构建模型
class PG(Model):

    # 构造器
    def __init__(self, act_dim, lr):
        super(PG, self).__init__()
        self.lr = lr
        self.act_dim = act_dim
        self.ds1 = layers.Dense(256, activation='relu')
        self.ds2 = layers.Dense(64, activation='relu')
        self.ds3 = layers.Dense(act_dim, activation=tf.nn.softmax)

    # 前向传播  : 通过输入的游戏画面,进行预测
    # inputs   : 游戏画面 obs
    def call(self, obs):
        # 根据层构建模型输出
        obs = self.ds1(obs)
        obs = self.ds2(obs)
        obs = self.ds3(obs)
        return obs

    # 反向传播 : 按照策略梯度算法进行更新参数
    # obs_list      : obs数组,shape :                 (None,6400)
    # act_list      : 经过obs数组预测得到的行为数组,    (None,1)
    # reward_list   : 行为获得的经过gama衰减的奖励,     (None,1)
    def learn(self, obs_list, act_list, reward_list):
        # 初始化学习率
        self.optimizer_ = optimizers.Adam(learning_rate=self.lr)
        obs_list = tf.cast(obs_list, dtype=tf.float32)
        reward_list = tf.cast(reward_list, dtype=tf.float32)
        # 求导过程,策略梯度算法的核心
        # 下列运算步骤可能还可以简化,调试没有达到提速的效果,有兴趣的自己试着再优化
        with tf.GradientTape() as tape:
            """
            表示预测的obs画面对应的action行为概率,其概率之和为1
            self(obs_list) 等价于 self.call(obs_list)
            案例 :
            predict_action_list :
            [
                [ 0.1 , 0.2 , 0.3 , 0.4],
                [ 0.1 , 0.5 , 0.2 , 0.2],
                ....
            ]

            """
            predict_action_list = self(obs_list)
            # 这一步 one_hot 是将预测到的action编码为热编码
            # 比如预测行为是 [ [1],... ] ,热编码 [ [0,1,0,0,0...],... ]
            one_hot_ = tf.one_hot(act_list, depth=self.act_dim, axis=1)
            """
                
            这一步是将热编码对应的行为的概率取出,其他行为概率抹除,然后求和得到结果
            比如  
                [0.1,  0.2,   0.3, ...]
            和热编码相乘得到 
                [0,           0.2,    0, ...]

            再进行求和,就得到 [ 0.2 ] 

            """
            predict_action_list *= one_hot_
            predict_action_list = tf.reduce_sum(predict_action_list, axis=1)
            
            """
            tf.math.log(0.1) 等价于 ln(0.1)
            假设 

                predict_action_list : [ 0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9]

            那么的结果如下
            tf.math.log(predict_action_list) : 
                tf.Tensor(
                [ -2.3025851  -1.609438   -1.2039728  -0.9162907  -0.6931472  -0.5108256
                -0.35667497 -0.22314353 -0.10536055     ], shape=(9,), dtype=float32)

            通过上面的结果可以明白,这一步实际就是一个缩放的过程,使得概率越小的越小,概率越大的更加的大
            预测概率越小 log((obs,action)) = 0.1 的结果越小 -2.3025851
            预测概率越大 log((obs,action)) = 0.9 的结果越大 -0.10536055

            """
            log_ = tf.math.log(predict_action_list)
            """
            reward_list : 是经过gama处理以后的权重奖励,
            log_和reward_list相乘得到权重结果,再加一个负号,得到梯度上升的损失
            """
            loss = -log_ * reward_list
        gradient_ = tape.gradient(loss, self.trainable_variables)
        self.optimizer_.apply_gradients(zip(gradient_, self.trainable_variables))

代码训练日志:

完整代码

https://github.com/cjs199/policy-gradient-tensoflow2.0

策略梯度\...                         // 模型权重和偏执,以及完整模型保存地
策略梯度_算法原生实现.py              // 代码执行入口
cjs_util.py                         // 工具类
pg_.py                              // 模型
train.log                           // 完整训练日志

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值