Есть ли лучший способ реализовать выбор действий Softmax для обучения с подкреплением?

Я реализую политику выбора действий 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.

Есть ли более эффективный способ сделать это?


person Alvin    schedule 07.05.2014    source источник
comment
Является ли nActions размером Q[state] ? У вас есть numpy ?   -  person Kiwi    schedule 07.05.2014
comment
Да, nActions — это количество возможных действий и, следовательно, размер каждого Q[состояния]. и у меня есть numpy   -  person Alvin    schedule 07.05.2014


Ответы (3)


Выбор действия на основе вероятностей можно легко сделать с помощью библиотеки numpy.

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

После того, как вы оцените вероятности для каждого действия, если у вас есть функция, возвращающая взвешенный случайный выбор, вы можете получить желаемое действие следующим образом:

action = weighted_choice(prob_t)

Хотя я не уверен, что это то, что вы называете «лучшим способом».

weighted_choice может выглядеть примерно так:

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)
person greeness    schedule 07.05.2014
comment
prob_t — это список, который содержит вероятности для каждого возможного действия, его значения в сумме составляют 1. При первом выполнении for в вашей функции running_total будет 1. Почему вы предлагаете это делать? - person Alvin; 07.05.2014
comment
Вместо того, чтобы делать if..elif..else для 3 возможных действий, это более эффективный способ выбрать желаемое действие? Я могу ошибаться, потому что я не знаю, как лучше определить в вашем исходном сообщении. - person greeness; 08.05.2014
comment
редактирую вопрос сейчас, чтобы лучше объяснить, как я выбираю действие. лучше, как в более эффективном, меньшем количестве вычислений (сравнений, циклов) - person Alvin; 08.05.2014

После предложений использовать 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]
person Alvin    schedule 13.05.2014
comment
какое значение температуры используется, это гиперпараметр? Как это решить? Спасибо - person cvg; 25.09.2019
comment
@cvg Температура используется для регулирования того, как различия в значениях преобразуются в вероятности: (согласно ссылке в исходном вопросе incompleteideas.net/book/ebook/node17.html). Это не обязательно гиперпараметр, который нужно настроить, я думаю, это зависит от вашего приложения. - person Alvin; 27.09.2019