栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

强化学习(一) K臂老虎机python实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

强化学习(一) K臂老虎机python实现

强化学习(一) K臂老虎机python实现

前言: 在本科毕业设计中使用Sarsa算法做了机械臂的运动控制,受限于时间,没有深入研究。现在研究生开学已经一月有余,利用课余时间系统的学习Sutton编写的《强化学习》第二版。尽量保持一周两章/三章的速度,因为课余时间真的不多(如果有中科大的老师逛到这,少布置点作业吧,球球了)。学习全程单打独斗,如有错误,恳请指正。

1. 贪心算法+乐观初始值10臂赌博机

下面这个程序中,10个动作的收益符合正态分布,均值依次从-10到9,价值初始值均为0。这也算是一种乐观初始值。后续的实验表面,乐观初始值对这个初级模型的影响非常大,如果初始值不够乐观甚至有些“悲观”,往往不能训练出正确结果。

# 10臂赌博机,采样平均策略,贪心算法
import numpy as np
import matplotlib.pyplot as plt
import random


def choose(a):  # 动作选择函数,返回动作编号
    max_act = np.max(a)
    max_array = np.where(a == max_act)[0]
    # 如果有多个最大价值,随机选
    if max_array.size > 1:
        return np.random.choice(max_array)
    else:
        return max_array[0]


def r_func(x):  # 奖励函数
    # 返回相应动作的奖励,所有动作奖励符合正态分布
    # 均值=相应动作的编号-10,标准差(方差的算数平方根)均为1
    a = int(np.random.normal(x - 10, 1, 1))
    return a


# 初始化价值Q和迭代轮数N
Q = np.zeros(10)
N = 0
# 总收益
r_all = [0]
for i in range(10000):
    act = choose(Q)
    r = r_func(act)
    N = N + 1
    # 计算平均收益序列
    k = r_all[i] + r
    k = k / N
    r_all.append(k)
    Q[act] = Q[act] + (r - Q[act]) / N

# 输出最大价值动作
print(Q)
e = np.max(Q)
print(np.where(Q == e)[0])
plt.plot(range(10000), r_all[1:100001])
plt.show()

输出如下:

[-1.8        -2.         -1.28571429 -3.         -8.         -0.75242984
 -0.73172197 -0.7350572  -1.         -0.66035183]
[9]
2. e-贪心算法

将动作选择函数改为如下所示:

def choose_e(a):  # e-贪心算法动作选择函数,返回动作编号
    ee = 0.2
    rand_e = random.random()
    if rand_e < ee:  # 随机选择
        return random.randint(0, 9)
    else:  # 贪心选择
        max_act = np.max(a)
        # 注意where函数的用法,括号内是条件式,
        # 返回一个元胞,一个是aaray,另一个是数据格式
        max_array = np.where(a == max_act)[0]

        # 如果有多个最大价值,随机选
        if max_array.size > 1:
            return np.random.choice(max_array)
        else:
            return max_array[0]

两者平均收益对比如图所示,其中黄色为贪心算法,红色为e-贪心算法

3. softmax算法

需新增四个全局变量:

# softmax,初始化概率H矩阵
H = np.ones(10)
# 指数HH矩阵
HH = np.ones(10)
# 累积收益标量
r_all2 = 0
# softmax步长
n = 0.1

动作选择函数设计:十个动作被选择的概率归一化之后,[0,1]刚好按十个动作的概率叠加和被划分为10个区间。随机产生[0,1]之间的浮点数,按顺序插入这个区间,浮点数区间中的索引值即为动作编号。
程序如下:

def choose_softmax(H):
    # 归一化
    h = sum(H)
    HP = H / h
    print(h)
    # 将[0,1]这一区间划分为各个动作的概率之比
    H2 = np.zeros(11)
    for t in range(10):
        H2[t + 1] = H2[t] + HP[t]
    H2 = H2[1:11]
    # 生成随机数并查看它在数组中的位置
    e = random.random()
    # 这里要用赋值覆盖原array,不然值不变
    H2 = np.append(H2, e)
    H2.sort()
    # 本次选择的动作编号 = 随机值在H2矩阵的坐标
    return np.where(H2 == e)[0]

在奖励函数中得到奖励,并根据公式更新指数HH数组。

def r_func_softmax(x):  # 奖励函数
    a = np.random.normal(x, 1, 1)
    global N, r_all2, H
    for i in range(10):
        if i == x:
            HH[i] = HH[i] + n * (a - r_all2 / N) * (1 - H[i])
        else:
            HH[i] = HH[i] - n * (a - r_all2 / N) * H[i]
        H[i] = pow(math.e, HH[i])
    r_all2 += a
    return r_all2

在softmax的训练中没有再使用乐观初始值,即价值初值为0,10个动作对应奖励的正态分布的均值=动作自身的编号。训练结果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/348081.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号