You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/sr/8-Reinforcement/1-QLearning/README.md

24 KiB

Увод у учење појачањем и Q-учење

Резиме учења појачањем у машинском учењу у виду скице

Скица од Tomomi Imura

Учење појачањем укључује три важна концепта: агента, нека стања и скуп акција за свако стање. Извршавањем акције у одређеном стању, агент добија награду. Замислите поново компјутерску игру Супер Марио. Ви сте Марио, налазите се на нивоу игре, стојите поред ивице литице. Изнад вас је новчић. Ви сте Марио, на нивоу игре, на одређеној позицији ... то је ваше стање. Померање један корак удесно (акција) одвешће вас преко ивице, што би вам донело низак нумерички резултат. Међутим, притиском на дугме за скок добили бисте поен и остали бисте живи. То је позитиван исход и требало би да вам донесе позитиван нумерички резултат.

Коришћењем учења појачањем и симулатора (игре), можете научити како да играте игру како бисте максимизовали награду, што је у овом случају преживљавање и освајање што више поена.

Увод у учење појачањем

🎥 Кликните на слику изнад да чујете Дмитрија како говори о учењу појачањем

Квиз пре предавања

Предуслови и подешавање

У овој лекцији ћемо експериментисати са кодом у Пајтону. Требало би да будете у могућности да покренете код из Јупитер бележнице из ове лекције, било на вашем рачунару или негде у облаку.

Можете отворити бележницу лекције и пратити ову лекцију како бисте је изградили.

Напомена: Ако отварате овај код из облака, такође треба да преузмете датотеку rlboard.py, која се користи у коду бележнице. Додајте је у исти директоријум као и бележницу.

Увод

У овој лекцији истражићемо свет Петра и вука, инспирисан музичком бајком руског композитора Сергеја Прокофјева. Користићемо учење појачањем како бисмо омогућили Петру да истражује своје окружење, сакупља укусне јабуке и избегава сусрет са вуком.

Учење појачањем (RL) је техника учења која нам омогућава да научимо оптимално понашање агента у неком окружењу извођењем многих експеримената. Агент у овом окружењу треба да има неки циљ, дефинисан функцијом награде.

Окружење

Ради једноставности, замислимо Петров свет као квадратну таблу величине ширина x висина, овако:

Петрово окружење

Свака ћелија на овој табли може бити:

  • тло, по коме Петар и друга створења могу ходати.
  • вода, по којој очигледно не можете ходати.
  • дрво или трава, место где можете одморити.
  • јабука, која представља нешто што би Петар радо пронашао како би се нахранио.
  • вук, који је опасан и треба га избегавати.

Постоји посебан Пајтон модул, rlboard.py, који садржи код за рад са овим окружењем. Пошто овај код није важан за разумевање наших концепата, увешћемо модул и користити га за креирање узорка табле (блок кода 1):

from rlboard import *

width, height = 8,8
m = Board(width,height)
m.randomize(seed=13)
m.plot()

Овај код би требало да испише слику окружења сличну оној изнад.

Акције и политика

У нашем примеру, Петров циљ би био да пронађе јабуку, избегавајући вука и друге препреке. Да би то урадио, он може суштински ходати док не пронађе јабуку.

Дакле, на било којој позицији, он може изабрати једну од следећих акција: горе, доле, лево и десно.

Дефинисаћемо те акције као речник и мапирати их на парове одговарајућих промена координата. На пример, померање удесно (R) одговарало би пару (1,0). (блок кода 2):

actions = { "U" : (0,-1), "D" : (0,1), "L" : (-1,0), "R" : (1,0) }
action_idx = { a : i for i,a in enumerate(actions.keys()) }

Да резимирамо, стратегија и циљ овог сценарија су следећи:

  • Стратегија нашег агента (Петра) дефинисана је такозваном политиком. Политика је функција која враћа акцију у било ком датом стању. У нашем случају, стање проблема представља табла, укључујући тренутну позицију играча.

  • Циљ учења појачањем је да на крају научимо добру политику која ће нам омогућити да ефикасно решимо проблем. Међутим, као основну линију, размотримо најједноставнију политику звану случајно ходање.

Случајно ходање

Прво ћемо решити наш проблем имплементацијом стратегије случајног ходања. Са случајним ходањем, насумично ћемо бирати следећу акцију из дозвољених акција, док не стигнемо до јабуке (блок кода 3).

  1. Имплементирајте случајно ходање помоћу кода испод:

    def random_policy(m):
        return random.choice(list(actions))
    
    def walk(m,policy,start_position=None):
        n = 0 # number of steps
        # set initial position
        if start_position:
            m.human = start_position 
        else:
            m.random_start()
        while True:
            if m.at() == Board.Cell.apple:
                return n # success!
            if m.at() in [Board.Cell.wolf, Board.Cell.water]:
                return -1 # eaten by wolf or drowned
            while True:
                a = actions[policy(m)]
                new_pos = m.move_pos(m.human,a)
                if m.is_valid(new_pos) and m.at(new_pos)!=Board.Cell.water:
                    m.move(a) # do the actual move
                    break
            n+=1
    
    walk(m,random_policy)
    

    Позив функције walk треба да врати дужину одговарајуће путање, која може варирати од једног покретања до другог.

  2. Покрените експеримент ходања више пута (рецимо, 100) и испишите резултујућу статистику (блок кода 4):

    def print_statistics(policy):
        s,w,n = 0,0,0
        for _ in range(100):
            z = walk(m,policy)
            if z<0:
                w+=1
            else:
                s += z
                n += 1
        print(f"Average path length = {s/n}, eaten by wolf: {w} times")
    
    print_statistics(random_policy)
    

    Приметите да је просечна дужина путање око 30-40 корака, што је прилично много, с обзиром на то да је просечна удаљеност до најближе јабуке око 5-6 корака.

    Такође можете видети како изгледа Петрово кретање током случајног ходања:

    Петрово случајно ходање

Функција награде

Да бисмо нашу политику учинили интелигентнијом, морамо разумети који потези су "бољи" од других. Да бисмо то урадили, морамо дефинисати наш циљ.

Циљ се може дефинисати у смислу функције награде, која ће враћати неку вредност резултата за свако стање. Што је број већи, то је боља функција награде. (блок кода 5)

move_reward = -0.1
goal_reward = 10
end_reward = -10

def reward(m,pos=None):
    pos = pos or m.human
    if not m.is_valid(pos):
        return end_reward
    x = m.at(pos)
    if x==Board.Cell.water or x == Board.Cell.wolf:
        return end_reward
    if x==Board.Cell.apple:
        return goal_reward
    return move_reward

Интересантна ствар код функција награде је да у већини случајева добијамо значајну награду тек на крају игре. То значи да наш алгоритам треба некако да запамти "добре" кораке који воде до позитивне награде на крају и повећа њихов значај. Слично томе, сви потези који воде до лоших резултата треба да буду обесхрабрени.

Q-учење

Алгоритам који ћемо овде размотрити зове се Q-учење. У овом алгоритму, политика је дефинисана функцијом (или структуром података) која се зове Q-табела. Она бележи "квалитет" сваке од акција у датом стању.

Зове се Q-табела јер је често згодно представити је као табелу или вишедимензионални низ. Пошто наша табла има димензије ширина x висина, можемо представити Q-табелу користећи numpy низ облика ширина x висина x len(actions): (блок кода 6)

Q = np.ones((width,height,len(actions)),dtype=np.float)*1.0/len(actions)

Приметите да иницијализујемо све вредности Q-табеле једнаком вредношћу, у нашем случају - 0.25. Ово одговара политици "случајног ходања", јер су сви потези у сваком стању подједнако добри. Можемо проследити Q-табелу функцији plot како бисмо визуализовали табелу на табли: m.plot(Q).

Петрово окружење

У центру сваке ћелије налази се "стрелица" која указује на пожељан правац кретања. Пошто су сви правци једнаки, приказује се тачка.

Сада треба да покренемо симулацију, истражимо наше окружење и научимо бољу расподелу вредности Q-табеле, што ће нам омогућити да много брже пронађемо пут до јабуке.

Суштина Q-учења: Белманова једначина

Када почнемо да се крећемо, свака акција ће имати одговарајућу награду, тј. теоретски можемо изабрати следећу акцију на основу највише непосредне награде. Међутим, у већини стања, потез неће постићи наш циљ достизања јабуке, и стога не можемо одмах одлучити који је правац бољи.

Запамтите да није битан непосредан резултат, већ коначни резултат, који ћемо добити на крају симулације.

Да бисмо узели у обзир ову одложену награду, морамо користити принципе динамичког програмирања, који нам омогућавају да размишљамо о проблему рекурзивно.

Претпоставимо да се сада налазимо у стању s, и желимо да пређемо у следеће стање s'. Тиме ћемо добити непосредну награду r(s,a), дефинисану функцијом награде, плус неку будућу награду. Ако претпоставимо да наша Q-табела тачно одражава "атрактивност" сваке акције, онда ћемо у стању s' изабрати акцију a која одговара максималној вредности Q(s',a'). Тако ће најбоља могућа будућа награда коју бисмо могли добити у стању s бити дефинисана као max Q(s',a') (максимум се овде рачуна преко свих могућих акција a' у стању s').

Ово нам даје Белманову формулу за израчунавање вредности Q-табеле у стању s, за дату акцију a:

Провера политике

Пошто Q-табела приказује "атрактивност" сваке акције у сваком стању, прилично је једноставно користити је за дефинисање ефикасне навигације у нашем свету. У најједноставнијем случају, можемо изабрати акцију која одговара највишој вредности у Q-табели: (код блок 9)

def qpolicy_strict(m):
        x,y = m.human
        v = probs(Q[x,y])
        a = list(actions)[np.argmax(v)]
        return a

walk(m,qpolicy_strict)

Ако пробате код изнад неколико пута, можда ћете приметити да понекад "заглави", и мораћете да притиснете дугме STOP у бележници да бисте га прекинули. Ово се дешава јер могу постојати ситуације када два стања "упућују" једно на друго у смислу оптималне Q-вредности, у ком случају агент завршава тако што се бесконачно креће између тих стања.

🚀Изазов

Задатак 1: Измените функцију walk да ограничите максималну дужину пута на одређени број корака (рецимо, 100), и посматрајте како код изнад враћа ову вредност с времена на време.

Задатак 2: Измените функцију walk тако да се не враћа на места на којима је већ био. Ово ће спречити walk да уђе у петљу, али агент и даље може завршити "заробљен" на локацији са које не може побећи.

Навигација

Боља политика навигације била би она коју смо користили током тренинга, која комбинује експлоатацију и истраживање. У овој политици, изабраћемо сваку акцију са одређеном вероватноћом, пропорционално вредностима у Q-табели. Ова стратегија може и даље довести до тога да се агент врати на позицију коју је већ истражио, али, као што можете видети из кода испод, резултира веома кратком просечном дужином пута до жељене локације (сетите се да print_statistics покреће симулацију 100 пута): (код блок 10)

def qpolicy(m):
        x,y = m.human
        v = probs(Q[x,y])
        a = random.choices(list(actions),weights=v)[0]
        return a

print_statistics(qpolicy)

Након покретања овог кода, требало би да добијете много мању просечну дужину пута него раније, у распону од 3-6.

Истраживање процеса учења

Као што смо поменули, процес учења је баланс између истраживања и експлоатације стеченог знања о структури простора проблема. Видели смо да су резултати учења (способност да се агенту помогне да пронађе кратак пут до циља) побољшани, али је такође занимљиво посматрати како се просечна дужина путања понаша током процеса учења:

Сажетак учења:

  • Просечна дужина пута се повећава. Оно што овде видимо је да се на почетку просечна дужина пута повећава. Ово је вероватно због чињенице да када ништа не знамо о окружењу, вероватно ћемо се заглавити у лошим стањима, води или код вука. Како више учимо и почнемо да користимо то знање, можемо дуже истраживати окружење, али још увек не знамо добро где се налазе јабуке.

  • Дужина пута се смањује како више учимо. Када довољно научимо, постаје лакше агенту да постигне циљ, и дужина пута почиње да се смањује. Међутим, још увек смо отворени за истраживање, па често одступамо од најбољег пута и истражујемо нове опције, чинећи пут дужим од оптималног.

  • Дужина се нагло повећава. Оно што такође примећујемо на овом графику је да се у једном тренутку дужина нагло повећала. Ово указује на стохастичку природу процеса, и да у једном тренутку можемо "покварити" коефицијенте у Q-табели тако што их препишемо новим вредностима. Ово би идеално требало минимизирати смањењем стопе учења (на пример, пред крај тренинга, вредности у Q-табели прилагођавамо само малим износом).

Уопштено, важно је запамтити да успех и квалитет процеса учења значајно зависе од параметара, као што су стопа учења, опадање стопе учења и фактор дисконтовања. Ови параметри се често називају хиперпараметри, како би се разликовали од параметара, које оптимизујемо током тренинга (на пример, коефицијенти у Q-табели). Процес проналажења најбољих вредности хиперпараметара назива се оптимизација хиперпараметара, и заслужује посебну тему.

Квиз након предавања

Задатак

Реалнији свет


Одрицање од одговорности:
Овај документ је преведен коришћењем услуге за превођење помоћу вештачке интелигенције Co-op Translator. Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.