强化学习:双Q学习算法

巧了我就是萌 提交于 2020-01-21 04:50:03

双Q学习算法 vs Q学习算法

问题提出

在这里插入图片描述
如图所示,这个MDP有两个非终止节点A和B,每幕都从A开始并选择向左或者向右。选择向右会立刻转移到终止状态并得到值为0的回报,选择向左则会到达节点B且得到值为0的回报。B状态下有很多种可能的动作,每种动作选择后都会从一个均值为-0.1、方差为1.0的正太分布中得到一个回报,然后到达终止状态。
我们的目的是分别用Q学习和双Q学习算法实现这个MDP过程,并设置参数记录在多次循环后该MDP过程在每幕中选择向左的概率,以比较两种算法的最大化偏差,进而比较两种算法的优劣。

问题解决

状态A有两个动作:left:0、 right:1
状态B设置有4个动作:0, 1, 2, 3;选择任何一个动作都会到达终止状态。
状态C(终止状态)一个动作:0;用来更新Q(s,a),此状态下终止MDP,不会选择动作。

Q(s,a)代表Q学习算法的状态-动作值函数;Q1(s,a)和Q2(s,a)代表双Q学习的状态-动作值函数。两者的初始化同上一篇博客的问题解决里的内容类似,不赘述。

其它参数:alpha:0.1,gamma: 1,epsilon: 0.1

算法

给出双Q学习的算法,Q学习算法上一篇博客已给出。
在这里插入图片描述

程序

由于程序较长,只给出与双Q学习算法有关的程序代码。注释写的也蛮清晰的。

'''
函数功能:双Q学习算法动作选择策略
输入:state、epsilon
输出:action
'''
def Epsilon_greedy2(state, epsilon):
    max = -2000
    action = 0
    r_value = random.uniform(0, 1)  # 策略选择
    if r_value < epsilon:       # 小于epsilon,动作随机选取
        if state == 0:
            action = random.uniform(0, 2)
        if state == 1:
            action = random.randint(0, 3)
    else:                       # 依贪心系数选择动作
        if state == 0:
            for item in range(2):
                if max < Q1[(state, item)] + Q2[(state, item)]:
                    max = Q1[(state, item)] + Q2[(state, item)]
                    action = item
        if state == 1:
            for item in range(4):
                if max < Q2[(state, item)] + Q2[(state, item)]:
                    max = Q2[(state, item)] + Q2[(state, item)]
                    action = item
    return action
'''
函数功能:双Q学习算法
输入:alpha、gamma
输出:向左概率
'''
def DQ_Learning(alpha, gamma):
    for i in range(100):
        for loop_num in range(300):                 #对每幕循环
            sum_Reward = 0
            state = 0
            while True:                             #对每步循环
                action = Epsilon_greedy2(state, 0.1)
                if state == 0:
                    if action == 0:
                        nextstate = 1
                        R = 0
                    else:
                        nextstate = 2
                        break
                if state == 1:
                    R = np.random.normal(mu, sigma, num)  # 从正太分布中得到一个收益
                    nextstate = 2
                if state == 2:
                    break
                maxa = Epsilon_greedy2(nextstate, -0.1)
                r_value = random.uniform(0, 1)
                if r_value <= 0.5:                      #更新Q
                    Q1[(state, action)] = Q1[(state, action)] + alpha * (
                                R + gamma * Q2[(nextstate, maxa)] - Q1[(state, action)])
                else:
                    Q2[(state, action)] = Q2[(state, action)] + alpha * (
                                R + gamma * Q1[(nextstate, maxa)] - Q2[(state, action)])
                state = nextstate
                sum_Reward = sum_Reward + R
            if sum_Reward != 0:          #向左走的情况
                P2[loop_num] = P2[loop_num] + 1

    for j in range(300):
        worksheet.write(j+1, 2, str(P2[j]/100))	#算概率

画图与分析

画图程序
'''
函数功能:画图分析
输入:
输出:两种算法的向左选择概率对比图
'''
def Show_picture():
    aa = 'D:\RL\Q_and_DQ.xlsx'
    df = pd.DataFrame(pd.read_excel(aa))
    df = df.set_index('幕数')
    df = df[['Q学习:向左概率', '双Q学习:向左概率']]
    df.plot(secondary_y=[], grid=True)
    plt.legend(('Q学习:向左概率', '双Q学习:向左概率'), loc='upper right')
    plt.rcParams['font.sans-serif'] = ['SimHei']
    matplotlib.rcParams['axes.unicode_minus'] = False
    plt.savefig("D:\RL\Q_Learning_vs_SARSA1.png", dpi=500)
    plt.show()
图示

采取100次循环,取平均值。由下图可见,Q学习在多次循坏后,依然有5%左右的概率选择向左到达终止节点,而双Q学习显然做的更好,基本不会再向左选择收益更少的路径到达终止节点。由此可见,双Q学习算法在降低最大化偏差上的效果比Q学习更好。
在这里插入图片描述

参考文献

[1]: Reinforcement Learning: An Introduction(Second Edition), Richard S. Sutton and Andrew G. Barto , 2019.9

ps:转载请表明出处

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!