چارچوب های کاری یادگیری تقویتی: فعالان این حوزه برای حل مسائل پیچیده چه میکنند؟
در این مقاله شما را با چارچوب های کاری یادگیری تقویتی Reinforcement Learning frameworks آشنا خواهیم کرد و توضیح خواهیم داد که چطور میتوانید وارد دنیای یادگیری تقویتی عمیق شوید.
پیش از این نگاهی انداختیم به بازنمایی سادهای از مجموعهای از الگوریتمهای یادگیری تقویتی که برنامهنویسی آنها به نسبت آسانتر بود. اما از این پس، باید هم مقیاس و هم پیچیدگی الگوریتمهای یادگیری تقویتی را مدنظر قرار دهیم. در این سناریو، نوشتن کدهای لازم برای اجرای یادگیری تقویتی ممکن است تبدیل به کاری خستهکننده شود. همچنین احتمال مواجهه با خطاهای کدنویسی در آن زیاد باشد.
فعالان حوزه یادگیری تقویتی برای حل این قبیل مسائل، چارچوب های کاری یادگیری تقویتی ایجاد کردند که فرآیند توسعه الگوریتمهای یادگیری تقویتی را تسهیل میکنند. آنها این کار را با خلق الگوریتمهای جدید و ترکیب عناصر الگوریتمهای مختلف با یکدیگر انجام دادند. در این مقاله ما قصد داریم تا این قبیل چارچوب های کاری یادگیری تقویتی را بررسی کرده و مشکل CartPole را به کمک RLlib که یک کتابخانه متنباز پایتونی و مبتنی بر چارچوب Ray است، حل کنیم.
انگیزه
پیش از ادامه بحث به یک مثال انگیزشی میپردازیم. اگر بهخاطر داشته باشید پیش از این درباره الگوریتمهای REINFORCE و محدودیتهای آنها را شرح دادیم. جامعه محققین، الگوریتمهای آموزشی متعددی برای حل این مسئله طراحی کردهاند، از جمله: A2C، A3C، DDPG، TD3، SAC و PPO. اما از صفر برنامهنویسی کردن این الگوریتمها پیچیدهتر از الگوریتم REINFORCE است. هر چه در این حوزه جلوتر بروید، گاه و بیگاه مجبور میشوید یک کد را بارها و بارها تکرار کنید. شاید هم از اول بنویسید.
برنامههای کاربردی یادگیری تقویتی در مقایسه با سایر حوزههای یادگیری عمیق (که چارچوب های کاری معتبری چون تنسورفلو، PyTorch و Mxnet را در دست دارند) بسیار جوان و خام هستند. اما مدتی است که چارچوب های کاری یادگیری تقویتی توسعه پیدا کردهاند. امروز میتوانیم از میان این پروژهها که استفاده از متدهای پیشرفته یادگیری تقویتی را برای ما تسهیل میکنند، چارچوب مناسب خود را انتخاب کنیم.
پیش از معرفی چارچوب های کاری یادگیری تقویتی به مفاهیم پایهای آنها میپردازیم.
یادگیری از طریق تعامل با محیط به جای استفاده از نمونه
در سالهای اخیر جامعه متخصصین یادگیری عمیق عمدتاً بر روی شناسایی الگوها متمرکز بودهاند. همین امر موجب شد که ما امروزه بتوانیم با اعمال روشهای مبتنی بر گرادیان، الگوهای درون دیتاستها را کشف کنیم و همچنین ابررایانههایی داریم که قادرند انواع دیتاست برچسبدار و بسیار بزرگ را پردازش کنند (و در اینجا متخصصان هستند که خروجیهای مجموعه آموزشی را تهیه میکنند) تا بتوانیم از آنها برای پیشبینی یا شناسایی ساختارهای درون دادهها استفاده کنیم.
اما این فرآیندهای برخلاف ذات بشر است. ما بخش مهمی از دانش عمومی خود را از طریق تعامل به دست میآوریم و لازم نیست کسی به ما بگوید نتیجه تک به تک اقدامات ما چه خواهد بود. بشر میتواند با کسب تجربه و تعامل با محیط برای مسائل جدیدی که با آنها روبهرو میشود، راهحل مناسبی پیدا کند و با کاوش و بررسی فعالانه دنیا درباره آن دانش کسب کند.
به همین دلیل، رویکردهای جدید یادگیری ماشین به دنبال راهی هستند که الگوریتمها بتوانند در یک محیط شبیهسازیشده و به کمک یادگیری تقویتی عمیق (یک رویکرد محاسباتی برای یادگیری هدفمند از طریق تعامل با محیط و بدون نیاز به نظارت متخصصان) با محیط تعامل داشته باشند. بدین منظور، عامل Agent یادگیری تقویتی باید از طریق تعامل با محیط دیتاست آموزشی مخصوص خود را بسازد.
این امر موجب میشود که الگوریتم بهصورت موازی با نمونههای مختلف محیط تعامل کند. همچنین بتواند با کسب تجربههای بیشتر، فرآیند یادگیری خود را سرعت ببخشد. این مسئله منجر به استفاده گسترده از سیستمهای موازی و توزیعشده در مقیاسهای بزرگ در حوزه یادگیری تقویتی میشود. این کار خود چالشهای زیادی در حوزههای مهندسی و طراحی الگوریتمها به وجود آوردند. البته این مشکلات را میتوان به کمک چارچوب های کاری یادگیری تقویتی که در ادامه معرفی خواهیم کرد، حل کرد.
[irp posts=”10403″]ابزراهای متنباز، نجاتبخش یادگیری تقویتی
طی سالهای اخیر، چارچوب های کاری همچون تنسورفلو و پای تورچ به کمک ما آمدهاند. از طرفی باعث شدهاند تا شناسایی الگو به یک کالای تجاری بدل شوند. به این روش بهکارگیری و استفاده از یادگیری تقویتی برای متخصصان تسهیل شود.
چنین اتفاقی تقریباً در دنیای یادگیری تقویتی نیز درحال رخ دادن است. ما شاهد ظهور کتابخانهها و ابزارهای تازه و متنبازی هستیم. آنها با خلق کدهای جدید (بهجای شروع کردن از صفر) و مهمتر از آن، ترکیب عناصر الگوریتمهای پیشساخته با یکدیگر، فرآیند توسعه یادگیری تقویتی را سرعت میبخشند. در نتیجه، این چارچوب های یادگیری تقویتی با فراهم آوردن مفاهیم سطح بالا از بخشهای اصلی الگوریتم یادگیری تقویتی، به کمک مهندسان میآیند. بهطور خلاصه، با استفاده از این چارچوبها توسعه و خواندن کدها آسانتر شده و کارآیی افزایش مییابد.
در ادامه فهرستی از محبوبترین چارچوب های یادگیری تقویتی ارائه شده است. بهنظر ما استفاده از کدهای منتشرشده در این چارچوبها یا کتابخانهها، برای شما مزایای زیادی در بر خواهد داشت.
- Keras-RL
- RL Coach
- ReAgent
- Ray+RLlib
- Dopamine
- Tensorforce
- RLgraph
- Garage
- DeeR
- Acme
- Baselines
این که کدامیک از چارچوب های بالا را برای پروژه خود انتخاب میکنید، به اولویتهای شما و کاری که میخواهید انجام دهید، بستگی دارد.
برای مثال، ما در مرکز تحقیقاتی خود از چارچوب کاری Acme استفاده میکنیم. اما ما به دلایلی که در ادامه خواهم گفت برای توضیح امکاناتی که این محیطها در اختیار شما قرار خواهد داد، از RLlib روی Ray، کمک خواهیم گرفت.
RLlib: الگوریتم مقیاسپذیر یادگیری تقویتی
ما در مرکز تحقیقاتی خود از چارچوب کاری Acme استفاده میکنیم. اما من به دلایلی که در ادامه خواهم گفت برای توضیح امکاناتی که این محیطها در اختیار شما قرار خواهد داد، از RLlib روی Ray، کمک خواهم گرفت.
افزایش توان محاسبتی موردنیاز
در الگوریتمهای یادگیری تقویتی عمیق تعداد زیادی شبیهسازی به علاوه یک ضریب فزاینده دیگر به پیچیدگیهای محاسباتی یادگیری عمیق افزوده میشود. این مسئله اغلب در الگوریتمهای همچون روشهای توزیعشده عامل-منتقد Actor-critic و یا روشهای چند عاملی Multi-agents مشاهده میشود.
اما حتی برای پیدا کردن بهترین مدل نیز اغلب باید ابرپارامترها Hyperparameter را تنظیم کرده و در میان تنظیمات مختلف ابرپارامتر جستوجو کنیم که کاری پرهزینه است. همه اینها مستلزم داشتن توان محاسباتی بالایی است که توسط ابررایانههای مبتنی بر سیستمهای توزیعشده و سرورهای ناهمگن (دارای CPUهای چند هستهای و شتابدهندههای سختافزاری همچون GPU و TPU) تولید میشود.
ابرارایانه کنونی ما به دو بلوک سختافزاری جداگانه تقسیم میشود. یک بلوک مربوط به هدف کلی است و بلوک دیگر مبتنی بر سیستم IBM، که مخصوصا برای اجرای برنامههای هوش مصنوعی و یادگیری عمیق طراحی شده است.
به لحاظ سختافزاری این بخش از رایانه از 54 خوشه گره Node تشکیل شده که دارای تراشه IBM Power 9 و NVIDIA V100 هستند و از سیستمعامل لینوکس استفاده میکنند و دارای اتصالات داخلی شبکه Infiniband با سرعتی معادل 100 گیگابایت بر ثانیه میباشند. هر گره مجهز به 2 پردازنده IBM POWER9، 20 هسته فیزیکی و 512 گیگابایت حافظه است. هر یک از این پردازندههای POWER9 به دو GPUی NVIDIA V100 دارای 16 گیگابایت حافظه متصل هستند. بدین ترتیب، هر گره در مجموع 4 عدد GPU دارد.
اما این سختافزار در هم پیچیده چگونه میتواند عملکرد خوبی داشته باشد؟
[irp posts=”10403″]پشته نرمافزاری
تسریع فرآیند یادگیری تقویتی با استفاده از سیستمهای موازی و توزیعشده، ما را با چالشهای فراوانی در حوزه مدیریت توزیع و موازیسازی اجرای برنامهها مواجه کرد. برای حل این پیچیدگیها لایههای نرمافزاری جدیدی ارائه شدند. آنها به لایههای پیشین اضافه میشدند. با این شرایط میتوانیم اجزای مختلف پشته نرمافزاری چند لایه سیستم را به صورت منطقی از یکدیگر جدا نگه داریم.
به دلیل همین مفهوم کلیدی، ما امروز میتوانیم روی مولفههای نرمافزاری در درون ابررایانهها متمرکز شویم که انجام کارهای پیچیده را برعهده دارند. خوب است در اینجا نقل قولی داشته باشیم از دنی هیلز، مؤسس شرکت Thinking Machines Corporation که توسعهدهنده محصول اتصال موازی دستگاه Parallel Connection Machine است، وی میگوید: «ساختار سلسله مراتبی انتزاعی مهمترین ابزار ما برای درک سیستمهای پیچیده است، زیرا به ما امکان این را میدهد که هر بار روی یک جنبه از مسئله متمرکز شویم».
این نکته یکی از مزیتهای مهم RLlib است که من به عنوان چارچوب کاری خود انتخاب کردم. تقسیمات و فلسفه این پشته نرمافزاری چند لایه به شکل زیر است.
ساختار سلسله مراتبی انتزاع که انتزاع عملی را برای ما امکانپذیر میکند، ویژگی بسیار مهمی است. زیرا با استفاده از آن میتوانیم اطلاعات را بدون نگرانی درخصوص بازنمایی بنیادین آن، دستکاری کرده و تغییر دهیم. دنیل هیلز در جای دیگر چنین گفت: «زمانی که نحوه اجرای تابع دادهشده را متوجه شویم، میتوانیم این مکانیسم را درون یک “جعبه سیاه” در داخل یک “بلوک سازنده building block” گذاشته و دیگر درباره آن فکر نخواهیم کرد. تابع جای گرفته در درون بلوک سازنده را میتوان بدون نیاز به دقیق شدن در محتویات آن، چندین بار استفاده کرد».
Ray
به طور خلاصه، رایانش توزیعشده و موازی مؤلفه اصلی و بنیادین الگوریتمهای یادگیری تقویتی است. ما برای بالا بردن سرعت برنامههای یادگیری تقویتی، باید از چندین هسته و شتابدهنده (روی چندین دستگاه) استفاده کنیم و ماژول پردازش چندگانه پایتون این مشکل را حل نخواهد کرد، بلکه در این شرایط به چارچوب های یادگیری تقویتی همچون Ray نیاز داریم.
صفحه رسمی پروژه Ray آن را یک چارچوب کاری ساده و با سرعت بالا برای ساخت و اجرای برنامههای توزیعشده معرفی میکند:
- این چارچوب عناصر ابتدایی و زیربنایی لازم برای ساخت و اجرای برنامههای توزیعشده را به ما ارائه میدهد.
- چارچوب کاری Ray امکان موازیسازی کد اجراشده روی یک دستگاه بدون کمترین تغییرات ممکن را برای کاربر نهایی فراهم میکند.
- Ray با داشتن شمار زیادی از برنامهها، کتابخانهها و ابزار موردنیاز، امکان توسعه برنامههای پیچیده را برای ما فراهم میآورد.
Ray Core عناصر ابتدایی و زیربنایی لازم برای برنامهها را برای ما فراهم کرده است. جدا از Ray Core و RLlib کتابخانههای دیگری نیز برای حل مسائل یادگیری ماشینی قابلاستفاده هستند. از جمله آنها میتوان به Tune (Scalable Hyperparameter Tuning) ،RaySGD (Distributed Training Wrappers) و Ray Serve (Scalable and Programmable Serving) اشاره کرد.
RLlib
RLlib یک کتابخانه متنباز برای یادگیری تقویتی است که هم مقیاسپذیری بالایی دارد و هم یک API یکپارچه برای انواع برنامهها ارائه میدهد. این کتابخانه همچنین از تنسورفلو، تنسورفلو Eager و PyTorch نیز پشتیبانی میکند، اما اغلب بخشهای داخلی آن وابسته به چارچوب کاری خاصی نیستند.
کتابخانه RLIib مستندسازی جامع و فراگیری دارد و کاربر علاوهبر استفاده از الگوریتمهای موجود در این کتابخانه میتواند الگوریتمهای موردنیاز خود را نیز بسازد.
مفاهیم اصلی در RLIib سیاستها، نمونهها و مربیان هستند. سیاستها درواقع کلاسهایی به زبان پایتون هستند که طرز عمل عامل در محیط را تعریف میکنند. تمامی دادههایی که در RLIib ردوبدل میشوند در قالب بستههای نمونه Sample batches هستند که یک یا چندین بخش از یک مسیر را رمزگذاری میکنند. مربیان نیز کلاسهای تکراری هستند که مولفههای ذکرشده در بالا را در کنار هم قرار میدهند. همچنین پیکربندی الگوریتمها، بهینهساز، معیارهای آموزش، جریان کاری اجرای مؤلفههای موازی و غیره را مدیریت میکنند.
در مقالههای آتی بهصورت تخصصی به الگوریتمها توزیعشده و چندعاملی نیز خواهیم پرداخت. همچنین مؤلفههای کتابخانه RLIib را با جزییات بیشتر بررسی خواهیم کرد.
تنسورفلو یا PyTorch
پیش از این دیدیم که رقابت شدیدی بین سامانههای قدرتمند تنسورفلو و PyTorch وجود دارد. به این ترتیب، کتابخانه RLIib با پشتیبانی از هر دو سامانه این امکان را به کاربر میدهد تا از برای اجرای پروژههای یادگیری تقویتی خود به راحتی بتواند از تنسورفلو و PyTorch استفاده کند.
RLIib به منظور فراهم کردن امکان تغییر میان تنسورفلو و Pytorch به عنوان هسته برای کاربران خود، RLIib شامل پیکربندی مربی Trainer config framework است. برای مثال، برای آنکه الگوریتم خود را به نسخه PyTorch آن منتقل کنیم، میتوانیم {“framework”:”torch”} را تعریف کنیم. این عبارت به RLIib میگوید که باید از نسخه torch سیاست مربوطه برای الگوریتم ما استفاده کند.
پیدا کردن راهحل محیط Cartpole به کمک کتابخانه RLIib
در ادامه مثال سادهای را بررسی میکنیم تا نحوه حل مسئله محیط Cartpole در نسخه OpenAI Gym را با استفاده از الگوریتم PPO توسط RLIib مشاهده کنید. PPO یکی از طرحهای پیشنهادی بود که محدودیتهای الگوریتم REINFORCE را رفع کرد. شما میتوانید با استفاده از کدهای ارائه شده در این مقاله هر یک از الگوریتمهای از پیش برنامهنویسی شده در این چارچوب را آزمایش کنید.
کدهای این مثال را میتوانید بهطور کامل در گیتهاب مشاهده کرد.
هشدار: با توجه به اینکه میخواهیم این مثال را اجرا کنیم، باید پس از نصب پکیج ray زمان اجرا را بازنشانی کرده و pyarrow را حذف کنیم.
میتوانید از طریق ray.rllib.agents به الگوریتمهایی که بدین منظور بهکار گرفته میشوند، دسترسی پیدا کنید.
اگر بخواهید از PPO استفاده کنید، میتوانید کد زیر را اجرا نمایید:
import ray from ray.rllib.agents.ppo import PPOTrainer, DEFAULT_CONFIG ray.init()
دستور ()ray.init تمامی فرآیندهای Ray مربوطه را آغاز میکند. این کار باید پیش از معرفی عوامل یادگیری تقویتی انجام شود. برای مثال شیء PPOTrainer را در مثال زیر درنظر بگیرید:
config = DEFAULT_CONFIG.copy() config["num_gpus"] = 1 # in order to use the GPU agent = PPOTrainer(config, 'CartPole-v0')
حال میتوانیم تعدادی ابرپارامتر را وارد شیء config میکنیم که تعیینکننده نحوه پیکربندی شبکه و شیوه آموزش است. تغییر پارامترها بسیار آسان است و تنها کافی است آنها را در قالب یک واژهنامه Dictionary به آرگومان config بدهیم. یک راه سریع برای اطلاع پیدا کردن از گزینههای در دسترس فراخوانی trainer.config است تا تنظیماتی که میتوانید از میان آنها انتخاب کنید را برای شما چاپ کند.
print(DEFAULT_CONFIG) { ‘num_workers’: 2, ‘num_envs_per_worker’: 1, ‘rollout_fragment_length’: 200, ‘num_gpus’: 0, ‘train_batch_size’: 4000, . . . }
پس از تعیین پیکربندی خود، با فراخوانی متد ()train در شیء trainer ، خروجی ما بهروزرسانی شده و به یک واژهنامه جدید به نام results فرستاده خواهد شد.
result = agent.train()
تمامی الگوریتمها از یک ساختار مشابه پیروی میکنند و اسامی مخففی که با حروف کوچک نوشته شدهاند را به حروف بزرگ تغییر میدهند و شیء Trainer نیز در ادامه آن میآید. برای مثال، اگر بخواهید از یک الگوریتم DQN استفاده کنید، میتوانید موارد زیر را فراخوانی کنید:
from ray.rllib.agents.dqn import DQNTrainer, DEFAULT_CONFIG agent = DQNTrainer(config=DEFAULT_CONFIG, env='CartPole-v0')
آسانترین راه از منظر برنامهنویسی برای محاسبه اقدامات یک عامل آموزشدیده استفاده از ()trainer.compute_action است:
action=agent.compute_action(state)
این متد هر مشاهده را پیش از درنظر گرفتن به عنوان سیاست عامل، پیشپردازش و فیلتر میکند. در زیر مثالی را مشاهده میکنید از عاملی که از ()compute_action استفاده کرده است:
def watch_agent(env): state = env.reset() rewards = [] img = plt.imshow(env.render(mode=’rgb_array’)) for t in range(2000): action=agent.compute_action(state) img.set_data(env.render(mode=’rgb_array’)) plt.axis(‘off’) display.display(plt.gcf()) display.clear_output(wait=True) state, reward, done, _ = env.step(action) rewards.append(reward) if done: print(“Reward:”, sum([r for r in rewards])) break env.close()
با استفاده از تابع watch_agent میتوانیم رفتار یک عامل را پیش و پس از آموزش را مقایسه کرده و با فراخونی متد ()train عامل را به تعداد دفعات دلخواه بهروزرسانی کنیم:
for i in range(10): result = agent.train() print(f'Mean reward: {result["episode_reward_mean"]:4.1f}')
آخرین خط در این کد با چاپ کردن اطلاعات موجود در متد ()train ، به ما میگوید که چگونه میتوانیم اجرای حلقه آموزش را کنترل و بررسی کنیم.
در بالا مثال سادهای از اجرای یک الگوریتم در چارچوب RLIib را بهطور خلاصه بررسی کردیم. دلیل اهمیت و ارزشمندی این چارچوب کاری، قابل استفاده بودن آن در زیرساختهای عظیم است. زیرساختهایی که الگوریتمهای ذاتاً موازی و پیچیده را اجرا میکنند و نوشتن کد از صفر در آنها غیرممکن است.
ما پس از بررسی همه چارچوب های ذکرشده در ابتدای مقاله، چارچوب RLIib را انتخاب کردیم. دلایل زیادی برای این کار داشتیم که برخی از آنها را در این مقاله ذکر کردیم. یکی دیگر از دلایل ما برای انتخاب این چارچوب این است که در سرویسهای ارائهدهنده خدمات ابری از قبیل AWS و AzureML قابل استفاده است. همچنین شرکت توانمند ANYSCALE که توانسته 20 میلیون دلار سرمایه جذب کند و برگزارکننده کنفرانس Ray Summit است نیز در این تصمیم سهم داشته است.
[irp posts=”6101″]مسیر پیشِ رو
امیدواریم این مقاله توانسته باشد با معرفی این فناوری هیجانانگیز شما را به مطالعه بیشتر در این حوزه از هوش مصنوعی ترغیب کند. ما در این مقاله چندان وارد جزییات نشدیم. تنها سعی کردیم تعدادی از جذابیتهای این دنیای فوقالعاده را به شما نشان دهیم. در ادامه لیستی از کتابها و مراجعی که میتوانند شما را در این مسیر کمک کنند، آوردهایم:
- Richard S. Sutton and Andrew G. Barto. Reinforcement Learning: An Introduction, by MIT Press, 2018. [available from incompleteideas.net]. Related independent repo of Python code.
- Miguel Morales. Grokking Deep Reinforcement Learning. MANNING, 2020.
- Alexander Zai and Brandon Brown. Deep Reinforcement Learning in Action. MANNING, 2020.
- Maxim Lapan. Deep Reinforcement Learning Hands-on. Packt Publishing Ltd., 2nd edition, 2020.
- Phil Winder. Reinforcement Learning, Industrial Applications and Intelligent Agents. O’Really Media Inc., 2020.
- Micheal Lanham. Hands-on Reinforcement Learning for Games. MANNING, 2020.
منابع آنلاین:
- UCL Course on RL by David Silver
- UC Berkeley CS 285 by Sergey Levine
- DeepMind & UCL by Hado Van Hasselt
- Stanford CS234 by Emma Brunskill
- UPC Barcelona Tech by Mario Martin
- University of Waterloo CS 885 by Pascal Poupart
- Berkeley DRL Bootcamp by Pieter Abbeel et all
- UPC Barcelona Tech by Xavier Giró-i-Nieto et all
- OpenAI by Josh Achiam
- Lilian Weng Blog
- Papers with code