Python强化学习实例,基于上一篇自主寻优,QLearning算法实现序贯决策,迷宫代码

序贯决策是时间序列中,多个阶段需要连续决策,决策是分前后顺序的,前一步的选择直接影响后一步的选择,就像走迷宫一样,走错一步,可能后续就到了死胡同。上一篇笔记已经了解了一些基本概念。这一篇举一个实例。
QLearning算法是一个经典算法,是一种强化学习中的异策略算法。所谓异就是action的策略使用贪婪策略,即选择的结果就是行为值函数最大的action,或者说最优的action。而状态行为(state_action)的选择策略是epsilon贪婪策略,这是在贪婪策略中加入了一个修正epsilon,相当于增加了一个探索利用。这导致每次选择的action不一定都是最优的。不是最优的action也有很小的概率被选择,但是最优的action被选择的概率仍然是最大的。而不是最优的action即使被选择了,也不会影响学习的结果,因为在迭代训练的过程中,不是最优的action的回报并不是最大的。
我们仍然使用上一篇的图。上一篇中,是随机初始化一个位置,每次action选择都是随机的,没有QLearning算法,所以结果可能不是找到金币,而是走到死胡同。这一篇中,加入QLearning算法,使得最终无论起点在哪,蓝点都可以按照最优的路径找到金币。
我们先人工设置一个最优回报(见下图),我们可以人工赋一些初值,也可以把模型迭代的最后结果作为best,因为我们的目的就是将学习的效果进行对比。
Python强化学习实例,基于上一篇自主寻优,QLearning算法实现序贯决策,迷宫代码_第1张图片
在qlearning代码开始的时候,读入人工赋值的回报,记为best,然后每次迭代,计算一次学习结果与best的误差。

register(
    id="GridWorld-v0",
    entry_point="Grid_MDP:GridEnv",
    max_episode_steps=200,
    reward_threshold=100.0,
)
grid = gym.make('GridWorld-v0')
states = grid.env.getStates()  # 获得网格世界的状态空间
actions = grid.env.getAction()  # 获得网格世界的动作空间
gamma = grid.env.getGamma()  # 获得折扣因子
best = dict()  # 储存最优行为值函数

def read_best():
    f = open("best.txt")
    for line in f:
        line = line.strip()
        if len(line) == 0: continue
        eles = line.split(":")
        best[eles[0]] = float(eles[1])

# 计算误差
def compute_error(qfunc):
    sum1 = 0.0
    for key in qfunc:
        error = qfunc[key] - best[key]
        sum1 += error * error
    return sum1

然后就是策略。

#贪婪策略
def greedy(qfunc, state):
    amax = 0
    key = "%d_%s" % (state, actions[0])
    qmax = qfunc[key]
    for i in range(len(actions)):  # 扫描动作空间得到最大动作值函数
        key = "%d_%s" % (state, actions[i])
        q = qfunc[key]
        if qmax < q:
            qmax = q
            amax = i
    return actions[amax]
#epsilon贪婪策略
def epsilon_greedy(qfunc, state, epsilon):
    amax = 0
    key = "%d_%s" % (state, actions[0])
    qmax = qfunc[key]
    for i in range(len(actions)):  # 扫描动作空间得到最大动作值函数
        key = "%d_%s" % (state, actions[i])
        q = qfunc[key]
        if qmax < q:
            qmax = q
            amax = i
            
    # 概率部分
    pro = [0.0 for i in range(len(actions))]
    pro[amax] += 1 - epsilon
    for i in range(len(actions)):
        pro[i] += epsilon / len(actions)

    ##选择动作
    r = random.random()
    s = 0.0
    for i in range(len(actions)):
        s += pro[i]
        if s >= r: return actions[i] # r很小,则可能选择的不是最优
    return actions[len(actions) - 1]

然后,主程序开始的时候,我们设置500次迭代,首先看看,学习的结果。
Python强化学习实例,基于上一篇自主寻优,QLearning算法实现序贯决策,迷宫代码_第2张图片
Python强化学习实例,基于上一篇自主寻优,QLearning算法实现序贯决策,迷宫代码_第3张图片
左侧是学习结果,右侧是best,可以看到,结果很接近。最后,我们连续启动多次运行,看一下运行结果。仍然使用上一篇的GridEnv,下边是主程序入口。

import sys
import gym
from qlearning import *
import time
from gym import wrappers


# main函数
if __name__ == "__main__":

    sleeptime = 1
    terminate_states = grid.env.getTerminate_states()
    # 读入最优值函数
    read_best()
    # 训练
    qfunc = qlearning(num_iter1=500, alpha=0.2, epsilon=0.2)
    time.sleep(sleeptime)
    # 学到的策略为:
    print("the learned policy is:")
    for i in range(len(states)):
        if states[i] in terminate_states:
            print("the state %d is terminate_states" % (states[i]))
        else:
            print("the policy of state %d is (%s)" % (states[i], greedy(qfunc, states[i])))
    # 设置系统初始状态
    s0 = 1
    grid.env.setAction(s0)
    # 对训练好的策略进行测试
    # 随机初始化,寻找金币的路径
    for i in range(7):
        # 随机初始化
        s0 = grid.reset()
        grid.render()
        time.sleep(sleeptime)
        t = False
        count = 0
        # 判断随机状态是否在终止状态中
        if s0 in terminate_states:
            print("reach the terminate state %d" % (s0))
        else:
            while False == t and count < 100:
                a1 = greedy(qfunc, s0)
                print(s0, a1)
                grid.render()
                time.sleep(sleeptime)

                # 与环境进行一次交互,从环境中得到新的状态及回报
                s1, r, t, i = grid.step(a1)
                if True == t:
                    # 打印终止状态
                    print(s1)
                    grid.render()
                    time.sleep(sleeptime)
                    print("reach the terminate state %d" % (s1))
                # s1处的最大动作
                s0 = s1
                count += 1

把上一篇的GridEnv最后改成下面这样,其他不变。

        if self.state is None: return None
        self.robotrans.set_translation(self.x[self.state - 1], self.y[self.state - 1])
        return self.viewer.render(return_rgb_array=mode == 'rgb_array')

下图就是运行结果,无论初始化在哪,都可以最快找到金币。
Python强化学习实例,基于上一篇自主寻优,QLearning算法实现序贯决策,迷宫代码_第4张图片

你可能感兴趣的:(python,gym,qlearning,python,强化学习,贪心算法,目标检测,机器学习)