新闻、帮助、产品更新动态

最新的业界新闻,产品系统更新开发动态,帮助教程和活动发布

强化学习(三)-gym介绍和实例

发布日:2022-02-09 15:13       阅读数:

gym是openAI下的一个开发和对比强化学习算法的工具包,内部提供了强化学习需要的环境。

gym库安装

我是在window下进行安装的
conda create -n gym
pip install gym
pip install pyglet

gym--hello world代码

我们参考官方文档执行gym的“hello world”代码。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    # take a random action
    env.step(env.action_space.sample()) 
env.close()
运行以上代码,如果出现一个倒立摆问题的动画,说明gym库安装成功了,我们跑通了gym最简单的hello world代码。
简单介绍下上面代码主要实现的功能:
env = gym.make('CartPole-v0')运创建一个cartpole问题的环境,对于cartpole问题下文会进行详细介绍。
env.reset() 对环境进行重置,得到初始的observation
env.render()渲染物体状态的UI,这里调用了gym的渲染接口,我们不做深究
env.action_space.sample()指从动作空间中随机选取一个动作
env.step() 指在环境中采取选择的动作,这里会返回reward等信息
也就是首先创建一个环境,对环境进行重置。然后循环迭代1000次,每个迭代中我们从环境的动作空间中选择一个动作进行执行,进入下一个状态。
我们在实现自己的算法时,最看重的就是选取动作和策略这一步,也就是根据现在的状态,如何选择下一步的动作。
gym实例--CartPole
通过上面简单的demo可能对整个环境的理解以及状态空间,状态空间,step返回还是不太理解。本节就对demo进行更详细的讲解。
CartPole介绍
首先,我们得知道CartPole是要解决什么问题。CartPole是一个小车倒立摆的问题。如下图所示:

CartPole环境介绍
对于CartPole环境中的状态空间和动作空间,可以通过源码结合我们在代码中的日志进行了解。
在demo代码中打印了解数据形式:
 print("env.action_space", env.action_space)
>> Discrete(2)

动作空间是一个离散数据:   状态空间值{0,1},0--表示左移动,1--表示右移动

print("env.observation_space", env.observation_space)
>>Box(4,) 
状态空间是一个多维空间,四个维度分别表示:小车在轨道上的位置,杆子和竖直方向的夹角,小车速度,角度变化率。
每执行一个step(),返回四个值:
observation, reward, done, info = env.step(sample_action)
observation:当前状态值
reward: 每步给出奖励1
done: 本轮探索是否结束
info:  调试信息
重新了解demo逻辑,首先初始化环境observation(状态),选取一个动作,然后返回在环境中执行动作后的observation,每次step的reward都是1,当杆倒下done就为False,杆向上的时间越长,得到的reward就越大。
我们学习的目标就是保持杆一直竖直朝上,杆由于重力原因会一直倾斜,当杆倾斜到一定程度就会倒下,此时需要朝左或者右移动杆保证它不会倒下来。
下面代码为将demo代码进行一些日志扩充,让我们对CartPole-v0环境有个更充分的认识。
import gym
# 创建一个CartPole-v0(小车倒立摆模型)
env = gym.make('CartPole-v0')
for i_episode in range(1000):
    # 环境重置,得到一个初始observation
    observation = env.reset()
    for t in range(1000):
        # 渲染引擎显示物体状态
        env.render()
        # 动作空间,{0,1} 0-左移动, 1-右移动
        print("env.action_space", env.action_space)
        # >>Discrete(2) 一个离散空间
        # 状态空间
        print("env.observation_space", env.observation_space)
        # >>Box(4,) 多维空间
        # 奖励范围和状态空间范围
        # print("env.reward_range", env.reward_range)
        # print("env.observation_space.high", env.observation_space.high)
        # print("env.observation_space.low", env.observation_space.low)
        # print("env.observation_space.bounded_above", env.observation_space.bounded_above)
        # print("env.observation_space.bounded_below",  env.observation_space.bounded_below)
        # 随机选取动作
        sample_action = env.action_space.sample()
        """
        observation:当前观察的object的状态值
        小车在轨道上的位置,杆子和竖直方向的夹角,小车速度,角度变化率)
        
        reward: 执行上一个action后的奖,每一步给出奖励1
        
        done:本轮探索是否结束,是否需要reset环境
        达到下列条件之一片段结束:
        杆子与竖直方向角度超过12度
        小车位置距离中心超过2.4(小车中心超出画面)
        考虑片段长度超过200
        考虑连续100次尝试的平均奖励大于等于195。
        
        info:调试信息
        """
        observation, reward, done, info = env.step(sample_action)
        print('observation:{}, reward:{}, done:{}, info:{}'.format(observation, reward, done, info))
        # 如果结束, 则退出循环
        if done:
            print("Episode finished after {} timesteps".format(t + 1))
            break
env.close()

CartPole问题--Random Guessing Algorithm & Hill Climbing Algorithm

在以上代码中,我们最重要的就是如何将学习过程中的sample_action修改为通过策略决定出一个合适的action。本文介绍简单的Random Guessing Algorithm & Hill Climbing Algorithm进行策略。
通过策略选择的action的取值即0 or 1,observation是一个四维向量,如果对这个向量求它的加权和,就可以得到一个值,再根据加权和的符号来决定action。
Random Guessing Algorithm就是每次加权权重为随机给出的值。
Hill Climbing Algorithm就是每次将上一次得到的最好权重加上一个小的随机变化更新。
主要流程和逻辑在一下代码中注释进行了讲解。
主要代码如下:
import numpy as np
import gym
import time

def get_action(weights, observation):
    """ 根据weights,对observation进行加权求和,根据值决定动作策略
    """
    wxb = np.dot(weights[:4], observation) + weights[4]
    if wxb >= 0:
        return 1
    else:
        return 0

def get_sum_reward_by_weights(env, weights):
    """ 根据当前策略,计算本次探索的累计reward
    """
    observation = env.reset()
    sum_reward = 0
    for t in range(1000):
        # time.sleep(0.01)
        # env.render()
        action = get_action(weights, observation)
        observation, reward, done, info = env.step(action)
        sum_reward += reward
        if done:
            break
    return sum_reward


def get_weights_by_random_guess():
    """ 使用 Random Guessing Algorithm 返回weights, 没轮随机给出权重
    """
    return np.random.rand(5)

def get_weights_by_hill_climbing(best_weights):
    """ 使用 hill_climbing Algorithm 返回weights, 每次最好的权重加上一点随机变化
    """
    return best_weights + np.random.normal(0, 0.1, 5)

def get_best_result(algo="random_guess"):
    env = gym.make("CartPole-v0")
    np.random.seed(10)
    best_reward = 0
    best_weights = np.random.rand(5)
    # 进行100轮探索
    for iter in range(10000):
        # 选择策略算法
        if algo == "hill_climbing":
            cur_weights = get_weights_by_hill_climbing(best_weights)
        else:
            cur_weights = get_weights_by_random_guess()
        # 使用本轮探索得到的策略权重,得到累计reward
        cur_sum_reward = get_sum_reward_by_weights(env, cur_weights)

        # 保存探索过程中最好的reward对应的权重值
        if cur_sum_reward > best_reward:
            best_reward = cur_sum_reward
            best_weights = cur_weights

        if best_reward >= 200:
            break
    print(iter, best_reward, best_weights)
    return best_reward, best_weights

if __name__ == '__main__':
    get_best_result("hill_climbing")
 

编辑:航网科技   来源:腾讯云

本文版权归原作者所有 转载请注明出处

联系我们

客服部:深圳市龙华区龙胜商业大厦5楼B5区

业务部:深圳市南山区讯美科技广场2栋12楼1202

资质证书

  • Copyright © 2011-2020 www.hangw.com. All Rights Reserved 深圳航网科技有限公司 版权所有 增值电信业务经营许可证:粤B2-20201122 - 粤ICP备14085080号

    在线客服

    微信扫一扫咨询客服


    全国免费服务热线
    0755-36300002

    返回顶部