【问题标题】:Is there a better way than this to implement Softmax Action Selection for Reinforcement Learning?有没有比这更好的方法来实现强化学习的 Softmax 动作选择?
【发布时间】:2014-05-07 18:44:15
【问题描述】:

我正在为强化学习任务 (http://www.incompleteideas.net/book/ebook/node17.html) 实施 Softmax 动作选择策略。

我提出了这个解决方案,但我认为还有改进的余地。

1-这里我评估概率

    prob_t = [0]*3
    denominator = 0
    for a in range(nActions):
        denominator += exp(Q[state][a] / temperature) 

    for a in range(nActions):
        prob_t[a] = (exp(Q[state][a]/temperature))/denominator  

2-这里我将 ]0,1[ 范围内的随机生成数与动作的概率值进行比较:

    rand_action = random.random()
    if rand_action < prob_t[0]:
        action = 0      
    elif rand_action >= prob_t[0] and rand_action < prob_t[1]+prob_t[0]:
        action = 1      
    else: #if rand_action >= prob_t[1]+prob_t[0]
        action = 2

编辑:

示例:rand_action 为 0.78,prob_t[0] 为 0.25,prob_t[1] 为 0.35,prob_t[2] 为 0.4。 概率总和为 1。 0.78 大于动作 0 和动作 1 的概率之和 (prob_t[0] + prob_t[1]),因此选择动作 2。

有没有更有效的方法?

【问题讨论】:

  • nActions 的大小是 Q[state] 吗?你有numpy 吗?
  • 是的,nActions 是可能动作的数量,因此是每个 Q[state] 的大小。我确实有 numpy

标签: python-2.7 if-statement random reinforcement-learning softmax


【解决方案1】:

使用 numpy 库可以轻松完成基于概率的动作选择。

q_values = [] #array of q_values
action = np.random.choice(q_values,p=q_values)

【讨论】:

    【解决方案2】:

    在评估每个动作的概率后,如果你有一个函数可以返回加权随机选择,你可以像这样得到你想要的动作:

    action = weighted_choice(prob_t)
    

    虽然我不确定这是否是你所说的“更好的方式”。

    weighted_choice 可以类似于this

    import random
    def weighted_choice(weights):
        totals = []
        running_total = 0
    
        for w in weights:
            running_total += w
            totals.append(running_total)
    
        rnd = random.random() * running_total
        for i, total in enumerate(totals):
            if rnd < total:
                return i
    

    如果你有很多可用的操作,一定要检查文章中的二分搜索实现,而不是上面的线性搜索。

    或者如果你可以访问numpy:

    import numpy as np
    def weighted_choice(weights):
        totals = np.cumsum(weights)
        norm = totals[-1]
        throw = np.random.rand()*norm
        return np.searchsorted(totals, throw)
    

    【讨论】:

    • prob_t 是一个列表,其中包含每个可能操作的概率,其值总和为 1。通过在函数中执行第一个 for,running_total 将为 1。为什么建议这样做?跨度>
    • 不是为 3 个可能的操作执行 if..elif..else,这是一种更有效的方式来选择您想要的操作吗?我可能错了,因为我不知道如何在您的原始帖子中定义“更好”。
    • 现在编辑问题以更好地解释我如何选择操作。更好,因为效率更高,计算更少(比较,循环)
    【解决方案3】:

    在使用 numpy 的建议之后,我做了一些研究,并为 soft-max 实现的第一部分提供了这个解决方案。

    prob_t = [0,0,0]       #initialise
    for a in range(nActions):
        prob_t[a] = np.exp(Q[state][a]/temperature)  #calculate numerators
    
    #numpy matrix element-wise division for denominator (sum of numerators)
    prob_t = np.true_divide(prob_t,sum(prob_t))      
    

    比我最初的解决方案少了一个 for 循环。 我能理解的唯一缺点是精度降低。

    使用 numpy:

    [ 0.02645082  0.02645082  0.94709836]
    

    初始双循环解决方案:

    [0.02645082063629476, 0.02645082063629476, 0.9470983587274104]
    

    【讨论】:

    • 使用的温度值是多少,是超参数吗?如何决定?谢谢
    • @cvg 温度用于调节数值差异如何转化为概率:(根据原始问题incompleteideas.net/book/ebook/node17.html 中的链接)。它不一定是要调整的超参数,我想这取决于您的应用程序。
    猜你喜欢
    • 1970-01-01
    • 2010-10-18
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 2021-11-15
    • 2020-04-05
    相关资源
    最近更新 更多