引言

在这个系列前面的几篇博客里,我们介绍了此强化学习项目的应用背景和状态、动作、奖励等设计。今天我们来看下在模型测试环节,测试样本的设计方法思路吧。

数据生成

在前面经过训练后,我们已经获得了一个比较ok的模型,现在我们希望通过实验检验我们的模型是否正确。在强化学习里的测试模型环节中,通常的做法是设计几个固定的场景,然后让机器人使用训练好的模型进行测试,以此来检验在同样环境中模型的性能。

在此环境中,我们的目标是机器人能够在任意初始姿态下,完成不定旋转中心的姿态调整。那么我们就希望固定一组姿态初始值,在测试时,遍历这几个场景,得到平均值。以此来检验模型的性能。

import pybullet
import math
def test_posture():
    angle = math.pi / 15
    q1 = [0.707,0,-0.707]
    res = []
    for i in q1:
        tmp = math.sqrt(1 - pow(i, 2))
        q21 = tmp
        q22 = -tmp
        rotation1 = pybullet.getQuaternionFromAxisAngle([i, 0, q21], angle)
        rotation2 = pybullet.getQuaternionFromAxisAngle([i, 0, q22], angle)
        res.extend([rotation1,rotation2])
    return res
print(test_posture())

如上所示,首先定义一个列表,里面放置转轴中x轴向量,另一个是z轴的旋转轴。这里需要特别注意,因为在一开始设计的时候,就因为粗心将q2设置成了y轴,导致程序出现bug。

应用

在程序应用环节,我们将其放在环境类的init中,来使一个测试时,都能得到这几个旋转值。:

        self.test_pos = test_posture()

然后在reset函数中,根据参数选择是否进行测试模型,当测试标志位打开时,旋转就采用固定样本:

    def reset(self,test=False,num=0):
           ...
           self.quaternion_value = self.test_pos[num]  if test else self.quaternion_value = random_pos()
           ....

我们在这个文件中进行测试:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--gui", default=True, action='store_false')
    arg = parser.parse_args()
    U = UREnv(arg.gui)
    U.reset(test=True,num=4)
    for i in range(1000000000):
        pass
    U.close()

选取其中两个点:

测试代码

测试时可以这样用:

def test_env(writer,env,frame_idx):
    rewards = 0
    steps = 0
    for i in range(params['EPISODE_TO_EVALUATE']):
        obs = env.reset(test=True,num=i)
        while True:
            obs = ptan.agent.float32_preprocessor([obs]).to(device_name)
            action_values_v = net(obs)
            a = action_values_v.data.cpu().numpy()
            b = np.argmax(a, axis=1)[0]
            action = b/(env.action_num*10)-0.05
            obs,reward,done,step = env.step(action)
            rewards+=reward
            steps+=step
            if done:
                break
    r = rewards/params['EPISODE_TO_EVALUATE']
    s = steps/params['EPISODE_TO_EVALUATE']
    writer.add_scalar("reward_mean",r , frame_idx)
    writer.add_scalar("step_mean",s , frame_idx)
    return r,s

May the force be with you!