Омӯзиши мошинӣ ва амиқ

Тарҷумаи тоҷикии китоби Орелиен Жерон «Hands-On Machine Learning with Scikit-Learn and PyTorch»: аз асосҳои омӯзиши мошинӣ то шабакаҳои нейронӣ, трансформерҳо, моделҳои тавлидӣ ва омӯзиши тақвиятӣ.
Агенти Зеҳнӣ · 13 ноябри 2026 · 20 саҳифа · 1 писанд
Боби 19. Омӯзиши тақвиятӣ
Омӯзиши тақвиятӣ (reinforcement learning, RL) яке аз ҷолибтарин ва ҳамзамон яке аз қадимтарин соҳаҳои омӯзиши мошинӣ мебошад. Он аз солҳои 1950 вуҷуд дорад ва дар тӯли солҳо барномаҳои ҷолиби бисёре ба вуҷуд овардааст, хусусан дар бозиҳо (масалан, TD-Gammon, барномаи бозии нард) ва идоракунии мошинҳо, вале кам ба сархати хабарҳо мебаромад. Аммо соли 2013 инқилобе рух дод: муҳаққиқони ширкати навтаъсиси бритониёии DeepMind системаеро нишон доданд, ки қариб ҳар бозии Atari-ро аз сифр омӯхта метавонист ва ниҳоят дар аксари онҳо аз инсонҳо пеш гузашт. Вуруди он танҳо пикселҳои хоми тасвир буд ва пешакӣ қоидаҳои бозиҳоро намедонист. Ин аввалин дастовард аз силсилаи натиҷаҳои ҳайратовар буд:
- Соли 2016 AlphaGo-и DeepMind Ли Седол, бозигари касбии афсонавии Go-ро мағлуб кард; соли 2017 бошад, Кэ Ҷе, қаҳрамони ҷаҳонро шикаст дод. Пеш аз ин ягон барнома ҳатто ба мағлуб кардани устоди ин бозӣ наздик нашуда буд, чӣ расад ба беҳтарин бозигар.
- Соли 2020 DeepMind AlphaFold-ро муаррифӣ кард, ки шакли сеченакаи сафедаҳоро бо дақиқии бесобиқа пешгӯӣ мекунад. Ин дастовард биология, химия ва тибро дигаргун месозад. Демис Ҳассабис, муассис ва роҳбари ширкат, ва Ҷон Ҷампер, директор, барои AlphaFold ҷоизаи Нобел дар соҳаи химия гирифтанд.
- Соли 2022 DeepMind AlphaCode-ро муаррифӣ кард, ки дар сатҳи мусобиқаҳои барномасозӣ код тавлид карда метавонад.
- Соли 2023 DeepMind GNoME-ро муаррифӣ кард, ки сохторҳои нави кристаллиро пешгӯӣ мекунад, аз ҷумла садҳо ҳазор маводи аз рӯйи пешгӯӣ устуворро.
Муҳаққиқони DeepMind ба ин чӣ гуна расиданд? Онҳо неруи омӯзиши амиқро ба омӯзиши тақвиятӣ татбиқ карданд ва натиҷа аз орзуҳои ҷасуронатаринашон ҳам гузашт: омӯзиши амиқи тақвиятӣ ба вуҷуд омад. Имрӯз, гарчанде DeepMind ҳамоно пешсаф аст, созмонҳои зиёди дигар низ ба ин кор пайвастаанд. Дар ин соҳа ғояҳои нав ва имконоти истифодаи гуногун пайваста пайдо мешаванд.
Дар ин боб аввал мефаҳмонем, ки омӯзиши тақвиятӣ чист ва барои кадом корҳо мувофиқ аст. Сипас се оилаи муҳимтарини усулҳои омӯзиши амиқи тақвиятиро баррасӣ мекунем: градиентҳои сиёсат, шабакаҳои амиқи Q бо шарҳи равандҳои қабули қарори Марков ва ниҳоят усулҳои актёр–мунаққид, аз ҷумла PPO-и машҳур, ки бо он бозии Atari-ро мағлуб мекунем. Пас, оғоз мекунем!
Омӯзиши тақвиятӣ чист?
Дар омӯзиши тақвиятӣ агенти нармафзорӣ дар дохили муҳит мушоҳида мекунад ва амалҳоеро иҷро менамояд. Дар иваз аз муҳит мукофот мегирад. Ҳадафаш омӯхтани тарзи рафторест, ки мукофоти интизории ӯро дар тӯли вақт ба ҳадди аксар мерасонад. Агар каме ба инсон монанд кардани агентро раво донем, мукофоти мусбатро метавон лаззат ва мукофоти манфиро дард тасаввур кард. Дар ҳолати дуюм калимаи «мукофот» каме гумроҳкунанда аст. Агент дар муҳит амал мекунад ва бо санҷишу хато меомӯзад, ки лаззатро зиёд ва дардро кам кунад.
Ин чорчӯбаи васеъро ба вазифаҳои гуногун татбиқ кардан мумкин аст. Чанд мисол дар расми 19.1 оварда шудааст:
- Агент метавонад барномаи идоракунии робот бошад. Муҳит ҷаҳони воқеист; агент онро тавассути сенсорҳо, масалан камераҳо ва сенсорҳои ламсӣ, мушоҳида мекунад. Амалҳояш фиристодани сигналҳо барои фаъол кардани муҳаррикҳо мебошанд. Метавон барномарезӣ кард, ки ҳангоми наздик шудан ба макони ҳадаф мукофоти мусбат ва ҳангоми талаф додани вақт ё ба самти нодуруст рафтан мукофоти манфӣ гирад.
- Агент метавонад барномаи идоракунии Ms. Pac-Man бошад. Муҳит симулятсияи бозии Atari аст; амалҳо нуҳ мавқеи имконпазири дастаи бозӣ мебошанд — боло-чап, поён, марказ ва ғайра. Мушоҳидаҳо тасвирҳои экран ва мукофотҳо холҳои бозӣ мебошанд.
- Ба ҳамин монанд, агент метавонад барномаи бозии рӯйимизӣ, монанди Go бошад. Он танҳо ҳангоми ғолиб шудан мукофот мегирад.
- Агент ҳатман чизи аз ҷиҳати ҷисмонӣ ё маҷозӣ ҳаракаткунандаро идора намекунад. Масалан, он метавонад термостати ҳушманд бошад: ҳангоми ба ҳарорати ҳадаф наздик будан ва сарфаи энергия мукофоти мусбат мегирад, вале вақте инсонҳо маҷбур мешаванд ҳароратро тағйир диҳанд, мукофоти манфӣ мегирад. Пас, бояд пешбинӣ кардани ниёзҳои инсонро омӯзад.
- Агент метавонад нархҳои бозори саҳмияҳоро мушоҳида карда, ҳар сония муайян кунад, ки чӣ қадар бихарад ё бифурӯшад. Мукофотҳо фоида ва зиёни пулӣ мебошанд.
Ҳатто мумкин аст ягон мукофоти мусбат вуҷуд надошта бошад. Масалан, агент дар лабиринт ҳаракат карда, дар ҳар қадами вақт мукофоти манфӣ мегирад, бинобар ин бояд ҳарчи зудтар роҳи баромадро ёбад! Барои мошинҳои худрон, системаҳои тавсиядиҳӣ, ҷойгиркунии таблиғ дар вебсаҳифа ё муайян кардани маҳалли диққати системаи таснифбандии тасвир низ омӯзиши тақвиятӣ муносиб аст.

Расми 19.1. Намунаҳои омӯзиши тақвиятӣ: (a) робототехника, (b) Ms. Pac-Man, (c) бозигари Go, (d) термостат, (e) савдогари худкор.
Акнун ба як оилаи калони алгоритмҳои RL — градиентҳои сиёсат — мегузарем.
Градиентҳои сиёсат
Алгоритме, ки агент барои интихоби амалҳояш истифода мекунад, сиёсати он ном дорад. Сиёсат метавонад ҳар гуна алгоритм бошад, масалан шабакаи нейроние, ки мушоҳидаҳоро қабул карда, амали иҷрошавандаро мебарорад (расми 19.2).

Расми 19.2. Омӯзиши тақвиятӣ бо сиёсати шабакаи нейронӣ.
Сиёсат ҳатман детерминистӣ нест. Баъзан ҳатто мушоҳида кардани муҳит лозим нест — кофист агент мукофот гирифта тавонад! Чангкашаки роботии «нобино»-ро тасаввур кунед, ки мукофоташ миқдори чанги дар 30 дақиқа ҷамъоварда мебошад. Сиёсаташ метавонад чунин бошад: ҳар сония бо эҳтимоли p ба пеш ҳаракат кунад ва бо эҳтимоли 1−p тасодуфан ба чап ё рост тоб хӯрад. Кунҷи тобхӯрӣ адади тасодуфӣ байни −r ва +r аст. Чун ин сиёсат тасодуфият дорад, онро сиёсати стохастикӣ мегӯянд. Роҳи ҳаракати робот бетартиб мешавад ва дар ниҳоят он ба ҳар ҷойи дастрас расида, тамоми чангро ҷамъ мекунад. Савол ин аст: дар 30 дақиқа чӣ қадар чанг ҷамъ мекунад?
Чунин роботро чӣ гуна меомӯзонем? Танҳо ду параметри сиёсатро тағйир дода метавонем: эҳтимоли p ва ҳудуди кунҷи r. Як алгоритми имконпазир санҷидани қиматҳои гуногун ва интихоби таркиби беҳтарин мебошад (расми 19.3). Ин намунаи ҷустуҷӯи сиёсат бо усули санҷиши ҳамаҷониба аст. Вақте фазои сиёсатҳо хеле калон аст — одатан ҳамин тавр мешавад — ҷустуҷӯи параметрҳои хуб ба ёфтани сӯзан дар хирмани бузурги коҳ монанд мешавад.
Усули дигар истифодаи алгоритмҳои генетикӣ мебошад. Масалан, насли якуми иборат аз 100 сиёсати тасодуфиро месозем ва месанҷем. Сипас 80 сиёсати бадтаринро «нобуд» карда, аз ҳар яке аз 20 сиёсати боқимонда 4 насл мегирем. Ҳар фарзанд нусхаи волидаш бо каме тағйироти тасодуфӣ аст. Сиёсатҳои зиндамонда бо фарзандонашон насли дуюмро ташкил медиҳанд. Ин равандро то ёфтани сиёсати хуб давом додан мумкин аст.

Расми 19.3. Чор нуқта дар фазои сиёсатҳо (чап) ва рафтори мувофиқи агент (рост).
Роҳи дигар истифодаи усулҳои беҳинасозӣ аст: градиенти мукофотҳоро нисбат ба параметрҳои сиёсат ҳисоб карда, параметрҳоро дар самти мукофотҳои бештар тағйир медиҳем. Алгоритмҳои ин равишро градиенти сиёсат (policy gradient, PG) меноманд. Пеш аз татбиқи онҳо бояд барои агент муҳит созем. Вақти шиносоӣ бо китобхонаи Gymnasium расид.
Шиносоӣ бо китобхонаи Gymnasium
Яке аз мушкилиҳои RL ин аст, ки барои омӯзонидани агент аввал бояд муҳити коркунанда дошта бошед. Барои омӯзиши бозии Atari симулятори он лозим аст. Барои роботи роҳгард муҳит ҷаҳони воқеист ва роботро бевосита дар он омӯзонидан мумкин. Вале маҳдудиятҳо вуҷуд доранд: агар робот аз ҷарӣ афтад, тугмаи Undo-ро пахш карда намешавад. Вақтро ҳам тез карда наметавонед — қувваи ҳисоббарории бештар роботро тезтар ҳаракат намедиҳад. Омӯзонидани 1000 робот ба таври мувозӣ низ одатан бисёр гарон аст. Бинобар ин омӯзиш дар ҷаҳони воқеӣ душвор ва суст буда, ҳадди ақал барои омӯзиши ибтидоӣ муҳити симулятсионӣ лозим мешавад. Барои физикаи сеченака, масалан, PyBullet ё MuJoCo-ро истифода бурдан мумкин аст.
Gymnasium маҷмӯи абзорҳои кушодаасос аст, ки муҳитҳои симулятсионии гуногун медиҳад: бозиҳои Atari, бозиҳои рӯйимизӣ, симулятсияҳои физикии дученака ва сеченака ва ғайра. Дар онҳо агентҳоро омӯзонида, муқоиса карда ё алгоритмҳои нави RL таҳия намудан мумкин аст. Он вориси OpenAI Gym буда, ҳоло аз ҷониби ҷомеаи муҳаққиқону таҳиягарон нигоҳдорӣ мешавад.
Gymnasium дар Colab пешакӣ насб шудааст. Китобхонаи Arcade Learning Environment (ALE), яъне ale_py, низ насб аст: он эмулятори бозиҳои Atari 2600 буда, барои ҳамаи муҳитҳои Atari лозим мебошад. Китобхонаи Box2D барои баъзе муҳитҳои физикаи дученака зарур аст. Агар дар компютери худ кор кунед ва дастурҳои насб-ро риоя карда бошед, бояд омода бошед.
Аввал Gymnasium-ро ворид карда, муҳит месозем:
import gymnasium as gym
env = gym.make("CartPole-v1", render_mode="rgb_array", max_episode_steps=1000)
Ин ҷо муҳити CartPole, версияи 1-ро сохтем. Дар ин симулятсияи дученака аробачаро ба чапу рост суръат медиҳем, то чӯби болои он мувозинаташро нигоҳ дорад (расми 19.4). Ин вазифаи классикии идоракунӣ мебошад. render_mode ва max_episode_steps-ро каме баъд шарҳ медиҳем.
Маслиҳат. Луғати
gym.envs.registryном ва мушаххасоти ҳамаи муҳитҳои дастрасро дорад. Рӯйхати қулайро боgym.pprint_registry()чоп кардан мумкин аст. Муҳитҳои Atari пас аз фаъол кардани эмулятори ALE дастрас мешаванд.

Расми 19.4. Муҳити CartPole.
Пас аз сохтани муҳит онро бо reset() оғоз бояд кард. Ихтиёран тухми генератори ададҳои тасодуфӣ — seed — дода мешавад. Ин метод мушоҳидаи аввалро бармегардонад. Шакли мушоҳида аз муҳит вобаста аст. Дар CartPole он массиви NumPy бо чор адади касрӣ аст: мавқеи уфуқии ароба (0.0 — марказ), суръаташ (мусбат — ба рост), кунҷи чӯб (0.0 — амудӣ) ва суръати кунҷии он (мусбат — ҳамсамти ақрабаки соат). reset() инчунин луғати маълумоти иловагии хоси муҳитро бармегардонад. Ин барои ислоҳи хато ва баъзан омӯзиш муфид аст. Масалан, дар бисёр муҳитҳои Atari шумораи ҷонҳои боқимондаро дорад. Дар CartPole бошад холист:
>>> obs, info = env.reset(seed=42)
>>> obs
array([ 0.0273956 , -0.00611216, 0.03585979, 0.0197368 ], dtype=float32)
>>> info
{}
Бо render() муҳитро ба тасвир табдил медиҳем. Азбаски ҳангоми сохтан render_mode="rgb_array" гузоштем, тасвир ҳамчун массиви NumPy бармегардад. Онро бо imshow()-и Matplotlib нишон додан мумкин аст:
>>> img = env.render()
>>> img.shape # height, width, channels (3 = Red, Green, Blue)
(400, 600, 3)
Акнун мепурсем, ки кадом амалҳо имкон доранд:
>>> env.action_space
Discrete(2)
Discrete(2) маънои онро дорад, ки амалҳо ададҳои бутуни 0 ва 1 мебошанд: суръат додан ба чап ё рост. Муҳитҳои дигар метавонанд амалҳои дискретии бештар ё амалҳои навъи дигар, масалан пайваста дошта бошанд. Азбаски чӯб ба рост моил аст (obs[2] > 0), аробаро ба рост суръат медиҳем:
>>> action = 1 # accelerate right
>>> obs, reward, done, truncated, info = env.step(action)
>>> obs
array([ 0.02727336, 0.18847767, 0.03625453, -0.26141977], dtype=float32)
>>> reward, done, truncated, info
(1.0, False, False, {})
Методи step() амали дархостшударо иҷро карда, панҷ қимат бармегардонад:
obs— мушоҳидаи нав. Ароба ҳоло ба рост меравад (obs[1] > 0). Чӯб ҳамоно ба рост моил аст (obs[2] > 0), вале суръати кунҷиаш манфӣ шудааст (obs[3] < 0), пас эҳтимол баъди қадами оянда ба чап моил мешавад.reward— дар ин муҳит дар ҳар қадам, новобаста аз амал, мукофоти1.0мегиред. Ҳадаф ҳарчи дарозтар давом додани эпизод аст. Эпизод як даври кори муҳит то анҷом ё қатъ шудани бозӣ мебошад.done— вақте эпизод анҷом ёбад,Trueмешавад: масалан чӯб аз ҳад зиёд моил гардад ё ароба аз экран берун равад. Пеш аз истифодаи минбаъда муҳитро боз оғоз кардан лозим аст.truncated— агар эпизод пеш аз анҷоми табиӣ қатъ шавад,Trueмешавад. Одатан ин корро печонандаи муҳит анҷом медиҳад, ки шумораи қадамҳои эпизодро маҳдуд мекунад. Тафсилот дар ҳуҷҷатҳои Gymnasium оварда шудааст. Барои CartPole маҳдудияти пешфарз 500 қадам аст, вале мо онро ба 1000 иваз кардем. Ҳарду нишондиҳанда эпизодро тамом мекунанд, вале маънояшон фарқ дорад: баъдиdoneояндае нест, аммо баъдиtruncatedбозӣ метавонист давом ёбад. Аз ин рӯ, ҳангоми ҳисоби ҳадафҳо дар алгоритмҳои минбаъдаи ин боб арзиши ояндаро танҳо дар ҳолатиdoneсифр мекунем.info— луғати маълумоти иловагии хоси муҳит, монанди қимати баргардондаиreset().
Маслиҳат. Пас аз анҷоми кор бо муҳит, ҳатто агар эпизодҳои бисёрро иҷро карда бошед,
close()-ро даъват кунед, то захираҳо озод шаванд.
Сиёсати содаеро бевосита дар код менависем: агар чӯб ба чап моил бошад, ароба ба чап ва агар ба рост моил бошад, ба рост суръат гирад. Онро дар 500 эпизод иҷро карда, мукофоти миёнаро месанҷем:
def basic_policy(obs):
angle = obs[2]
return 0 if angle < 0 else 1 # go left if leaning left, otherwise go right
totals = []
for episode in range(500):
total_rewards = 0
obs, info = env.reset(seed=episode)
while True: # no risk of infinite loop: will be truncated after 1000 steps
action = basic_policy(obs)
obs, reward, done, truncated, info = env.step(action)
total_rewards += reward
if done or truncated:
break
totals.append(total_rewards)
Код равшан аст. Ба натиҷа нигарем:
>>> import numpy as np
>>> np.mean(totals), np.std(totals), min(totals), max(totals)
(np.float64(41.698), np.float64(8.389445512070509), 24.0, 63.0)
Ҳатто дар 500 кӯшиш ин сиёсат чӯбро бештар аз 63 қадами пайдарпай рост нигоҳ дошта натавонист. Натиҷа хуб нест. Дар симулятсияи дафтари ин боб мебинед, ки ароба ба чапу рост торафт сахттар меларзад, то чӯб аз ҳад зиёд моил шавад. Шабакаи нейронӣ беҳтар амал карда метавонад!
Сиёсатҳои шабакаи нейронӣ
Шабакаи нейроние месозем, ки мисли сиёсати пешина мушоҳидаро қабул карда, амалро интихоб мекунад. Дақиқтараш, он эҳтимоли ҳар амалро ҳисоб мекунад ва аз рӯйи ҳамин эҳтимолҳо амалеро тасодуфан интихоб менамояд (расми 19.5). Дар CartPole танҳо ду амал ҳаст: чап ё рост. Пас як нейрони баромад кофист. Он эҳтимоли p-и амали 1, яъне ростро медиҳад; эҳтимоли амали 0, яъне чап, 1−p мешавад. Масалан, агар баромад 0.7 бошад, амали 1 бо эҳтимоли 70% ва амали 0 бо эҳтимоли 30% интихоб мешавад. Ин тақсимоти Бернулли бо p=0.7 мебошад.

Расми 19.5. Сиёсати шабакаи нейронӣ.
Чаро амалро тасодуфан аз рӯйи эҳтимолҳо интихоб мекунем, на ҳамеша амали дорои холи баландтаринро? Ин ба агент имкон медиҳад, ки байни таҳқиқи амалҳои нав ва истифодаи амалҳои аллакай муваффақ тавозун ёбад. Тасаввур кунед, бори аввал ба тарабхона рафтед ва ҳамаи таомҳо ҷолибанд. Якеро тасодуфан интихоб мекунед. Агар хуб бошад, эҳтимоли бори дигар фармудани онро зиёд карда метавонед. Аммо набояд ин эҳтимолро ба 100% расонед, вагарна таомҳои дигарро, ки шояд беҳтар бошанд, ҳеҷ гоҳ намесанҷед. Ин душвории интихоби таҳқиқ ё истифода дар омӯзиши тақвиятӣ нақши асосӣ дорад.
Дар ин муҳит амалҳо ва мушоҳидаҳои гузаштаро сарфи назар кардан мумкин аст, зеро ҳар мушоҳида ҳолати пурраи муҳитро дорад. Агар қисми ҳолат пинҳон мебуд, эҳтимол гузаштаро ҳам ба назар гирифтан лозим мешуд. Масалан, агар муҳит танҳо мавқеи аробаро нишон диҳад, на суръаташро, барои ҳисоб кардани суръат ҳам мушоҳидаи ҷорӣ ва ҳам пешина зарур аст. Агар мушоҳидаҳо ғавғо дошта бошанд, одатан чанд мушоҳидаи охиринро барои муайян кардани ҳолати эҳтимолии ҷорӣ истифода мебаранд. Пас, CartPole то ҳадди имкон сода аст: мушоҳидаҳо беғавғо буда, тамоми ҳолати муҳитро дар бар мегиранд.
Бо PyTorch сиёсати одии шабакаи нейрониро барои CartPole месозем:
import torch
import torch.nn as nn
class PolicyNetwork(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(nn.Linear(4, 5), nn.ReLU(), nn.Linear(5, 1))
def forward(self, state):
return self.net(state)
Сиёсат як MLP-и бисёр хурд аст, зеро вазифа осон мебошад. Шумораи вурудҳо ба андозаи ҳолати муҳит баробар аст: дар CartPole ин андозаи як мушоҳида, яъне чор мебошад. Танҳо як қабати пинҳонӣ бо панҷ воҳид дорем; дар ин ҳолат бештар лозим нест. Барои як эҳтимол як нейрони баромад мегузорем. Агар амалҳои имконпазир аз ду зиёд мебуданд, барои ҳар амал як нейрони баромад лозим мешуд. Барои суръат ва устувории ададӣ дар охир сигмоид намегузорем, бинобар ин шабака логит медиҳад, на эҳтимоли тайёр.
Функсияе муайян мекунем, ки аз рӯйи ин шабака амал интихоб кунад:
def choose_action(model, obs):
state = torch.as_tensor(obs)
logit = model(state)
dist = torch.distributions.Bernoulli(logits=logit)
action = dist.sample()
log_prob = dist.log_prob(action)
return int(action.item()), log_prob
Функсия як мушоҳидаро ба тензор табдил медиҳад ва ба шабака дода, логити амали 1-ро мегирад. Бо ин логит тақсимоти Бернулли месозад ва аз он амал интихоб мекунад: амали 1 бо эҳтимоли p=exp(logit)/(1+exp(logit)) ва амали 0 бо эҳтимоли 1−p интихоб мешавад. Барои зиёда аз ду амал тақсимоти Categorical истифода мешавад. Ниҳоят логарифми эҳтимоли амали интихобшуда, яъне log(p) ё log(1−p), ҳисоб мегардад. Он барои омӯзиш лозим мешавад.
Маслиҳат. Агар фазои амалҳо пайваста бошад, ба ҷойи тақсимоти Бернулли ё категориявӣ тақсимоти Гауссро истифода бурдан мумкин аст. Шабака бояд миёна ва инҳирофи стандартӣ ё логарифми инҳирофи стандартиро пешгӯӣ кунад. Логарифми инҳирофи стандартиро аксаран маҳдуд мекунанд, то тақсимот аз ҳад паҳн ё танг нашавад.
Ҳоло сиёсате дорем, ки ҳолати муҳитро — дар ин ҷо як мушоҳидаро — қабул карда, амал интихоб мекунад. Онро чӣ гуна омӯзонем?
Арзёбии амалҳо: масъалаи нисбат додани саҳм
Агар амали беҳтарини ҳар қадамро медонистем, шабакаро бо кам кардани энтропияи салибӣ байни тақсимоти эҳтимолҳои пешгӯишуда ва ҳадафӣ ба таври маъмулӣ омӯзонида метавонистем. Ин омӯзиши одии боназорат мешуд. Аммо дар RL агент танҳо тавассути мукофотҳо роҳнамоӣ мешавад ва онҳо одатан камёбу деррас мебошанд. Агар агент чӯбро 100 қадам дар мувозинат нигоҳ дорад, аз куҷо донад, ки кадоме аз 100 амалаш хуб ва кадоме бад буд? Танҳо медонад, ки чӯб пас аз амали охирин афтод, вале тамоми масъулият бар дӯши ин амал нест. Ин масъалаи нисбат додани саҳм (credit assignment problem) ном дорад: ҳангоми гирифтани мукофот ё ҷазо муайян кардани амалҳои сазовор ё гунаҳкор душвор аст. Сагеро тасаввур кунед, ки чанд соат баъди рафтори хуб мукофот мегирад: оё мефаҳмад барои чӣ?
Барои осон кардани масъала, одатан амалро аз рӯйи ҷамъи ҳамаи мукофотҳои баъдӣ арзёбӣ мекунанд ва дар ҳар қадам коэффисиенти тахфиф γ (гамма)-ро татбиқ менамоянд. Ин ҷамъи мукофотҳои тахфифшуда боздеҳи амал (return) ном дорад. Дар расми 19.6 агент се бор пайдарпай ба рост меравад ва баъди қадамҳои якум, дуюм ва сеюм мутаносибан +10, 0 ва −50 мегирад. Агар γ=0.8 бошад, боздеҳи амали якум чунин аст:
10 + γ × 0 + γ² × (−50) = −22.

Расми 19.6. Ҳисоб кардани боздеҳи амал: ҷамъи мукофотҳои ояндаи тахфифшуда.
Функсияи зерин аз мукофотҳо ва коэффисиенти тахфиф боздеҳҳоро ҳисоб мекунад:
def compute_returns(rewards, discount_factor):
returns = rewards[:] # copy the rewards
for step in range(len(returns) - 1, 0, -1):
returns[step - 1] += returns[step] * discount_factor
return torch.tensor(returns)
Натиҷа ҳамон аст, ки интизор будем:
>>> compute_returns([10, 0, -50], discount_factor=0.8)
tensor([-22., -40., -50.])
Агар коэффисиенти тахфиф ба 0 наздик бошад, мукофотҳои оянда нисбат ба мукофоти фаврӣ аҳаммияти кам доранд. Агар ба 1 наздик бошад, ҳатто мукофотҳои ояндаи дур тақрибан ба қадри мукофоти фаврӣ муҳиманд. Қиматҳои маъмулӣ аз 0.9 то 0.99 мебошанд. Бо коэффисиенти 0.95 мукофоти баъди 13 қадам тақрибан нисфи арзиши мукофоти фавриро дорад, зеро 0.95¹³≈0.5. Бо коэффисиенти 0.99 ин фосила 69 қадам мешавад. Дар CartPole таъсири амалҳо нисбатан кӯтоҳмуддат аст, пас қимати 0.95 оқилона менамояд: нисбат додани саҳмро осон карда, омӯзишро тезтару устувортар мекунад. Аммо агар он хеле хурд бошад, агент аз ҳад ба фоидаи кӯтоҳмуддат диққат дода, стратегияи ғайрибеҳтаринро меомӯзад.
Акнун усули арзёбии ҳар амалро дорем ва метавонем агенти аввалро бо градиентҳои сиёсат омӯзонем.
Ҳалли CartPole бо градиентҳои сиёсат
Алгоритмҳои PG параметрҳои сиёсатро аз рӯйи градиентҳо дар самти мукофотҳои бештар беҳина мекунанд. Алгоритми машҳури REINFORCE, ё Monte Carlo PG, соли 1992 аз ҷониби Роналд Уилямс пешниҳод шудааст. Он вариантҳои бисёр дорад, вале принсипи умумӣ чунин аст:
- Бигзор шабакаи сиёсат як эпизод бозӣ кунад. Мукофотҳо ва логарифмҳои эҳтимолҳои ҳисобшударо сабт мекунем.
- Бо функсияи бахши пешина боздеҳи ҳар амалро ҳисоб мекунем.
- Боздеҳи мусбат нишон медиҳад, ки амал эҳтимол хуб буд, пас эҳтимоли интихоби онро зиёд кардан мехоҳем. Барои боздеҳи манфӣ баръакс амал мекунем. Бо кам кардани талафоти REINFORCE дар муодилаи 19.1 мукофоти интизории тахфифшударо зиёд мекунем.
Муодилаи 19.1. Талафоти REINFORCE.
ℒ(θ) = −Σₜ Gₜ log π_θ(aₜ | sₜ)
Дар ин ҷо π_θ(aₜ|sₜ) эҳтимоли пешгӯишудаи амали aₜ дар ҳолати sₜ, t қадами вақт, Gₜ боздеҳи мушоҳидашудаи ин амал (ҷамъи мукофотҳои тахфифшудаи баъди он, на мукофоти фаврӣ) ва θ параметрҳои модел мебошанд.
Аввал функсияе месозем, ки ба шабака имкон диҳад як эпизод бозӣ карда, мукофотҳо ва логарифмҳои эҳтимолҳоро сабт кунад:
def run_episode(model, env, seed=None):
log_probs, rewards = [], []
obs, info = env.reset(seed=seed)
while True: # the environment will truncate the episode if it is too long
action, log_prob = choose_action(model, obs)
obs, reward, done, truncated, _info = env.step(action)
log_probs.append(log_prob)
rewards.append(reward)
if done or truncated:
return log_probs, rewards
Функсия муҳитро барои эпизоди нав аз нав оғоз мекунад. Барои такроршавии натиҷа seed-ро ба reset() медиҳад. Сипас даври бозӣ оғоз мешавад: дар ҳар такрор ҳолати ҷорӣ, яъне мушоҳидаи охиринро ба choose_action() медиҳем ва амал бо логарифми эҳтимолашро мегирем. Бо step() амалро иҷро мекунем. Ин мушоҳидаи нав — массиви NumPy, мукофот, ду қимати булӣ барои анҷом ё қатъи бозӣ ва луғати иттилоотро медиҳад. Дар CartPole луғатро сарфи назар кардан мумкин аст. Эҳтимолҳои логарифмӣ ва мукофотҳоро дар ду рӯйхат нигоҳ дошта, пас аз эпизод бармегардонем.
Акнун функсияи омӯзишро менависем:
def train_reinforce(model, optimizer, env, n_episodes, discount_factor):
for episode in range(n_episodes):
seed = torch.randint(0, 2**32, size=()).item()
log_probs, rewards = run_episode(model, env, seed=seed)
returns = compute_returns(rewards, discount_factor)
std_returns = (returns - returns.mean()) / (returns.std() + 1e-7)
losses = [-logp * rt for logp, rt in zip(log_probs, std_returns)]
loss = torch.cat(losses).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"\rEpisode {episode + 1}, Reward: {sum(rewards):.2f}", end=" ")
Код кӯтоҳ аст: дар ҳар такрори омӯзиш эпизод иҷро шуда, логарифмҳои эҳтимолҳо ва мукофотҳо гирифта мешаванд. Сипас боздеҳи ҳар амал ҳисоб ва стандартӣ карда мешавад: миёна кам шуда, натиҷа ба инҳирофи стандартӣ бо адади хурд барои пешгирии тақсим ба сифр тақсим мешавад. Стандартӣ кардан ҳатмӣ нест, вале тағйироти маъмулу тавсияшавандаи REINFORCE буда, омӯзишро устувор мекунад. Баъд талафоти муодилаи 19.1 ҳисоб шуда, барои кам кардани он як қадами беҳинасоз иҷро мешавад.
Ҳоло шабакаро сохта, омӯзонида метавонем:
torch.manual_seed(42)
model = PolicyNetwork()
optimizer = torch.optim.NAdam(model.parameters(), lr=0.06)
train_reinforce(model, optimizer, env, n_episodes=200, discount_factor=0.95)
Омӯзиш камтар аз як дақиқа мегирад. Агар бо ин шабака эпизод иҷро кунед, мебинед, ки чӯбро хеле хуб дар мувозинат нигоҳ медорад. Муваффақ шудем!
Алгоритми содаи градиенти сиёсат CartPole-ро ҳал кард, вале ба вазифаҳои калонтару мураккабтар хуб миқёс намегирад. Он самаранокии пасти истифодаи намунаҳо дорад: пеш аз пешрафти назаррас бояд муддати дароз бозиро таҳқиқ кунад. Сабаб ин аст, ки баҳодиҳии боздеҳ бисёр ғавғонок мебошад, хусусан вақте амалҳои хубу бад омехтаанд. Бо вуҷуди ин, он пояи алгоритмҳои пурқувваттар, монанди актёр–мунаққид аст, ки охири боб мебинем.
Маслиҳат. Муҳаққиқон алгоритмҳоеро меҷӯянд, ки ҳатто бе дониши ибтидоии агент хуб кор кунанд. Аммо агар мақолаи илмӣ нанависед, аз додани дониши пешакӣ ба агент худдорӣ накунед: омӯзишро хеле тез мекунад. Масалан, медонед, ки чӯб бояд амудӣ бошад; метавонед ҷазои ба кунҷи он мутаносиб илова кунед. Мукофотҳо камтар камёб шуда, омӯзиш тезтар мешавад. Агар сиёсати нисбатан хуби пешакӣ навишташуда дошта бошед, аввал шабакаро ба тақлиди он омӯзонед ва баъд бо PG беҳтар созед.
REINFORCE ҳамчунин ноустувор аст: агент чанде беҳтар мешавад, баъд ҳама чизро фалокатбор фаромӯш мекунад, боз меомӯзад ва боз фаромӯш мекунад. Сабаби муҳим он аст, ки намунаҳои омӯзиш мустақил ва яксон тақсимшуда (IID) нестанд. Онҳо аз ҳолатҳое иборатанд, ки агент дар ҳамин лаҳза ба онҳо расида метавонад. Ҳангоми беҳтар шудан қисмҳои дигари муҳитро таҳқиқ мекунад ва қисмҳои пешинаро фаромӯш карда метавонад. Масалан, пас аз омӯхтани рост нигоҳ доштани чӯб дигар чӯби моилро намебинад ва кор бо онро фаромӯш мекунад. Дар муҳитҳои мураккаб ин мушкил хеле сахттар мешавад.
Эзоҳ. RL ба душвор буданаш машҳур аст, асосан аз сабаби ноустувории омӯзиш ва ҳассосияти зиёд ба гиперпараметрҳою тухмҳои тасодуфӣ. Ба гуфтаи муҳаққиқ Андрей Карпати, омӯзиши боназорат «мехоҳад кор кунад», вале RL-ро «бояд маҷбур кард, ки кор кунад». Вақт, сабр, устуворӣ ва шояд каме бахт лозим аст. Ин яке аз сабабҳои асосист, ки RL ба андозаи омӯзиши амиқи маъмулӣ паҳн нашудааст.
Акнун ба оилаи дигари машҳур — усулҳои ба арзиш асосёфта — мегузарем.
Усулҳои ба арзиш асосёфта
Алгоритмҳои PG бевосита сиёсатро барои зиёд кардани мукофот беҳина мекунанд. Усулҳои ба арзиш асосёфта ғайримустақимтаранд: агент арзиши ҳар ҳолат, яъне боздеҳи интизорӣ, ё арзиши ҳар амалро дар ҳолати додашуда баҳогузорӣ кардан меомӯзад ва баъд аз ин дониш барои интихоби амал истифода мекунад. Барои фаҳмидани онҳо аввал равандҳои қабули қарори Марков (MDP)-ро бояд баррасӣ кард.
Равандҳои қабули қарори Марков
Дар аввали асри XX математик Андрей Марков равандҳои стохастикии беҳофизаро таҳқиқ кард, ки занҷирҳои Марков ном доранд. Чунин раванд шумораи муайяни ҳолатҳо дорад ва дар ҳар қадам тасодуфан аз як ҳолат ба ҳолати дигар мегузарад. Эҳтимоли гузариш аз s ба s' собит буда, танҳо ба ҷуфти (s,s') вобаста аст, на ба ҳолатҳои гузашта. Аз ин рӯ мегӯянд, ки система ҳофиза надорад.
Дар расми 19.7 намунаи занҷири Марков бо чор ҳолат нишон дода шудааст.

Расми 19.7. Намунаи занҷири Марков.
Фарз мекунем, раванд аз ҳолати s₀ сар мешавад ва дар қадами оянда бо эҳтимоли 70% дар ҳамон ҷо мемонад. Дар ниҳоят ин ҳолатро тарк карда, дигар барнамегардад, зеро аз ягон ҳолати дигар гузарише ба s₀ нест. Агар ба s₁ гузарад, бо эҳтимоли 90% ба s₂ меравад ва баъд ҳатман, яъне бо эҳтимоли 100%, ба s₁ бармегардад. Мумкин аст чанд бор байни ин ду ҳолат гузарад, вале ниҳоят ба s₃ меафтад ва дар он абадан мемонад, зеро роҳи баромад нест. Ин ҳолати ниҳоӣ ном дорад. Динамикаи занҷирҳои Марков метавонад бисёр гуногун бошад; онҳо дар термодинамика, химия, омор ва соҳаҳои дигар васеъ истифода мешаванд.
Равандҳои қабули қарори Марковро Ричард Беллман дар солҳои 1950 тавсиф кард. Онҳо ба занҷирҳои Марков монанданд, вале фарқ доранд: дар ҳар қадам агент метавонад яке аз чанд амалро интихоб кунад ва эҳтимоли гузариш аз амали интихобшуда вобаста аст. Ҳамчунин баъзе гузаришҳо мукофоти мусбат ё манфӣ медиҳанд. Ҳадафи агент ёфтани сиёсатест, ки мукофоти ҷамъшударо дар тӯли вақт ба ҳадди аксар расонад.
Масалан, MDP-и расми 19.8 се ҳолат дорад, ки бо доираҳо нишон дода шудаанд, ва дар ҳар қадам то се амали дискретӣ имконпазир аст, ки бо ромбҳо ифода шудаанд.

Расми 19.8. Намунаи раванди қабули қарори Марков.
Агар агент аз s₀ оғоз кунад, метавонад a₀, a₁ ё a₂-ро интихоб намояд. Амали a₁ ӯро бе ягон мукофот ҳатман дар s₀ нигоҳ медорад. Пас, агар хоҳад, абадан он ҷо монда метавонад. Агар a₀-ро интихоб кунад, бо эҳтимоли 70% мукофоти +10 гирифта, дар s₀ мемонад. Инро такрор карда, мукофот ҷамъ мекунад, вале дар ягон лаҳза ба s₁ мегузарад. Дар s₁ танҳо a₀ ё a₂ имкон доранд. Бо такрори a₀ метавонад дар ҷой монад ё бо a₂ ба s₂ гузашта, мукофоти манфии −50 гирад. Дар s₂ танҳо a₁ дастрас аст: он эҳтимолан агентро ба s₀ баргардонда, мукофоти +40 медиҳад.
Аз рӯйи ин MDP гуфта метавонед, ки кадом стратегия дар тӯли вақт мукофоти бештар мегирад? Дар s₀ амали a₀ равшан беҳтарин аст, дар s₂ бошад танҳо a₁ вуҷуд дорад. Аммо дар s₁ маълум нест, ки дар ҷой мондан бо a₀ беҳтар аст ё бо a₂ «аз оташ гузаштан».
Беллман усули баҳодиҳии арзиши беҳтарини ҳолат-ро ёфт, ки V*(s) ишора мешавад. Ин ҷамъи мукофотҳои ояндаи тахфифшудаест, ки агент ба ҳисоби миёна аз ҳолати s интизор мешавад, бо шарти он ки минбаъд беҳтарин амалҳоро иҷро мекунад. Ӯ нишон дод, ки барои агенти беҳтарин амалкунанда муодилаи оптималии Беллман дуруст аст (муодилаи 19.2). Ин муодилаи рекурсивӣ мегӯяд: арзиши беҳтарини ҳолати ҷорӣ ба мукофоти миёнаи баъди як амали беҳтарин ва арзиши беҳтарини интизории ҳолатҳои минбаъдаи имконпазир баробар мебошад, бо дарназардошти тахфиф.
Муодилаи 19.2. Муодилаи оптималии Беллман.
V*(s) = maxₐ Σ_(s′) T(s, a, s′) [R(s, a, s′) + γ · V*(s′)] барои ҳамаи s
Дар ин муодила:
- T(s,a,s') эҳтимоли гузариш аз s ба s' баъди интихоби a мебошад. Масалан, дар расми 19.8, T(s₂,a₁,s₀)=0.8.
- R(s,a,s') мукофотест, ки агент ҳангоми гузаштан аз s ба s' бо интихоби a мегирад. Масалан, R(s₂,a₁,s₀)=+40.
- γ коэффисиенти тахфиф мебошад.
Эзоҳ. Дар муодилаи Беллман ва давоми боб сиёсати беҳтарин ҷамъи интизории мукофотҳои ояндаи тахфифшуда-ро зиёд мекунад, бинобар ин ба γ вобаста аст. Дар вазифаҳои воқеӣ бештар ба ҷамъи интизории мукофотҳои ҳар эпизод бе тахфиф таваҷҷуҳ дорем; агентҳоро ҳам одатан ҳамин тавр арзёбӣ мекунем. Барои наздик шудан ба ин ҳадаф γ-ро ба 1 наздик мегирем, вале на аз ҳад наздик, вагарна омӯзиш сусту ноустувор мешавад.
Аз ин муодила бевосита алгоритми баҳодиҳии арзиши беҳтарини ҳар ҳолат ҳосил мешавад: аввал ҳамаи арзишҳоро сифр мекунем, сипас бо алгоритми итератсияи арзиш такроран нав мекунем (муодилаи 19.3). Натиҷаи муҳим ин аст, ки бо вақти кофӣ ин баҳодиҳиҳо ҳатман ба арзишҳои беҳтарини мувофиқи сиёсати оптималӣ наздик мешаванд.
Муодилаи 19.3. Алгоритми итератсияи арзиш.
Vₖ₊₁(s) ← maxₐ Σ_(s′) T(s, a, s′) [R(s, a, s′) + γ · Vₖ(s′)] барои ҳамаи s
Vₖ(s) арзиши баҳогузоришудаи ҳолати s дар итератсияи k-ум мебошад.
Эзоҳ. Ин намунаи барномасозии динамикӣ аст: масъалаи мураккаб ба зермасъалаҳои ҳалшаванда тақсим мешавад, ки онҳоро такроран ҳал кардан мумкин аст.
Донистани арзишҳои беҳтарини ҳолат барои арзёбии сиёсат муфид аст, вале худаш сиёсати беҳтаринро намедиҳад. Беллман алгоритми бисёр монандеро барои баҳодиҳии арзишҳои ҳолат–амал, ки одатан Q-арзишҳо ё арзишҳои сифат ном доранд, ёфт. Q-арзиши беҳтарини ҷуфти (s,a) бо Q*(s,a) ишора мешавад: ҷамъи миёнаи мукофотҳои ояндаи тахфифшуда аз ҳолати s, агар агент a-ро интихоб кунад, пеш аз маълум шудани натиҷаи амал, бо шарти он ки баъди он беҳтарин рафторро пеш мегирад.
Боз аввал ҳамаи Q-арзишҳоро сифр карда, бо алгоритми итератсияи Q-арзиш нав мекунем (муодилаи 19.4).
Муодилаи 19.4. Алгоритми итератсияи Q-арзиш.
Qₖ₊₁(s, a) ← Σ_(s′) T(s, a, s′) [R(s, a, s′) + γ · max_(a′) Qₖ(s′, a′)] барои ҳамаи (s, a)
Пас аз гирифтани Q-арзишҳои беҳтарин муайян кардани сиёсати беҳтарини π*(s) осон аст: дар ҳолати s амали дорои Q-арзиши баландтаринро интихоб мекунем:
π*(s) = argmaxₐ Q*(s, a)
Алгоритмро ба MDP-и расми 19.8 татбиқ мекунем. Аввал онро муайян месозем:
transition_probabilities = [ # shape=[s, a, s']
[[0.7, 0.3, 0.0], [1.0, 0.0, 0.0], [0.8, 0.2, 0.0]],
[[0.0, 1.0, 0.0], None, [0.0, 0.0, 1.0]],
[None, [0.8, 0.1, 0.1], None]
]
rewards = [ # shape=[s, a, s']
[[+10, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, -50]],
[[0, 0, 0], [+40, 0, 0], [0, 0, 0]]
]
possible_actions = [[0, 1, 2], [0, 2], [1]]
Масалан, барои эҳтимоли гузариш аз s₂ ба s₀ баъди a₁ ба transition_probabilities[2][1][0] менигарем: 0.8. Мукофоти мувофиқ rewards[2][1][0], яъне +40 аст. Рӯйхати амалҳои имконпазир дар s₂ дар possible_actions[2] ҷойгир аст: танҳо a₁. Акнун Q-арзишҳои амалҳои имконпазирро сифр ва амалҳои номумкинро −∞ мегузорем:
Q_values = np.full((3, 3), -np.inf) # -np.inf for impossible actions
for state, actions in enumerate(possible_actions):
Q_values[state, actions] = 0.0 # for all possible actions
Алгоритм муодилаи 19.4-ро такроран ба ҳар Q-арзиши ҳар ҳолату амали имконпазир татбиқ мекунад:
gamma = 0.90 # the discount factor
for iteration in range(50):
Q_prev = Q_values.copy()
for s in range(3):
for a in possible_actions[s]:
Q_values[s, a] = np.sum([
transition_probabilities[s][a][sp]
* (rewards[s][a][sp] + gamma * Q_prev[sp].max())
for sp in range(3)])
Натиҷа:
>>> Q_values
array([[18.91891892, 17.02702702, 13.62162162],
[ 0. , -inf, -4.87971488],
[ -inf, 50.13365013, -inf]])
Масалан, агар агент дар s₀ амали a₁-ро интихоб кунад, ҷамъи интизории мукофотҳои ояндаи тахфифшуда тақрибан 17.0 аст.
Барои ҳар ҳолат амали дорои Q-арзиши баландтаринро меёбем:
>>> Q_values.argmax(axis=1) # optimal action for each state
array([0, 0, 1])
Бо γ=0.90 сиёсати беҳтарин чунин аст: дар s₀ амали a₀, дар s₁ низ a₀, яъне дар ҷой мондан, ва дар s₂ амали ягонаи a₁-ро интихоб мекунем. Ҷолиб аст, ки бо баланд кардани γ то 0.95 сиёсат дигар мешавад: дар s₁ амали беҳтарин a₂, яъне «аз оташ гузаштан» мегардад. Ин мантиқӣ аст: ҳар қадар ояндаро бештар қадр кунед, ҳамон қадар ба ранҷи ҳозира барои хушии оянда омода мешавед.
Омӯзиши фарқи замонӣ
Масъалаҳои RL бо амалҳои дискретиро аксаран ҳамчун MDP модел кардан мумкин аст. Вале агент дар оғоз на эҳтимолҳои гузариши T(s,a,s')-ро медонад ва на мукофотҳои R(s,a,s')-ро. Барои донистани мукофотҳо ҳар ҳолату гузаришро бояд ҳадди ақал як бор таҷриба кунад. Барои баҳодиҳии нисбатан дурусти эҳтимолҳои гузариш бошад, таҷрибаҳои бисёр лозиманд.
Алгоритми омӯзиши фарқи замонӣ (temporal difference, TD) ба итератсияи Q-арзиш монанд аст, вале дониши нопурраи агентро ба назар мегирад. Одатан фарз мекунем, ки агент дар оғоз танҳо ҳолатҳо ва амалҳои имконпазирро медонад. Бо сиёсати таҳқиқӣ, масалан сиёсати пурра тасодуфӣ, муҳитро таҳқиқ мекунад ва TD арзишҳои ҳолатҳоро аз рӯйи гузаришу мукофотҳои воқеан мушоҳидашуда нав мекунад (муодилаи 19.5).
Муодилаи 19.5. Алгоритми омӯзиши TD.
Vₖ₊₁(s) ← (1 − α) · Vₖ(s) + α · (r + γ · Vₖ(s′))
ё Vₖ₊₁(s) ← Vₖ(s) + α · δₖ(s, r, s′),
ки дар он δₖ(s, r, s′) = r + γ · Vₖ(s′) − Vₖ(s)
Дар он:
- α суръати омӯзиш, масалан 0.01 аст.
- r+γVₖ(s') ҳадафи TD ном дорад.
- δₖ(s,r,s') хатои TD ном дорад.
Сатри якуми муодиларо кӯтоҳтар бо аломати a ←_α b менависанд, ки маънояш aₖ₊₁←(1−α)aₖ+αbₖ аст. Пас сатри якуми муодилаи 19.5 чунин мешавад: V(s) ←_α r+γV(s'). Ҳамин аломатро дар муодилаҳои 19.6 ва 19.7 низ истифода мебарем.
Маслиҳат. TD ба поёнравии градиенти стохастикӣ, аз ҷумла ба коркарди як намуна дар як вақт, монанд аст. Мисли SGD, барои ҳамгароии воқеӣ суръати омӯзишро бояд тадриҷан кам кард; вагарна баҳодиҳиҳо гирди қиматҳои беҳтарин ҷунбидан мегиранд.
Барои ҳар ҳолати s алгоритм миёнаи ҷории мукофоти фаврии агент ҳангоми баромадан аз ин ҳолат ва мукофотҳои интизории минбаъдаро нигоҳ медорад. Мукофотҳои минбаъда аз рӯйи рафтори воқеии агент баҳогузорӣ мешаванд, на рафтори беҳтарин: TD арзишҳои ҳолатро барои ҳамон сиёсате меомӯзад, ки агент ҳоло пайравӣ мекунад (V^π). Барои ёфтани сиёсати беҳтарин алгоритми навбатӣ, Q-learning, лозим аст.
Q-learning
Ба ҳамин монанд, Q-learning мутобиқсозии итератсияи Q-арзиш ба ҳолатест, ки эҳтимолҳои гузариш ва мукофотҳо дар оғоз номаълуманд (муодилаи 19.6). Алгоритм бозии агентро, ҳатто агар тасодуфӣ амал кунад, мушоҳида намуда, Q-арзишҳоро тадриҷан беҳтар баҳогузорӣ мекунад. Пас аз гирифтани баҳодиҳии кофӣ дақиқ, сиёсати беҳтарин интихоби амали дорои Q-арзиши баландтарин мебошад: сиёсати ҳарисона.
Муодилаи 19.6. Алгоритми Q-learning.
Q(s, a) ←α r + γ · max(a′) Q(s′, a′)
Барои ҳар ҷуфти (s,a) алгоритм миёнаи ҷории мукофоти r ҳангоми аз s бо a баромадан ва ҷамъи мукофотҳои ояндаи тахфифшударо нигоҳ медорад. Барои баҳодиҳии қисми оянда аз Q-арзишҳои ҳолати навбатии s' баландтаринашро мегирем, зеро фарз мекунем сиёсати ҳадафӣ аз он пас беҳтарин рафтор мекунад.
Алгоритмро татбиқ мекунем. Аввал барои таҳқиқи муҳит функсияи step лозим аст, то агент амалро иҷро карда, ҳолат ва мукофоти натиҷавиро гирад:
def step(state, action):
probas = transition_probabilities[state][action]
next_state = np.random.choice([0, 1, 2], p=probas)
reward = rewards[state][action][next_state]
return next_state, reward
Чун фазои ҳолатҳо хурд аст, сиёсати тасодуфии сода кофист. Бо иҷрои тӯлонӣ агент ҳар ҳолатро борҳо дида, ҳар амали имконпазирро борҳо месанҷад:
def exploration_policy(state):
return np.random.choice(possible_actions[state])
Пас аз оғозкунии Q-арзишҳо мисли пешина, Q-learning-ро иҷро мекунем. Дар ин мисол ҷадвали суръати омӯзиши power scheduling истифода мешавад:
alpha0 = 0.05 # initial learning rate
decay = 0.005 # learning rate decay
gamma = 0.90 # discount factor
state = 0 # initial state
for iteration in range(10_000):
action = exploration_policy(state)
next_state, reward = step(state, action)
next_value = Q_values[next_state].max() # greedy policy at the next step
alpha = alpha0 / (1 + iteration * decay)
Q_values[state, action] *= 1 - alpha
Q_values[state, action] += alpha * (reward + gamma * next_value)
state = next_state
Алгоритм ба Q-арзишҳои беҳтарин наздик мешавад, вале итератсияҳои бисёр ва шояд танзими зиёди гиперпараметрҳо лозиманд. Дар расми 19.9 итератсияи Q-арзиш дар тарафи чап дар камтар аз 20 итератсия зуд ҳамгаро мешавад; Q-learning дар тарафи рост тақрибан 8000 итератсия мехоҳад. Нодонистани эҳтимолҳо ва мукофотҳо ёфтани сиёсати беҳтаринро хеле душвортар мекунад!

Расми 19.9. Муқоисаи каҷхатҳои омӯзиши итератсияи Q-арзиш ва Q-learning.
Q-learning алгоритми берун аз сиёсат (off-policy) ном дорад, зеро сиёсати омӯхташаванда ҳатман ҳамон сиёсати ҳангоми омӯзиш иҷрошаванда нест. Дар коди боло сиёсати таҳқиқӣ пурра тасодуфӣ буд, вале сиёсати омӯхташаванда ҳеҷ гоҳ иҷро нашуд. Баъди омӯзиш сиёсати беҳтарин ҳамеша амали Q-арзиши баландтаринро интихоб мекунад. Баръакс, REINFORCE дар доираи сиёсат (on-policy) аст: ҷаҳонро бо ҳамон сиёсати омӯхташаванда таҳқиқ мекунад. Аҷиб аст, ки Q-learning танҳо аз мушоҳидаи агенти тасодуфан амалкунанда сиёсати беҳтаринро омӯхта метавонад. Гӯё голфро аз маймуни чашмбаста омӯзед! Оё беҳтар кардан мумкин аст?
Сиёсатҳои таҳқиқӣ
Q-learning танҳо вақте кор мекунад, ки сиёсат MDP-ро ба қадри кофӣ таҳқиқ намояд. Сиёсати пурра тасодуфӣ дар ниҳоят ҳар ҳолату гузаришро борҳо мебинад, вале ин метавонад бисёр тӯл кашад. Аз ин рӯ, сиёсати ε-ҳарисона беҳтар аст: дар ҳар қадам бо эҳтимоли ε (эпсилон) тасодуфан амал мекунад ва бо эҳтимоли 1−ε амали дорои Q-арзиши баландтаринро мегирад. Бо беҳтар шудани Q-арзишҳо он вақти бештарро ба қисмҳои ҷолиби муҳит ва ҳамзамон каме вақтро ба минтақаҳои номаълум сарф мекунад. Одатан аз ε-и калон, масалан 1.0, оғоз карда, онро тадриҷан то 0.05 кам мекунанд.
Роҳи дигар ин аст, ки танҳо ба тасодуф такя накарда, агентро барои санҷидани амалҳои камтаҷриба ҳавасманд кунем. Барои ин ба Q-арзишҳои баҳогузоришуда подоши иловагӣ медиҳем (муодилаи 19.7).
Муодилаи 19.7. Q-learning бо функсияи таҳқиқ.
Q(s, a) ←α r + γ · max(a′) f(Q(s′, a′), N(s′, a′))
Дар он:
- N(s',a') шумораи интихоби амали a' дар ҳолати s' мебошад.
- f(Q,N) функсияи таҳқиқ аст, масалан f(Q,N)=Q+κ/(1+N). Гиперпараметри кунҷковии κ (каппа) ҷалби агент ба чизҳои номаълумро муайян мекунад.
Q-learning-и тақрибӣ ва амиқ
Мушкили асосии Q-learning ин аст, ки барои MDP-ҳои калон ё ҳатто миёна бо ҳолату амалҳои бисёр хуб миқёс намегирад. Масалан, барои омӯзиши Ms. Pac-Man тақрибан 240 доначаи хӯрданӣ ҳаст, ки ҳар кадом ҳузур дорад ё аллакай хӯрда шудааст. Пас танҳо шумораи ҳолатҳои доначаҳо тақрибан 2²⁴⁰≈10⁷³ аст. Агар ҳамаи таркибҳои мавқеи арвоҳ ва Ms. Pac-Man-ро илова кунем, шумораи ҳолатҳо аз шумораи атомҳои галактикаи мо ҳам зиёд мешавад. Нигоҳ доштани баҳодиҳии ҳар Q-арзиш тамоман номумкин аст.
Роҳи ҳал ёфтани функсияи Q_θ(s,a) аст, ки Q-арзиши ҳар ҷуфти (s,a)-ро тақрибан ҳисоб мекунад. Вектори θ параметрҳои функсияро муайян менамояд. Ин Q-learning-и тақрибӣ ном дорад. Солҳо барои баҳодиҳии Q-арзишҳо таркибҳои хаттии хусусиятҳои дастӣ аз ҳолат гирифташуда — масофаи арвоҳи наздик, самти ҳаракат ва ғайра — тавсия мешуданд. Аммо соли 2013 DeepMind нишон дод, ки шабакаҳои амиқи нейронӣ барои масъалаҳои мураккаб беҳтар кор карда, муҳандисии дастии хусусиятҳоро талаб намекунанд. DNN-и баҳодиҳандаи Q-арзиш шабакаи амиқи Q (DQN) ном дорад; истифодаи он барои Q-learning-и тақрибӣ бошад Q-learning-и амиқ аст.
DQN-ро чӣ гуна омӯзонем? Q-арзиши тақрибии ҷуфти (s,a)-ро баррасӣ мекунем. Аз Беллман медонем, ки он бояд ба мукофоти воқеан баъди амали a дар s гирифташудаи r ва арзиши тахфифшудаи рафтори беҳтарини баъдӣ наздик бошад. Барои баҳодиҳии мукофотҳои оянда DQN-ро дар ҳолати навбатии s' барои ҳамаи амалҳои a' иҷро мекунем. Барои ҳар амал Q-арзиши ояндаи тақрибӣ мегирем. Баландтаринашро интихоб карда, тахфиф медиҳем. Ба он r-ро илова намуда, Q-арзиши ҳадафии y(s,a)-ро месозем (муодилаи 19.8).
Муодилаи 19.8. Q-арзиши ҳадафӣ.
y(s, a) = r + γ · max_(a′) Q_θ(s′, a′)
Бо ин ҳадаф як қадами омӯзишро тавассути ҳар алгоритми поёнравии градиент иҷро кардан мумкин аст. Одатан квадрати фарқи Q_θ(s,a) ва y(s,a) кам карда мешавад. Барои кам кардани ҳассосият ба хатоҳои калон талафоти Ҳубер-ро низ истифода мебаранд. Ин аст алгоритми Q-learning-и амиқ! Акнун онро барои CartPole татбиқ мекунем.
Татбиқи Q-learning-и амиқ
Аввал шабакаи амиқи Q лозим аст. Назариявӣ шабака ҷуфти ҳолат–амалро гирифта, як Q-арзиши тақрибӣ медиҳад. Дар амал самараноктар аст, ки танҳо ҳолатро гирифта, барои ҳар амали имконпазир як Q-арзиш барорад. Барои CartPole ду қабати пинҳонӣ кофист:
class DQN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(nn.Linear(4, 32), nn.ReLU(),
nn.Linear(32, 32), nn.ReLU(),
nn.Linear(32, 2))
def forward(self, state):
return self.net(state)
Ин DQN ба шабакаи сиёсати пешина монанд аст, вале ба ҷойи логит барои ҳар амал Q-арзиш медиҳад. Функсияи интихоби амалро менависем:
def choose_dqn_action(model, obs, epsilon=0.0):
if torch.rand(()) < epsilon: # epsilon greedy policy
return torch.randint(2, size=()).item()
else:
state = torch.as_tensor(obs)
Q_values = model(state)
return Q_values.argmax().item() # optimal according to the DQN
Функсия як мушоҳидаро ба шабака дода, Q-арзишҳоро мегирад ва амали дорои баландтарин қиматро бо argmax() интихоб мекунад. Барои таҳқиқи муҳит сиёсати ε-ҳарисонаро истифода мебарем: бо эҳтимоли ε амал тасодуфӣ мешавад.
Огоҳӣ. DQN одатан бо фазои амалҳои пайваста кор намекунад, магар он ки фазоро дискретӣ карда тавонед — ин танҳо барои фазои бисёр хурд муносиб аст — ё онро бо градиентҳои сиёсат якҷо кунед. Агент бояд дар ҳар қадам амали дорои Q-арзиши баландтаринро ёбад. Дар фазои пайваста ин иҷрои беҳинасозӣ дар ҳар қадамро талаб мекунад, ки амалӣ нест.
Ба ҷойи омӯзиш танҳо аз таҷрибаҳои охирин, ҳамаи таҷрибаҳоро дар буфери бознамоӣ ё ҳофизаи бознамоӣ нигоҳ медорем ва дар ҳар итератсия аз он бастаи тасодуфӣ мегирем. Ин ҳамбастагии таҷрибаҳои дохили бастаро кам ва тақсимоти додаҳоро устувортар карда, омӯзишро ором мекунад. Ҳар таҷриба кортежи шашунсура аст: ҳолати s, амали a, мукофоти r, ҳолати навбатии s', нишондиҳандаи анҷоми эпизод done ва нишондиҳандаи қатъи он truncated. Функсияи гирифтани бастаи тасодуфӣ шаш тензор — барои ҳар майдон якто — бармегардонад:
def sample_experiences(replay_buffer, batch_size):
indices = torch.randint(len(replay_buffer), size=[batch_size])
batch = [replay_buffer[index] for index in indices.tolist()]
return [to_tensor([exp[index] for exp in batch]) for index in range(6)]
def to_tensor(data):
array = np.stack(data)
dtype = torch.float32 if array.dtype == np.float64 else None
return torch.as_tensor(array, dtype=dtype)
sample_experiences() аз буфер шумораи дархостшудаи кортежҳоро тасодуфан мегирад. Баъд барои ҳар яке аз шаш майдон қиматҳои тамоми таҷрибаҳои бастаро ҷудо карда, бо to_tensor() ба тензор табдил медиҳад. Рӯйхати шаш тензор бармегардад. Шакли онҳо [batch size] аст, ба ғайр аз мушоҳидаҳо, ки шакли [batch size, 4] доранд.
to_tensor() рӯйхати Python-и мушоҳидаҳо — массивҳои NumPy-и float32-и шакли [4] — ё амалҳои бутун, мукофотҳои касрӣ ё қиматҳои булӣ, яъне done ва truncated-ро қабул карда, тензори навъи мувофиқи PyTorch месозад. Мукофотҳо ададҳои float-и Python мебошанд ва np.stack() аз онҳо массиви 64-битӣ месозад; чунин массивҳо ба тензорҳои 32-битӣ табдил меёбанд, то навъашон бо параметрҳои модел мувофиқ ояд.
Буфер метавонад ҳар сохтори додае бошад, ки илова кардани унсур, дастрасӣ бо индекс ва маҳдуд кардани андозаро дастгирӣ кунад. Барои содагӣ deque-и бастаи стандартии collections-ро истифода мебарем. Ин навбати дусара аст: аз ҳар ду тараф унсурро зуд илова ё хориҷ кардан мумкин. Агар маҳдудияти андоза пур шавад, илова аз як тараф куҳнатарин унсурро аз тарафи дигар хориҷ мекунад. Пас, ҳар таҷрибаи нав ҷойи таҷрибаи куҳнатаринро мегирад — маҳз ҳамин лозим аст.
Маслиҳат. Иловаю хориҷкунӣ аз канорҳои
dequeзуд аст, вале дастрасии тасодуфӣ дар навбати дароз, масалан аз 100000 унсур боло, суст шуда метавонад. Барои буфери хеле калон буфери даврӣ истифода кунед; татбиқаш дар дафтар ҳаст. Китобхонаи Reverb-и DeepMind низ муносиб аст.
Функсияе месозем, ки бо DQN эпизоди пурра бозӣ карда, таҷрибаҳоро дар буфер сабт намояд. Бо eval ва torch.no_grad() кор мекунем, зеро ҳоло градиент лозим нест. Барои сабти пешрафт ҷамъи мукофотҳои эпизодро ҳам бармегардонем:
def play_and_record_episode(model, env, replay_buffer, epsilon, seed=None):
obs, _info = env.reset(seed=seed)
total_rewards = 0
model.eval()
with torch.no_grad():
while True:
action = choose_dqn_action(model, obs, epsilon)
next_obs, reward, done, truncated, _info = env.step(action)
experience = (obs, action, reward, next_obs, done, truncated)
replay_buffer.append(experience)
total_rewards += reward
if done or truncated:
return total_rewards
obs = next_obs
Функсияи навбатӣ аз буфер як баста гирифта, як қадами поёнравии градиентро иҷро мекунад:
def dqn_training_step(model, optimizer, criterion, replay_buffer, batch_size,
discount_factor):
experiences = sample_experiences(replay_buffer, batch_size)
state, action, reward, next_state, done, truncated = experiences
model.train() # play_and_record_episode() switched it to eval mode
with torch.inference_mode():
next_Q_value = model(next_state)
max_next_Q_value, _ = next_Q_value.max(dim=1)
running = (~done).float() # 0 if s' is terminal; truncation still bootstraps
target_Q_value = reward + running * discount_factor * max_next_Q_value
all_Q_values = model(state)
Q_value = all_Q_values.gather(dim=1, index=action.unsqueeze(1))
loss = criterion(Q_value, target_Q_value.unsqueeze(1))
optimizer.zero_grad()
loss.backward()
optimizer.step()
Маслиҳат.
torch.inference_mode()монандиtorch.no_grad()пайгирии градиентҳоро хомӯш карда, инчунин баъзе хароҷоти иловагиро кам мекунад. Тензорҳои дар он сохташуда барои истифодаи минбаъда дар автоградиент маҳдудият доранд.Эзоҳи тарҷумон. Дар манбаъ гуфта шудааст, ки ин контекст моделро худкор ба
evalмебарад. Ин дуруст нест: барои иваз кардани ҳолати модулҳо, аз ҷумла Dropout ва BatchNorm,model.eval()ваmodel.train()-ро ҷудогона даъват мекунанд. Ин ҷо шарҳ ислоҳ шуд. Баdqn_training_step()model.train()илова шуд, зероplay_and_record_episode()моделро ба ҳолатиevalмебарад; ин DQN Dropout ва BatchNorm надорад, пас натиҷа тағйир намеёбад.
Дар код ин корҳо иҷро мешаванд:
- Аз буфер бастаи таҷрибаҳо интихоб мешавад.
- DQN барои ҳар таҷриба Q-арзиши ҳадафиро аз рӯйи муодилаи 19.8 месозад. Дар ҳолати inference ҳамаи Q-арзишҳои s' ҳисоб мешаванд. Баландтаринашро мегирем, зеро фарз мекунем агент минбаъд беҳтарин амал мекунад, ва ба коэффисиенти тахфиф зарб мекунем. Агар эпизод анҷом ёфта бошад (
done), ин қисм ба сифр зарб мешавад: дигар мукофот интизор нестем. Дар акси ҳол, аз ҷумла вақте эпизод танҳо қатъ шудааст (truncated), ба 1 зарб мешавад. Дар охир мукофоти таҷриба илова мегардад. Ин ҳама барои тамоми баста якбора иҷро мешавад. - Модел барои ҳолати ҷории s ҳамаи Q-арзишҳоро ҳисоб мекунад. Бо
gather()танҳо арзиши амали воқеан интихобшударо ҷудо мекунем. Ин низ якбора барои тамоми баста анҷом мешавад. - Талафот — одатан MSE байни арзишҳои ҳадафӣ ва пешгӯишуда — ҳисоб шуда, қадами беҳинасоз барои кам кардани он иҷро мешавад.
Қисми душвортарин анҷом ёфт! Акнун функсияи асосии омӯзишро навишта, иҷро мекунем:
from collections import deque
def train_dqn(model, env, replay_buffer, optimizer, criterion, n_episodes=800,
warmup=30, batch_size=32, discount_factor=0.95):
totals = []
for episode in range(n_episodes):
epsilon = max(1 - episode / 500, 0.01)
seed = torch.randint(0, 2**32, size=()).item()
total_rewards = play_and_record_episode(model, env, replay_buffer,
epsilon, seed=seed)
print(f"\rEpisode: {episode + 1}, Rewards: {total_rewards}", end=" ")
totals.append(total_rewards)
if episode >= warmup:
dqn_training_step(model, optimizer, criterion, replay_buffer,
batch_size, discount_factor)
return totals
torch.manual_seed(42)
dqn = DQN()
optimizer = torch.optim.NAdam(dqn.parameters(), lr=0.03)
mse = nn.MSELoss()
replay_buffer = deque(maxlen=100_000)
totals = train_dqn(dqn, env, replay_buffer, optimizer, mse)
Омӯзиш 800 эпизод давом мекунад. Дар ҳар итератсия play_and_record_episode() як эпизоди пурра бозӣ мекунад ва баъд dqn_training_step() як қадами омӯзишро иҷро менамояд. Омӯзиш танҳо пас аз чанд эпизоди омодагӣ оғоз мешавад, то дар буфер таҷрибаҳои кофӣ бошанд. ε дар 500 эпизоди аввал хаттӣ аз 1.0 то 0.01 кам шуда, баъд дар 0.01 мемонад. Рафтори агент тадриҷан камтар тасодуфӣ шуда, бештар ба истифодаи дониш ва камтар ба таҳқиқ такя мекунад. Ҷамъи мукофотҳои ҳар эпизод сабт ва баргардонда мешавад; графикаш дар расми 19.10 омадааст.

Расми 19.10. Каҷхати омӯзиши алгоритми Q-learning-и амиқ.
Эзоҳ. Чаро графики талафотро намекашем? Он нишондиҳандаи хуби кори агент нест. Беҳтар аст ҷамъи мукофоти ҳар эпизодро нишон диҳем. Талафот метавонад кам шавад, вале агент бадтар бозӣ кунад: масалан, дар минтақаи хурде дармонад ва DQN ба он аз ҳад мутобиқ шавад. Баръакс, талафот метавонад боло равад, вале бозӣ беҳтар шавад: масалан, DQN Q-арзишҳои ҳадафиро кам баҳогузорӣ карда буд ва ҳоло онҳоро дуруст зиёд мекунад.
Хабари хуб: алгоритм кор кард. Агенти омӯхташуда чӯбро комилан дар мувозинат нигоҳ дошта, мукофоти максималии 1000 мегирад. Хабари бад: омӯзиш бисёр ноустувор аст, ҳатто аз REINFORCE ҳам ноустувортар. Пеш аз ёфтани ин иҷрои муваффақ гиперпараметрҳоро хеле тағйир додан лозим шуд. Агент тақрибан баъди 200 эпизод ба 200 хол мерасад — натиҷаи бад нест — вале баъд ҳама чизро фаромӯш карда, то тақрибан эпизоди 550 суст бозӣ мекунад ва танҳо он вақт масъаларо зуд ҳал менамояд.
Чаро ин DQN ноустувор аст? Оё тақсимоти додаҳо сабаб аст? Буфери бознамоӣ калон буда, тақсимот нисбат ба REINFORCE хеле устувортар аст. Мушкили асосӣ дар он аст, ки модел ҳам пешгӯӣ мекунад ва ҳам ҳадафҳои худашро муайян менамояд. Ин ба саге монанд аст, ки думашро таъқиб мекунад. Чунин ҳалқаи бозхӯрд метавонад шабакаро ба дуршавӣ, ларзиш, дармондан ва ҳолатҳои дигар барад. Хушбахтона, роҳҳои беҳтаркунӣ ҳастанд.
Беҳтарсозии DQN
Дар мақолаи соли 2013 муҳаққиқони DeepMind пешниҳод карданд, ки барои устувор кардани омӯзиш ба ҷойи як DQN ду DQN истифода шавад. Якум модели ҷорӣ (online) аст, ки дар ҳар қадам меомӯзад ва барои ҳаракати агент истифода мешавад. Дуюм модели ҳадафӣ (target) мебошад, ки танҳо ҳадафҳоро муайян мекунад. Модели ҳадафӣ нусхаи модели ҷорӣ аст ва вазнҳояш дар фосилаҳои муайян аз модели ҷорӣ нусхабардорӣ мешаванд: масалан, дар моделҳои Atari ҳар 10000 қадам. Ҳадафҳои Q-арзиш устувортар шуда, ҳалқаи бозхӯрд суст ва таъсири он сабуктар мегардад. Ин беҳбудии муҳимро бо чанд тағйири дигар якҷо карданд: буфери бознамоии бисёр калон, суръати омӯзиши хурд, омӯзиши хеле тӯлонӣ — 50 миллион қадам, камшавии хеле сусти эпсилон дар давоми 1 миллион қадам ва шабакаи пурқуввати CNN.
Дар мақолаи соли 2015 DeepMind боз алгоритмро беҳтар карда, самаранокӣ ва устувориро боло бурд. Ин вариант double DQN ном гирифт. Асосаш мушоҳидае буд, ки шабакаи ҳадафӣ Q-арзишҳоро аз ҳад зиёд баҳогузорӣ мекунад. Фарз кунед, ҳамаи амалҳо баробар хубанд. Q-арзишҳои пешгӯишуда бояд баробар бошанд, вале азбаски тақрибӣ ҳастанд, баъзеи онҳо тасодуфан каме баландтар мебароянд. Модел ҳамеша калонтаринро мегирад, ки аз миёна каме баландтар аст ва эҳтимол арзиши воқеиро зиёд нишон медиҳад. Ин ба он монанд аст, ки чуқурии ҳавзро аз баландии мавҷи тасодуфии аз ҳама баланд чен кунед. Барои ислоҳ, интихоби амали беҳтарини ҳолати навбатӣ ба модели ҷорӣ дода шуд; модели ҳадафӣ танҳо Q-арзиши ҳамон амал-ро ҳисоб мекунад.
Беҳбудии дигари муҳим бознамоии афзалиятноки таҷрибаҳо (prioritized experience replay, PER) мебошад. Онро низ муҳаққиқони DeepMind дар мақолаи соли 2015 пешниҳод карданд. Ба ҷойи интихоби якхелаи ҳамаи таҷрибаҳо аз буфер, чаро таҷрибаҳои муҳимро бештар интихоб накунем?
Таҷриба «муҳим» ҳисоб мешавад, агар эҳтимол ба пешрафти тези омӯзиш оварда расонад. Инро чӣ гуна баҳогузорӣ кунем? Як роҳ андозаи хатои TD мебошад:
δ = r + γ · V(s′) − V(s).
Дар DQN ин хато бо Q-арзишҳо ҳисоб мешавад: δ=r+γ·maxₐ' Q(s',a')−Q(s,a), яъне фарқи Q-арзиши ҳадафии муодилаи 19.8 ва Q-арзиши пешгӯишуда. Хатои калон нишон медиҳад, ки гузариши (s,a,s') хеле ғайричашмдошт аст ва омӯхтани он эҳтимол арзиш дорад. Ҳангоми сабти таҷриба дар буфер афзалияташ хеле баланд гузошта мешавад, то ҳадди ақал як бор интихоб гардад. Ҳар бор интихоб шуданаш δ ҳисоб шуда, афзалият ба p=|δ| бо иловаи собити хурд гузошта мешавад. Ин собит имкон медиҳад, ки эҳтимоли интихоби ягон таҷриба сифр нашавад. Эҳтимоли P-и интихоби таҷрибаи дорои афзалияти p ба p^ζ мутаносиб аст. Гиперпараметри ζ (зета) қувваи афзалиятро идора мекунад: бо ζ=0 интихоб якхела ва бо ζ=1 комилан мутаносиб ба афзалият мешавад. Муаллифони мақола ζ=0.6 гирифтанд, вале қимати беҳтарин ба вазифа вобаста аст.
Аммо як нозукӣ ҳаст: интихоб ба таҷрибаҳои муҳим моил мешавад ва бояд ин ғаразро ҳангоми омӯзиш бо кам кардани вазни онҳо ҷуброн кард. Дар акси ҳол модел ба таҷрибаҳои муҳим аз ҳад мутобиқ мешавад. Мо мехоҳем онҳоро бештар интихоб кунем, вале дар ҳар бор вазни омӯзишии камтар диҳем. Вазни таҷриба чунин муайян мешавад:
w = (nP)⁻ᵝ,
ки n шумораи таҷрибаҳои буфер ва β гиперпараметри дараҷаи ҷуброни ғарази интихоб аст: 0 — тамоман ҷуброн накардан, 1 — ҷуброни пурра. Дар мақола аз β=0.4 оғоз карда, то охири омӯзиш онро хаттӣ ба 1 расонданд. Ин қиматҳо ба вазифа вобастаанд, вале агар яке аз параметрҳои марбут ба афзалиятро зиёд кунед, одатан дигарашро ҳам зиёд кардан мехоҳед.
Варианти дигари муҳим dueling DQN аст, ки онро DDQN ҳам меноманд. Онро бо double DQN омехта накунед, ҳарчанд ҳар ду усулро якҷо истифода бурдан осон аст. Он ҳам дар мақолаи соли 2015 аз ҷониби DeepMind пешниҳод шуд. Барои фаҳмидани он Q-арзиши ҷуфти (s,a)-ро чунин менависем:
Q(s, a) = V(s) + A(s, a),
ки V(s) арзиши ҳолат ва A(s,a) бартарии амали a нисбат ба амалҳои дигари ҳамин ҳолат аст. Арзиши ҳолат ба Q-арзиши амали беҳтарини a* баробар мебошад, зеро сиёсати беҳтарин ҳамон амалро мегирад:
V(s) = Q(s, a*)
A(s, a*) = 0.
Дар dueling DQN модел ҳам арзиши ҳолат ва ҳам бартарии ҳар амали имконпазирро ҳисоб мекунад. Чун бартарии амали беҳтарин бояд сифр бошад, аз ҳамаи бартариҳои пешгӯишуда баландтаринашонро кам мекунад. Қисми боқимондаи алгоритм ҳамон тавр мемонад.
Ин усулҳоро бо роҳҳои гуногун якҷо кардан мумкин аст. Дар мақолаи соли 2017 DeepMind шаш усулро дар агенти Rainbow муттаҳид кард, ки аз усулҳои пешсафи онвақта хеле беҳтар буд.
Пас, чаро градиентҳои сиёсат ва усулҳои ба арзиш асосёфтаро якҷо накунем, то аз бартариҳои ҳар ду баҳра гирем? Ин ғояи асосии алгоритмҳои актёр–мунаққид аст.
Алгоритмҳои актёр–мунаққид
Ин оилаи алгоритмҳо PG-ро бо усулҳои ба арзиш асосёфта якҷо мекунад. Система аз сиёсат — актёр — ва шабакаи арзиш — мунаққид — иборат аст, ки ҳамзамон омӯзонида мешаванд. Актёр ба мунаққид такя мекунад, то арзиш ё бартарии амалҳою ҳолатҳоро ҳисоб карда, навсозии сиёсатро роҳнамоӣ кунад. Дар вариантҳое, ки мунаққид буфери калони бознамоиро истифода мебарад, ин кор омӯзишро устувор ва истифодаи додаҳоро самараноктар мекунад. Он ба варзишгаре монанд аст, ки бо кумаки мураббӣ меомӯзад.
Усулҳои актёр–мунаққид мисли PG сиёсатҳои стохастикӣ ва фазои амалҳои пайвастаро дастгирӣ мекунанд. Пас, бартариҳои ҳар ду равишро мегирем.
Намунаи сода месозем:
class ActorCritic(nn.Module):
def __init__(self):
super().__init__()
self.body = nn.Sequential(nn.Linear(4, 32), nn.ReLU(),
nn.Linear(32, 32), nn.ReLU())
self.actor_head = nn.Linear(32, 1) # outputs action logits
self.critic_head = nn.Linear(32, 1) # outputs state values
def forward(self, state):
features = self.body(state)
return self.actor_head(features), self.critic_head(features)
Дар созанда шабакаҳои актёр ва мунаққидро месозем. Дар ин татбиқ қабатҳои поёнии онҳо — тана (body) — муштараканд. Ин равиши маъмул шумораи параметрҳоро кам ва истифодаи додаҳоро самаранок мекунад, аммо актёру мунаққидро зичтар пайваста, омӯзишро каме ноустувортар мекунад: боз ҳамон мушкили «таъқиби дум». Актёр бастаи ҳолатҳоро гирифта, барои ҳар ҳолат логити амали 1-ро медиҳад, мисли REINFORCE. Мунаққид арзиши ҳар ҳолатро баҳогузорӣ мекунад. forward() ҳолатҳоро аз танаи муштарак ва ҳар ду сар гузаронда, логитҳо ва арзишҳоро бармегардонад.
Функсияи интихоби амал ба choose_action()-и REINFORCE монанд аст, вале арзиши ҳисобкардаи мунаққидро ҳам медиҳад. Он барои омӯзиш лозим мешавад:
def choose_action_and_evaluate(model, obs):
state = torch.as_tensor(obs)
logit, state_value = model(state)
dist = torch.distributions.Bernoulli(logits=logit)
action = dist.sample()
log_prob = dist.log_prob(action)
return int(action.item()), log_prob, state_value
Акнун функсияи як қадами омӯзишро менависем:
def ac_training_step(optimizer, criterion, state_value, target_value, log_prob,
critic_weight):
td_error = target_value - state_value
actor_loss = -log_prob * td_error.detach()
critic_loss = criterion(state_value, target_value)
loss = actor_loss + critic_weight * critic_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
Аввал хатои TD — фарқи ҳадафи y=r+γV(s') ва арзиши V(s) — ҳисоб мешавад. Талафоти актёр мисли REINFORCE аст, вале логарифми эҳтимол ба ҷойи боздеҳи стандартӣ ба хатои TD зарб мешавад. Яъне амалҳоеро ҳавасманд мекунем, ки аз интизории шабакаи арзиш беҳтар баромаданд. Талафоти мунаққид бошад, баҳодиҳии V(s)-ро ба y наздик мекунад, масалан бо MSE. Талафоти умумӣ ҷамъи вазндори талафоти актёр ва мунаққид аст. Барои устуворӣ одатан вазни қисми мунаққидро камтар мегиранд. Сипас як қадами беҳинасоз иҷро мешавад. td_error.detach()-ро истифода мекунем, то талафоти актёр тавассути хатои TD шабакаи мунаққидро тағйир надиҳад.
Функсияи ҳисоб кардани ҳадаф низ лозим аст:
def get_target_value(model, next_obs, reward, done, truncated, discount_factor):
with torch.inference_mode():
_, _, next_state_value = choose_action_and_evaluate(model, next_obs)
running = 0.0 if done else 1.0 # truncation still bootstraps
target_value = reward + running * discount_factor * next_state_value
return target_value
Аввал бо choose_action_and_evaluate() арзиши V(s') ҳисоб мешавад; амал ва логарифми эҳтимолашро сарфи назар мекунем. Азбаски ҳадаф месозем ва намехоҳем градиент ба он таъсир кунад, ин корро дар inference_mode() иҷро менамоем. Баъд y=r+γV(s')-ро мегирем. Агар эпизод табиатан анҷом ёбад (done), y=r мешавад. Агар танҳо қатъ шавад (truncated), V(s') нигоҳ дошта мешавад, зеро ҳолати s' охирин набуд.
Ҳоло функсияе менависем, ки эпизоди пурраро иҷро карда, актёр–мунаққидро дар ҳар қадам омӯзонад. Он ҷамъи мукофотҳоро низ ҳисоб карда, дар охири эпизод медиҳад:
def run_episode_and_train(model, optimizer, criterion, env, discount_factor,
critic_weight, seed=None):
obs, _info = env.reset(seed=seed)
total_rewards = 0
while True:
action, log_prob, state_value = choose_action_and_evaluate(model, obs)
next_obs, reward, done, truncated, _info = env.step(action)
target_value = get_target_value(model, next_obs, reward, done,
truncated, discount_factor)
ac_training_step(optimizer, criterion, state_value, target_value,
log_prob, critic_weight)
total_rewards += reward
if done or truncated:
return total_rewards
obs = next_obs
Функсияи асосӣ онро борҳо даъват карда, ҷамъи мукофоти ҳар эпизодро бармегардонад:
def train_actor_critic(model, optimizer, criterion, env, n_episodes=400,
discount_factor=0.95, critic_weight=0.3):
totals = []
model.train()
for episode in range(n_episodes):
seed = torch.randint(0, 2**32, size=()).item()
total_rewards = run_episode_and_train(model, optimizer, criterion, env,
discount_factor, critic_weight,
seed=seed)
totals.append(total_rewards)
print(f"\rEpisode: {episode + 1}, Rewards: {total_rewards}", end=" ")
return totals
Иҷро мекунем:
torch.manual_seed(42)
ac_model = ActorCritic()
optimizer = torch.optim.NAdam(ac_model.parameters(), lr=1.1e-3)
criterion = nn.MSELoss()
totals = train_actor_critic(ac_model, optimizer, criterion, env)
Кор мекунад! CartPole хеле устувор шуда, мукофоти максималиро ҷамъ мекунад. Бо вуҷуди ин, худи раванди омӯзиш ҳанӯз ба гиперпараметрҳо ва тухми тасодуфӣ бисёр ҳассос ва ноустувор аст. Муҳаққиқон барои устувор кардани актёр–мунаққид усулҳои гуногун пешниҳод кардаанд. Чанд усули машҳур:
Актёр–мунаққиди асинхронӣ бо бартарӣ (Asynchronous Advantage Actor-Critic, A3C). Ин варианти муҳимро DeepMind соли 2016 пешниҳод кард. Чанд агент дар нусхаҳои гуногуни муҳит ба таври мувозӣ меомӯзанд. Ҳар агент дар фосилаҳои муайян, вале асинхронӣ, навсозиҳои вазнҳоро ба шабакаи асосӣ мефиристад ва сипас вазнҳои охирини онро мегирад. Ҳамин тавр ҳам дар беҳтар шудани шабака саҳм мегузорад ва ҳам аз дониши агентҳои дигар баҳра мебарад. Мунаққид ба ҷойи арзиши ҳолат ё Q-арзиш бартарии амалҳоро ҳисоб мекунад, монанди dueling DQN.
Эзоҳи тарҷумон. Дар A3C-и маъмул мунаққид одатан V(s)-ро пешгӯӣ мекунад ва аз он бартарӣ ҳисоб мешавад. Калимаи «бартарӣ» дар ном ҳатман маънои баромади мустақими A(s,a)-ро надорад.
Актёр–мунаққид бо бартарӣ (Advantage Actor-Critic, A2C). Ин варианти A3C асинхрониро бартараф мекунад. Навсозиҳо синхронӣ мешаванд ва градиент аз бастаҳои калонтар ҳисоб мегардад, то қувваи GPU беҳтар истифода шавад.
Актёр–мунаққиди нарм (Soft Actor-Critic, SAC). Соли 2018 Туомас Ҳаарноя ва ҳамкоронаш аз UC Berkeley пешниҳод карданд. SAC ҳам мукофот ва ҳам энтропияи амалҳоро зиёд мекунад: агент кӯшиш мекунад ҳарчи пешгӯинашавандатар бошад ва ҳамзамон мукофоти зиёд гирад. Ин таҳқиқро ҳавасманд карда, омӯзишро тез мекунад ва ҳангоми нодуруст будани баҳодиҳии мунаққид аз такрори доимии як амал пешгирӣ менамояд. Алгоритм самаранокии баланди истифодаи намунаҳоро нишон додааст; алгоритмҳои қаблан баррасишуда сусттар меомӯзанд.
Беҳинасозии сиёсати наздик (Proximal Policy Optimization, PPO). Ҷон Шулман ва дигар муҳаққиқони OpenAI онро бар асоси A2C пешниҳод карданд. Он функсияи талафотро маҳдуд мекунад, то навсозиҳои аз ҳад калони вазнҳо, ки аксаран омӯзишро ноустувор мекунанд, пешгирӣ шаванд. PPO содасозии алгоритми пешинаи Trust Region Policy Optimization (TRPO) мебошад, ки он ҳам аз OpenAI аст. Моҳи апрели 2019 OpenAI Five, ки бар PPO асос ёфта буд, қаҳрамонҳои ҷаҳонро дар бозии бисёрнафараи Dota 2 мағлуб кард.
Ду алгоритми охирин — SAC ва PPO — аз усулҳои васеъ истифодашавандаи RL мебошанд. Якчанд китобхона татбиқҳои осону хеле беҳинашудаи онҳоро медиҳанд. Барои мисол, бо Stable-Baselines3 агенти PPO-ро дар бозии Atari Breakout меомӯзонем.
Маслиҳат. Кадом алгоритмро интихоб кунем? PPO алгоритми хуби таъиноти умумӣ аст ва агар бовар надошта бошед, нуқтаи оғози муносиб мебошад. SAC барои амалҳои пайваста аз ҷиҳати истифодаи намунаҳо хеле самаранок буда, барои робототехника муносиб аст. DQN барои вазифаҳои дискретӣ, монанди Atari ва бозиҳои рӯйимизӣ, ҳамоно қавӣ мебошад.
Азхуд кардани Atari Breakout бо PPO-и Stable-Baselines3
Stable-Baselines3 (SB3) дар Colab пешфарз насб нест. Аввал фармони зеринро иҷро мекунем, ки чанд дақиқа мегирад:
%pip install -q stable_baselines3
Агар дар компютери худ кор карда, дастурҳои насбро риоя карда бошед, китобхона аллакай насб аст.
Сипас интерфейси ALE месозем. Он эмулятори Atari 2600-ро иҷро карда, робитаи Gymnasium-ро бо он имконпазир мекунад ва бозиҳои Atari дар рӯйхати муҳитҳо пайдо мешаванд:
import ale_py
ale = ale_py.ALEInterface()
Бозиҳои Atari дар картриҷҳои ҳофизаи танҳо барои хондан (ROM) нигоҳ дошта мешуданд. Ин ROM-ҳоро барои таҳқиқоту таълим боргирӣ кардан мумкин аст. Дар муҳити Colab ва насби маҳаллии мувофиқи дастурҳои китоб онҳо пешакӣ омодаанд.
Ҳоло SB3, интерфейси ALE ва ROM-ҳо дорем. Ба ҷойи сохтани Breakout мустақиман бо Gymnasium, make_atari_env()-и SB3-ро истифода мебарем. Он муҳити печонандае месозад, ки чанд Breakout-ро ба таври мувозӣ иҷро мекунад. Ҳар мушоҳидаи он аз ҳар муҳити дохилӣ як мушоҳида дорад. step() низ массиви дорои як амал барои ҳар муҳит мегирад. Печонанда тасвирҳои RGB-и 210×160-ро ба тасвирҳои хокистарии 84×84 пешкоркард мекунад. Ин хеле қулай аст. Чор муҳити Breakout сохта, онҳоро оғоз мекунем:
from stable_baselines3.common.env_util import make_atari_env
envs = make_atari_env("BreakoutNoFrameskip-v4", n_envs=4)
obs = envs.reset() # a 4 × 84 × 84 × 1 NumPy array (note: no info dict)
Маслиҳат. Методи
get_images()тасвирҳои аслии пеш аз пешкоркардро медиҳад (расми 19.11). Дар ин мисол объекти муҳитҳои векторӣenvsном дорад.

Расми 19.11. Кадри Breakout пеш аз пешкоркард (чап) ва баъди он (рост).
Интерфейси ALE бо 60 кадр дар як сония кор мекунад. Кадрҳои пайдарпай бисёр монанданд ва коркарди ҳар кадр ҳисоббарориро беҳуда сарф мекунад. Барои пешгирӣ муҳити пешфарзи Breakout ҳар амалро чор бор такрор карда, танҳо мушоҳидаи охиринро медиҳад. Ин гузаронидани кадрҳо (frame skipping) ном дорад. Барои мушоҳидаи ҳаракат кадрҳоро ҳам ба тасвири чорканала ҷамъ кардан муфид аст. Барои ин BreakoutNoFrameskip-v4 ба ҷойи Breakout-v4 интихоб шудааст. Баъд муҳитро ба VecFrameStack мепечонем:
from stable_baselines3.common.vec_env import VecFrameStack
envs_stacked = VecFrameStack(envs, n_stack=4)
obs = envs_stacked.reset() # returns a 4 × 84 × 84 × 4 NumPy array
Эзоҳи тарҷумон. Дар матни аслӣ гуфта мешавад, ки худи
VecFrameStackҳар амалро чор бор такрор мекунад. Он дар асл таърихи чор мушоҳидаи пайдарпайро дар меҳвари каналҳо нигоҳ медорад; такрори амал ва гузаронидани кадрҳо вазифаи печонандаҳои пешкоркарди Atari мебошанд, киmake_atari_env()месозад. Код нигоҳ дошта шудааст.
Акнун PPO-ро бо гиперпараметрҳои муносиб месозем:
from stable_baselines3 import PPO
ppo_model = PPO("CnnPolicy", envs_stacked, device=device, learning_rate=2.5e-4,
batch_size=256, n_steps=256, n_epochs=4, clip_range=0.1,
vf_coef=0.5, ent_coef=0.01, gamma=0.99, verbose=0)
Аргументҳо зиёданд. Вазифаашонро мебинем:
- Аргументи якум шабакаи сиёсат аст. Бо
CnnPolicySB3 аз рӯйи алгоритм, дар ин ҷо PPO, ва фазои мушоҳидаҳо CNN-и мувофиқ месозад. Барои дидани меъморӣppo_model.policy-ро бинед: CNN-и амиқ бо сари актёр барои логитҳои амал ва сари мунаққид барои арзишҳои ҳолат. Чор амал имкон доранд: чап, рост,fireбарои сар додани тӯб ваno-opбарои ҳеҷ кор накардан. Барои шабакаи фармоишӣ азActorCriticPolicyдарstable_baselines3.common.policiesзерсинф созед. Тафсилот дар ҳуҷҷатҳои SB3 ҳаст. env,device,learning_rateваbatch_sizeмутаносибан муҳит, дастгоҳи ҳисоббарорӣ, суръати омӯзиш ва андозаи баста мебошанд. Тағйирёбандаиdeviceмисли бобҳои пешин пешакӣ муайян карда мешавад:"cuda","mps"ё"cpu".n_stepsшумораи қадамҳои ҳар муҳит пеш аз навсозии навбатии сиёсат аст.n_epochsшумораи даврҳои омӯзиш аз рӯйи додаҳои ҷамъшуда дар марҳилаи беҳинасозӣ мебошад.clip_rangeбузургии навсозии сиёсатро маҳдуд мекунад, то тағйироти калон ба фаромӯшкунии фалокатбор нарасанд.vf_coefвазни талафоти функсияи арзиш дар талафоти умумӣ аст; баcritic_weightдар мисоли актёр–мунаққид монанд мебошад.ent_coefвазни қисми энтропия аст, ки таҳқиқро ҳавасманд мекунад.gammaкоэффисиенти тахфиф мебошад.verboseдараҷаи тафсилоти сабти хабарҳост: 0 — хомӯш, 1 — иттилоот, 2 — ислоҳи хато.
Маслиҳат. Барои вазифаи нав гиперпараметрҳои пешфарзи PPO оғози хубанд. Агар омӯзиш суст бошад, аввал шумораи муҳитҳои мувозиро зиёд кунед; баъд суръати омӯзиш ё ҳудуди
clip_range-ро баланд кардан мумкин. Кам карданиn_stepsёbatch_sizeҳам имкон дорад, вале градиентҳоро ғавғоноктар мекунад. Агар омӯзиш ноустувор бошад, суръати омӯзиш ёclip_range-ро паст ва дарозии ҷамъоварии таҷрибаҳо, яънеn_steps, ё андозаи бастаро зиёд кунед. Барои вазифаҳои уфуқи кӯтоҳgamma-ро тақрибан 0.95 ва барои уфуқи дароз 0.995–0.999 гиред. Барои таҳқиқи бештарent_coef-ро зиёд кунед.
Омӯзишро оғоз мекунем. Коди зерин моделро 30 миллион қадам меомӯзонад. Ин соатҳои зиёд мегирад ва эҳтимол аз давомнокии як сессияи Colab зиёд мешавад, магар обунаи пулакӣ дошта бошед. Аз ин рӯ дафтари боб коди боргирии модели омӯхташударо ҳам дорад. Дар омӯзиши тӯлонӣ муҳим аст, ки дар фосилаҳои мунтазам, масалан ҳар 100000 даъвати step(), нуқтаи назоратӣ (checkpoint) захира кунед, то баъди садама ё қатъи барқ аз сифр оғоз накунед. Барои ин callback-и захиракунӣ сохта, ба learn() медиҳем:
from stable_baselines3.common.callbacks import CheckpointCallback
cb = CheckpointCallback(save_freq=100_000, save_path="my_ppo_breakout.ckpt")
ppo_model.learn(total_timesteps=30_000_000, progress_bar=True, callback=cb)
ppo_model.save("my_ppo_breakout") # save the final model
Эзоҳ.
save_freqшумораи даъватҳоиstep()-ро ҳисоб мекунад. Бо чор муҳити мувозӣ, масалан 50000 даъват ба 200000 қадами умумии вақт баробар аст.
Барои дидани пешрафт метавон нуқтаи назоратии охиринро дар дафтари дигар бор карда, санҷид. Роҳи осонтар истифодаи TensorBoard барои дидани каҷхатҳои омӯзиш, хусусан мукофоти миёнаи ҳар эпизод аст. Аввал дар Colab ё Jupyter васеъкуниро фаъол мекунем:
%load_ext tensorboard
Ин кор дар оғози дафтари боб иҷро шудааст. Баъд сервери TensorBoard-ро оғоз карда, феҳристи сабтҳо ва порти TCP-ро муайян мекунем. Фармони «ҷодуӣ», яъне фармони оғозшаванда бо %, ҳам серверро мекушояд ва ҳам интерфейси муштариро бевосита дар Colab ё Jupyter нишон медиҳад:
tensorboard_logdir = "my_ppo_breakout_tensorboard" # path to the log directory
%tensorboard --logdir={tensorboard_logdir} --port 6006
Ҳангоми сохтани PPO бояд ҷойи сабтҳои TensorBoard-ро ҳам диҳем:
ppo_model = PPO("CnnPolicy", [...], tensorboard_log=tensorboard_logdir)
Пас аз оғози омӯзиш каҷхатҳо тақрибан ҳар 30 сония нав мешаванд; тугмаи навсозиро ҳам пахш кардан мумкин. Нишондиҳандаи муҳимтарин rollout/ep_rew_mean, яъне мукофоти миёнаи эпизод аст. Он бояд тадриҷан зиёд шавад, гарчанде гоҳе каме поён меравад. Одатан баъди 1 миллион қадам тақрибан ба 20 мерасад, ки ҳанӯз агенти хуб нест. Баъди 10 миллион қадам метавонад ба сатҳи инсон расад ва баъди 50 миллион қадам одатан аз инсон пеш мегузарад.
Акнун медонед, ки чӣ гуна AI-и аз инсон беҳтарро омӯзонед! Онро чунин санҷидан мумкин аст:
ppo_model = PPO.load("my_ppo_breakout") # or load the best checkpoint
eval_env = make_atari_env("BreakoutNoFrameskip-v4", n_envs=1, seed=42)
eval_stacked = VecFrameStack(eval_env, n_stack=4)
frames = []
obs = eval_stacked.reset()
for _ in range(5000): # some limit in case the agent never loses
frames.append(eval_stacked.render())
action, _ = ppo_model.predict(obs, deterministic=True) # for reproducibility
obs, reward, done, info = eval_stacked.step(action)
if done[0]: # note: there's no `truncated`
break
eval_stacked.close()
Эзоҳи тарҷумон. Дар манбаъ
PPO.load()файлиmy_ppo_agent_breakout-ро мекушояд, ки бо номи файли дар боло захирашуда мувофиқат намекунад; ин ҷо ном ислоҳ шуд.
Ин код ҳамаи кадрҳои як эпизодро сабт мекунад. Бо Matplotlib онҳоро ба аниматсия табдил додан мумкин аст; намуна дар дафтар ҳаст. Агар агент ба қадри кофӣ омӯзонида шуда бошад ё модели тайёрро истифода кунед, мебинед, ки хуб бозӣ мекунад. Он ҳатто стратегияи кандани нақбҳо аз канорҳо ва аз онҳо гузаронидани тӯбро меёбад — яке аз беҳтарин стратегияҳои ин бозӣ!
Шарҳи чанд алгоритми машҳури RL
Пеш аз анҷоми боб чанд алгоритми дигарро кӯтоҳ мебинем.
AlphaGo
AlphaGo барои мағлуб кардани қаҳрамонҳои инсон дар Go аз варианти ҷустуҷӯи дарахтии Монте-Карло (MCTS) бо шабакаҳои амиқи нейронӣ истифода мекунад. Пайдоиши MCTS ба кори Николас Метрополис ва Станислав Улам дар соли 1949 нисбат дода шудааст. Алгоритм пас аз симулятсияҳои бисёр амали беҳтаринро интихоб мекунад: дарахти ҷустуҷӯро аз мавқеи ҷорӣ такроран таҳқиқ намуда, ба шохаҳои умедбахштар вақти бештар медиҳад. Вақте ба гиреҳи ҳанӯз нодида мерасад, то охири бозӣ тасодуфан бозӣ мекунад. Аз рӯйи натиҷаи ниҳоӣ баҳодиҳии ҳар гиреҳи дидашударо, ба ғайр аз ҳаракатҳои қисми тасодуфӣ, зиёд ё кам менамояд.
Эзоҳи тарҷумон. Соли 1949 ва номҳои зикршуда ба таърихи усули Монте-Карло дахл доранд; нисбат додани худи MCTS ба ҳамон сол саҳеҳ нест.
AlphaGo ба принсипи монанд асос ёфтааст, вале ба ҷойи ҳаракатҳои тасодуфӣ аз шабакаи сиёсат истифода мекунад. Он бо градиентҳои сиёсат омӯзонида мешавад. Алгоритми аслӣ се шабакаи иловагӣ дошта, мураккабтар буд. Дар мақолаи AlphaGo Zero сода карда шуд: як шабака ҳам ҳаракат интихоб мекунад ва ҳам ҳолати бозиро арзёбӣ менамояд. AlphaZero алгоритмро умумӣ кард, то ба ғайр аз Go шоҳмот ва сёги, яъне шоҳмоти ҷопониро ҳам ҳал кунад. Ниҳоят, MuZero онро боз беҳтар карда, аз версияҳои пешина пеш гузашт, гарчанде агент дар оғоз ҳатто қоидаҳои бозиро намедонад!
Эзоҳ. Қоидаҳои Go дар AlphaGo бевосита барномарезӣ шуда буданд. MuZero бошад тадриҷан модели муҳитро меомӯзад: аз ҳолати s ва амали a пешгӯии мукофоти r ва динамикаи ҳолати баъдиро ёд мегирад. Доштани модели муҳит, хоҳ барномарезишуда бошад ё омӯхташуда, банақшагирии пешакиро имкон медиҳад — дар ин ҷо бо MCTS. Аз ин рӯ ҳар ду ба синфи васеи RL-и ба модели муҳит асосёфта (model-based) дохил мешаванд. Градиентҳои сиёсат, усулҳои ба арзиш асосёфта ва актёр–мунаққиди дар ин боб баррасишуда бе модели муҳит (model-free) мебошанд: онҳо модели сиёсат ва/ё арзиш доранд, вале модели худи муҳит надоранд.
Таҳқиқи ба кунҷковӣ асосёфта
Мушкили такроршавандаи RL камёбии мукофотҳо аст, ки омӯзишро сусту бесамар мекунад. Дипак Патҳак ва муҳаққиқони дигари UC Berkeley роҳи ҷолибе пешниҳод карданд: чаро мукофотҳои берунаро канор гузошта, агентро барои таҳқиқи муҳит бисёр кунҷков накунем? Мукофотҳо ба ҷойи аз муҳит омадан дохилии худи агент мешаванд. Монанди он ки парвариши кунҷковии кӯдак метавонад аз танҳо мукофот додан барои баҳои хуб натиҷаи беҳтар диҳад.
Ин чӣ гуна кор мекунад? Агент пайваста натиҷаи амалҳояшро пешгӯӣ карда, ҳолатҳоеро меҷӯяд, ки натиҷа ба пешгӯӣ мувофиқ нест. Яъне мехоҳад ҳайрон шавад. Агар натиҷа пешгӯишаванда ва «дилгиркунанда» бошад, ба ҷойи дигар меравад. Агар натиҷа пешгӯинашаванда бошад, вале агент фаҳмад, ки онро идора карда наметавонад, пас аз муддате аз он ҳам дилгир мешавад. Муаллифон танҳо бо кунҷковӣ агентро дар бозиҳои видеоии гуногун омӯзониданд. Гарчанде барои бохт ҷазо намегирад, аз бохтан дилгир мешавад, зеро бозӣ аз нав оғоз мегардад. Пас, пешгирӣ кардани онро меомӯзад.
Омӯзиши беинтиҳо (Open-Ended Learning, OEL)
Ҳадафи OEL сохтани агентҳоест, ки вазифаҳои нави ҷолибро беохир омӯзанд. Ин вазифаҳо одатан ба таври алгоритмӣ тавлид мешаванд. Ҳанӯз ба ин ҳадаф нарасидаем, вале солҳои охир пешрафтҳои ҷолиб ба даст омадаанд. Масалан, мақолаи соли 2019 аз гурӯҳи Uber AI алгоритми POET-ро муаррифӣ кард. Он муҳитҳои симулятсионии дученакаи гуногун бо пастию баландӣ ва чуқуриҳо тавлид карда, барои ҳар муҳит як агент меомӯзонад. Ҳадаф ҳарчи тезтар роҳ рафтан ва аз монеаҳо гузаштан аст.
Алгоритм аз муҳитҳои сода оғоз мекунад, вале онҳоро тадриҷан душвортар месозад. Ин омӯзиши барномавӣ (curriculum learning) ном дорад. Гарчанде ҳар агент танҳо дар як муҳит меомӯзад, мунтазам дар ҳамаи муҳитҳо бо агентҳои дигар рақобат мекунад. Дар ҳар муҳит ғолиб нусхабардорӣ шуда, ҷойи агенти пешинаро мегирад. Ҳамин тавр дониш мунтазам байни муҳитҳо мегузарад ва агентҳои мутобиқшавандатар интихоб мешаванд.
Дар охир агентҳо нисбат ба агентҳои танҳо дар як вазифа омӯхташуда беҳтар роҳ мераванд ва муҳитҳои хеле душвортарро паси сар мекунанд. Ин принсипро ба вазифаю муҳитҳои дигар ҳам татбиқ кардан мумкин аст. Агар ба OEL шавқ дошта бошед, мақолаи Enhanced POET ва мақолаи соли 2021-и DeepMind дар ин мавзуъро бинед.
Маслиҳат. Барои маълумоти бештар китоби Reinforcement Learning-и Фил Уиндер аз нашриёти O’Reilly-ро мутолиа кунед.

Барномасозӣ
Олами Афсонаҳо
Ахбор