还有比这更好的方法来实现强化学习的 Softmax 动作选择吗?

问题描述 投票:0回答:4

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

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

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。

有更有效的方法吗?

python-2.7 if-statement random reinforcement-learning softmax
4个回答
2
投票

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

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

1
投票

评估每个动作的概率后,如果您有一个函数返回加权随机选择,您可以获得如下所示的所需动作:

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)

0
投票

在使用 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]

0
投票

如果您有包含操作 ID 的列表:

actions = [0, 1, 2]

您可以使用带有概率列表的 numpy 随机选择:

action_int = numpy.random.choice(actions, p=prob_t)

您可以通过多次迭代此语句来证明这一点:

results = []
for i in range(30):
    actions = [0, 1, 2]
    prob_t = [0.6, 0.1, 0.3]

    action_int = np.random.choice(actions, p=prob_t)

    results.append(action_int)

print(results)

你会得到这样的东西:

[0, 1, 2, 0, 0, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0, 2, 2, 2, 0, 0, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0]
© www.soinside.com 2019 - 2024. All rights reserved.