理论的东西看着总是让人云里雾里没有实感,别担心,看看代码就懂了。
让我们来看一下ROS里面是如何实现强化学习算法的
首先,让我们来了解下ROS-RL-agent的基本结构及其定义。
ROS 的RL引擎提供了一系列强化学习的引擎和环境。
代码可以在https://github.com/toddhester/rl-texplore-ros-pkg下载到
其主要包含以下几个包:
rl_common: Some files that are common to both agents and environments.
引擎和环境共通方法的定义,加入新引擎时必须COMMON中定义的头文件
rl_msgs: Definitions of ROS messages for agents and envs to communicate.
引擎和环境之间消息的定义
rl_agent: A library of some RL agents including Q-Learning and TEXPLORE.
一些强化学习的引擎
rl_env: A library of some RL environments such as Taxi and Fuel World.
一些强化学习用的模拟环境
rl_experiment: Code to run some RL experiments without ROS message passing.
不使用ROS中MESSAGE机制而直接 实例化引擎和环境并通过其方法的直接调用来进行实验的环境
common package定义了在ROS——RL框架下引擎和环境中必须拥有的一些方法,其都定义在core.hh文件中,如果想要撰写新的引擎或者环境,都必须包含core.hh并继承为其对应目标的子类。
struct experience {
std::vector s;
int act;
float reward;
std::vector next;
bool terminal;
};
定义一个状态序列的转换动作及其回报< s,a,r,s’>其可用于更新引擎模型.terminal变量用于定义这个转换是否是一个吸收态(不再会转换为其他状态)的转换。
这个结构仅仅表示一次经验,即在既有状态下特定动作所得到的结果,所以里面没有描述概率的分量。而转换的概率其实是需要我们通过多次观察得到的。
struct StateActionInfo {
bool known;
float reward;
float termProb;
int frameUpdated;
// map from outcome state to probability
std::map< std::vector , float> transitionProbs;
};
StateActionInfo是在模型进行在给定动作下更新状态所必须返回的结构。它包含了模型在给定的状态和动作下预测所需要的一切信息。其中know指示该过程是否是已知的、reward指示预测的消费,termProb指示信度、frameUpdated指示、transitionProbs表示预测的下个状态的转换概率。
class MDPModel {
public:
/** Update the MDP model with a vector of experiences. */
virtual bool updateWithExperiences(std::vector &instances) = 0;
/** Update the MDP model with a single experience. */
virtual bool updateWithExperience(experience &instance) = 0;
/** Get the predictions of the MDP model for a given state action */
virtual float getStateActionInfo(const std::vector &state, int action, StateActionInfo* retval) = 0;
/** Get a copy of the MDP Model */
virtual MDPModel* getCopy() = 0;
virtual ~MDPModel() {};
};
之前所提到的两个结构全部整合在MDP模型中,以构成完整的概率推断体系。MDP模型必须提供四种方法的实现:
updateWithExperiences:以一系列的经验来更新模型
updateWithExperience:以一个单独的经验来更新模型
getStateActionInfo:获取一个状态-动作信息
getCopy:获取一个模型信息的副本
根据不同模型对于过程条件概率定义的不同,其更新方式也会有区别。
Planner是任务的规划模块
必须定义的方法主要包括:
updateModelWithExperience(state, action, next state, reward, terminal) :以经验数据更新模型的方法
planOnNewModel() :当模型变化以后,根据新模型做出规划
getBestAction(state):在当前状态给出最佳动作
比较有趣的事情在于,所有的消费(reward)都没有通过后续的更新变化,也就是说,如果刚开始时考虑的消费不正确,就有可能导致整个决策层面的倾斜 。
提供环境模型的定义以及与环境交互的接口。主要方法有:
sensation:为引擎提供当前感知的数据
apply(int action):对环境施行一个动作,返回消费值
getNumActions():获取当前环境可以执行的动作数目。理论上来说可以执行的动作和状态应该是解耦的,所以这里不必特意关心状态。
isEpisodic():判断当前环境是否是可以全感知的
std::vector getSeedings():为引擎提供一系列的经验以初始化系数
引擎将接受环境给予的反馈数据并且决定下一步需要作出的动作,主要方法有:
first_action(const std::vector &s):用于确定引擎对环境施加的第一个动作,s参数将环境的初始化参数传入
,返回第一个决定的动作
next_action(float r, const std::vector &s):传入当前的状态与消费,返回下一步需要进行的动作
last_action(float r):最后一步决定的动作,只有在最后动作为第一步This method may only
be called if the last method called was first_action or
next_action.
seedExp(std::vector seeds):通过经验初始化引擎
用于在强化学习的引擎和环境之间交互的一些ROS消息定义
可以发现,在实际的应用中,Enviroment结点是可以通过topic和其他realWord的传感器相结合,从而表达机器人在真实世界中的反应。而引擎和环境之间主要通过五中消息进行沟通,他们主要分为:
int32 action
向环境结点发送一个决定的动作
int32 episode_number
float32 episode_reward
int32 number_actions
This message provides information on the results of the latest episode of the experiment, namely an episode number, the sum of rewards for that episode, and the number of actions the agent took in that episode. The episode_reward can be plotted to look at rewards per episode. rl_msgs/RLExperimentInfo
# Message that contains details about an RL enviroment/task
float32 num_actions
float32 num_states
#Optional information to describe the range of a continous state
#Some RL algorithms may need this to discretize the state space
float32[] min_state_range
float32[] max_state_range
#Info needed for r-max some other methods
float32 max_reward
float32 reward_range
bool stochastic
bool episodic
string title
本消息描述了一个环境模型,包括该环境的命名、动作的数量、状态的数量、每个状态的范围、单步最大最小的消费、两个布尔变量分别指示该经验是随机获取(stochastic)还是从一个完整流程(episodic)中抽取的
# Message that contains a seed experience to initialize the model
float32[] from_state
int32 action
float32[] to_state
float32 reward
bool terminal
定义了一个“经验”数据的结构,包括初始状态、动作、转移状态、消费以及描述它是否是终止状态的变量,以此初始化引擎学习
# Message for returning the current sensation vector
# (i.e. state or observation or sensor readings) and a
# reward from an environment
float32[] state
float32 reward
bool terminal
描述处于不同状态的消费。