# कार्टपोल स्केटिङ हामीले अघिल्लो पाठमा समाधान गरिरहेको समस्या खेलौना समस्या जस्तो देखिन सक्छ, जुन वास्तविक जीवनका परिस्थितिहरूमा प्रयोगयोग्य नहुन सक्छ। यस्तो होइन, किनकि धेरै वास्तविक विश्वका समस्याहरूले पनि यो परिदृश्य साझा गर्छन् - जस्तै चेस वा गो खेल्ने। तिनीहरू मिल्दोजुल्दो छन् किनकि हामीसँग बोर्ड छ र निश्चित नियमहरू छन् र एक **विविक्त अवस्था** छ। ## [पाठ अघि क्विज](https://ff-quizzes.netlify.app/en/ml/) ## परिचय यस पाठमा हामी Q-लर्निङका उहि सिद्धान्तहरूलाई **सतत अवस्था** भएको समस्यामा लागू गर्नेछौं, जसको मतलब एउटा वा बढी वास्तविक संख्याबाट दिइएको अवस्था हो। हामी तलको समस्यामा काम गर्नेछौं: > **समस्या**: यदि पिटर बँदेलबाट भाग्न चाहन्छ भने, उसको छिटो हिँड्न सक्नुपर्नेछ। हामी देख्नेछौं कि पिटर कसरी स्केट गर्न सिक्न सक्छ, विशेष गरी सन्तुलन कायम राख्न, Q-लर्निङ प्रयोग गरेर। ![महान भाग्ने योजना!](../../../../translated_images/ne/escape.18862db9930337e3.webp) > पिटर र उनका साथीहरूले बँदेलबाट भाग्न रचनात्मकता देखाउँछन्! तस्बिर: [जेन लूपर](https://twitter.com/jenlooper) हामी एक सरल संस्करणको सन्तुलनलाई कार्टपोल समस्या भनेर चिनिने समस्या प्रयोग गर्नेछौं। कार्टपोल दुनियाँमा, हामीसँग एक तेर्सो स्लाइडर हुन्छ जुन बायाँ वा दायाँ सर्न सक्छ, र लक्ष्य स्लाइडरको माथि एउटा ठाडो पोललाई सन्तुलनमा राख्नु हो। a cartpole ## आवश्यकताहरू यस पाठमा, हामी **OpenAI Gym** नामक पुस्तकालय प्रयोग गर्नेछौं विभिन्न **परिवेश** अनुकरण गर्न। तपाईंले यो पाठको कोड स्थानीय रूपमा चलाउन सक्नुहुन्छ (जस्तै Visual Studio Code बाट), यस अवस्थामा अनुकरण नयाँ विन्डोमा खुल्नेछ। अनलाइन कोड चलाउँदा, तपाईंले केहि संशोधनहरू गर्नुपर्ने हुन सक्छ, जस्तै तपाईले [यहाँ](https://towardsdatascience.com/rendering-openai-gym-envs-on-binder-and-google-colab-536f99391cc7) वर्णन गरिएको छ। ## OpenAI Gym अघिल्लो पाठमा, खेलका नियम र अवस्था `Board` क्लासले दिइन्थ्यो जुन हामीले आफैं परिभाषित गर्यौं। यहाँ हामी विशेष **अनुकरण वातावरण** प्रयोग गर्नेछौं, जसले सन्तुलन पोलको पछाडि भएको भौतिक विज्ञान अनुकरण गर्नेछ। प्रशिक्षण सुदृढीकरण सिक्ने एल्गोरिदमका लागि सबैभन्दा लोकप्रिय अनुकरण वातावरणहरूमध्ये एक [Gym](https://gym.openai.com/) हो, जुन [OpenAI](https://openai.com/) द्वारा व्यवस्थापन गरिन्छ। यस जिम प्रयोग गरेर हामी कार्टपोल अनुकरणदेखि एटारी खेलसम्म फरक **परिवेश** बनाउन सक्छौं। > **टिप्पणी**: तपाईं OpenAI Gym द्वारा उपलब्ध अन्य वातावरणहरू [यहाँ](https://gym.openai.com/envs/#classic_control) हेर्न सक्नुहुन्छ। पहिले, जिम स्थापना गरौं र आवश्यक पुस्तकालयहरू आयात गरौं (कोड ब्लक 1): ```python import sys !{sys.executable} -m pip install gym import gym import matplotlib.pyplot as plt import numpy as np import random ``` ## अभ्यास - कार्टपोल वातावरण प्रारम्भ गर्नुहोस् कार्टपोल सन्तुलन समस्यामा काम गर्न, हामीलाई सम्बन्धित वातावरण प्रारम्भ गर्नुपर्छ। प्रत्येक वातावरणसँग सम्बन्धित हुन्छ: - **अवलोकन स्थान** जसले वातावरणबाट प्राप्त गर्ने सूचना संरचना परिभाषित गर्दछ। कार्टपोल समस्याका लागि, हामी पोलको स्थिति, गति र केही अन्य मानहरू पाउँछौं। - **कार्य स्थान** जसले सम्भावित कार्यहरू परिभाषित गर्दछ। हाम्रो अवस्थामा, कार्य क्षेत्र विविक्त छ र दुई कार्यहरू समावेश गर्दछ - **बायाँ** र **दायाँ**। (कोड ब्लक 2) 1. प्रारम्भ गर्न, तलको कोड टाइप गर्नुहोस्: ```python env = gym.make("CartPole-v1") print(env.action_space) print(env.observation_space) print(env.action_space.sample()) ``` वातावरण कसरी काम गर्छ हेर्न, १०० चरणको छोटो अनुकरण चलाऔं। प्रत्येक चरणमा, हामी लिने कार्य मध्ये एउटा दिन्छौं - यस अनुकरणमा हामी `action_space` बाट बेतरतीब रूपमा एउटा कार्य चयन गर्छौं। 1. तलको कोड चलाउनुहोस् र परिणाम के हुन्छ हेर्नुहोस्। ✅ याद गर्नुहोस् कि यो कोड स्थानीय Python इन्स्टलेसनमा चलाउन सिफारिस गरिन्छ! (कोड ब्लक 3) ```python env.reset() for i in range(100): env.render() env.step(env.action_space.sample()) env.close() ``` तपाईंले यो तस्बिर जस्तो केही देख्नुपर्नेछ: ![सन्तुलन नगरिएको कार्टपोल](../../../../8-Reinforcement/2-Gym/images/cartpole-nobalance.gif) 1. अनुकरणको क्रममा, हामीले कस्तो कार्य गर्ने निर्णय गर्न अवलोकनहरू लिनुपर्छ। वास्तवमा, स्टेप फंक्शनले हालको अवलोकनहरू, पुरस्कार समारोह र `done` झण्डा फर्काउँछ जुन बताउँछ कि अनुकरण जारी राख्नु उपयुक्त छ कि छैन: (कोड ब्लक 4) ```python env.reset() done = False while not done: env.render() obs, rew, done, info = env.step(env.action_space.sample()) print(f"{obs} -> {rew}") env.close() ``` तपाईं नोटबुकको आउटपुटमा यस्तै केही देख्नुहुनेछ: ```text [ 0.03403272 -0.24301182 0.02669811 0.2895829 ] -> 1.0 [ 0.02917248 -0.04828055 0.03248977 0.00543839] -> 1.0 [ 0.02820687 0.14636075 0.03259854 -0.27681916] -> 1.0 [ 0.03113408 0.34100283 0.02706215 -0.55904489] -> 1.0 [ 0.03795414 0.53573468 0.01588125 -0.84308041] -> 1.0 ... [ 0.17299878 0.15868546 -0.20754175 -0.55975453] -> 1.0 [ 0.17617249 0.35602306 -0.21873684 -0.90998894] -> 1.0 ``` प्रत्येक अनुकरण चरणमा फर्काइएको अवलोकन भेक्टरले यस्ता मानहरू समावेश गर्दछ: - कार्टको स्थिति - कार्टको गति - पोलको कोण - पोलको घुम्ने दर 1. ती संख्याहरूको न्यूनतम र अधिकतम मान पाउँ: (कोड ब्लक 5) ```python print(env.observation_space.low) print(env.observation_space.high) ``` तपाईंले अवलोकन गर्नुहुनेछ कि प्रत्येक अनुकरण चरणमा पुरस्कार मान सधैं १ हुन्छ। यसको कारण यो हो कि हाम्रो लक्ष्य सकेसम्म लामो समय सम्म जीवित रहनु, अर्थात पोललाई उचित ठाडो अवस्थामै राख्नु हो। ✅ साँच्चिकै, कार्टपोल अनुकरणलाई परिमार्जन गरिएको मानिन्छ यदि हामीले १०० लगातार प्रयासमा औसत पुरस्कार १९५ प्राप्त गर्न सक्छौं भने। ## अवस्थाको विविक्तीकरण Q-लर्निङमा, हामीले Q-टेबल निर्माण गर्नुपर्छ जुन हरेक अवस्थामा के गर्ने भन्ने जनाउँछ। यसका लागि, हामीलाई अवस्था **विविक्त** हुनुपर्छ, अर्थात यसले सीमित संख्याका विविक्त मानहरू समावेश गर्नुपर्छ। त्यसैले, हामीले हाम्रो अवलोकनहरूलाई कतै न कतै **विविक्तीकरण** गर्न आवश्यक छ, तिनीहरूलाई सीमित अवस्थाहरूमा नक्साङ्कन गर्न। यसका लागि केही तरिकाहरू छन्: - **बिनहरूमा विभाजन**। यदि हामीलाई कुनै मानको अन्तराल थाहा छ भने, हामी त्यो अन्तराललाई केही **बिनहरू**मा विभाजन गर्न सक्छौं, र त्यसपछि मानलाई त्यो बिन नम्बरले प्रतिस्थापन गर्न सक्छौं जसमा त्यो पर्छ। यो numpy को [`digitize`](https://numpy.org/doc/stable/reference/generated/numpy.digitize.html) विधि प्रयोग गरेर गर्न सकिन्छ। यस अवस्थामा, हामी अवस्थाको आकारलाई ठ्याक्कै जान्नेछौं किनकि यो बिनहरूको संख्यामा निर्भर गर्दछ जुन हामीले डिजिटलाइजेसनका लागि चयन गरेका छौं। ✅ हामी रैखिक अन्तर्वर्तीकरण (linear interpolation) प्रयोग गरेर मानहरूलाई केही सीमित अन्तराल (जस्तै -२० देखि २० सम्म) ल्याउन सक्छौं, त्यसपछि ती सङ्ख्याहरूलाई पूर्णाङ्कमा परिणत गर्न सक्छौं। यसले हाम्रो अवस्थामा अवस्थाको आकारमा अलि कम नियन्त्रण दिन्छ, विशेषगरी यदि हामीले इनपुट मानहरूको सही श्रेणी थाहा नपाएमा। उदाहरणका लागि, हाम्रो अवस्थामा ४ मध्ये २ मानहरूको माथिल्लो/तल्लो सीमा छैन, जसले अनन्त अवस्थाहरू उत्पादन गर्न सक्छ। हाम्रो उदाहरणमा, हामी दोस्रो तरिका अपनाउनेछौं। तपाईं पछि देख्नुहुनेछ कि अपरिभाषित माथिल्लो/तल्लो सीमा भए पनि, ती मानहरू प्रायः केही सीमित अन्तरालबाट बाहिर जान सक्दैनन्, त्यसैले ती चरम मानहरू भएका अवस्थाहरू दुर्लभ हुनेछन्। 1. यहाँ फङ्क्शन छ जुन हाम्रो मोडेलबाट अवलोकन लिन्छ र चार पूर्णाङ्क मानहरूको टुपल उत्पादन गर्छ: (कोड ब्लक 6) ```python def discretize(x): return tuple((x/np.array([0.25, 0.25, 0.01, 0.1])).astype(np.int)) ``` 1. अर्को विविक्तीकरण विधि बिनहरू प्रयोग गरेर अन्वेषण गरौं: (कोड ब्लक 7) ```python def create_bins(i,num): return np.arange(num+1)*(i[1]-i[0])/num+i[0] print("Sample bins for interval (-5,5) with 10 bins\n",create_bins((-5,5),10)) ints = [(-5,5),(-2,2),(-0.5,0.5),(-2,2)] # प्रत्येक प्यारामिटरको लागि मानहरूको अन्तरालहरू nbins = [20,20,10,10] # प्रत्येक प्यारामिटरको लागि बिनहरूको संख्या bins = [create_bins(ints[i],nbins[i]) for i in range(4)] def discretize_bins(x): return tuple(np.digitize(x[i],bins[i]) for i in range(4)) ``` 1. अब छोटो अनुकरण चलाऔं र ती विविक्त वातावरणका मानहरू अवलोकन गरौँ। `discretize` र `discretize_bins` दुवै प्रयोग गरेर देख्न सक्नुहुन्छ फरक छ कि छैन। ✅ discretize_bins बिन नम्बर फर्काउँछ, जुन ०-आधारित हुन्छ। त्यसैले इनपुट चरको मानहरू 0 नजिकको लागि यसको मान अन्तरालको मध्य भाग (१०) हुन्छ। discretize मा हामीले आउटपुट मानको सीमा नहेर्ने गर्यौं, जसले नकारात्मक मान राख्न दिनेछ, त्यसैले अवस्थाका मानहरू न सर्ने गरी ० ले ० जनाउँछ। (कोड ब्लक 8) ```python env.reset() done = False while not done: #env.render() obs, rew, done, info = env.step(env.action_space.sample()) #print(discretize_bins(obs)) print(discretize(obs)) env.close() ``` ✅ यदि तपाईंले वातावरण सञ्चालन कसरी हुन्छ हेर्न चाहानुहुन्छ भने env.render को लाइन अनकमेन्‍ट गर्नुहोस्। नत्र यसलाई पृष्ठभूमिमा चलाउन सक्नुहुन्छ जुन छिटो हुन्छ। हामी हाम्रो Q-लर्निङ प्रक्रियामा यो "अदृश्य" सञ्चालन प्रयोग गर्नेछौं। ## Q-टेबल संरचना हाम्रो अघिल्लो पाठमा, अवस्था सजिलो जोडी ० देखि ८ सम्मका संख्याहरू थियो, त्यसैले numpy टेन्सर जसको आकार ८x८x२ थियो Q-टेबल प्रतिनिधित्व गर्न सहज थियो। यदि हामी बिन्स विविक्तीकरण प्रयोग गर्छौं भने, अवस्थाको आकार पनि ज्ञात हुन्छ, त्यसैले हामी उहि तरिका अपनाएर २०x२०x१०x१०x२ आकारको एरेले अवस्थालाई प्रतिनिधित्व गर्न सक्छौं (यहाँ २ कार्य स्थानको आयाम हो, र पहिलेका आयाम अवलोकन स्थानका हरेक प्यारामिटरहरूको लागि चयन गरिएका बिनहरूका सङ्ख्यालाई जनाउँछन्)। यद्यपि कहिलेकाहीं अवलोकन स्थानका थोरै सही आयामहरू थाहा हुँदैनन्। `discretize` फङ्क्शनको अवस्थामा, हामीले कहिल्यै निश्चित हुन सक्दैनौं कि हाम्रो अवस्था कुनै सीमामा रहन्छ वा छैन, किनकि केहि मूल मानहरू निर्धारण छैनन्। त्यसैले, हामी अलि फरक तरिका अपनाउनेछौं र Q-टेबललाई शब्दकोश (डिक्शनरी) द्वारा प्रतिनिधित्व गर्नेछौं। 1. जोडी *(state,action)* लाई डिक्शनरी कुञ्जीको रूपमा प्रयोग गर्नुहोस्, र मान Q-टेबल प्रविष्टि मान हुनेछ। (कोड ब्लक 9) ```python Q = {} actions = (0,1) def qvalues(state): return [Q.get((state,a),0) for a in actions] ``` यहाँ हामीले `qvalues()` फङ्क्शन पनि परिभाषित गरेका छौं, जसले दिइएको अवस्थाका लागि सबै सम्भावित कार्यका Q-टेबल मानहरूको सूची फर्काउँछ। यदि Q-टेबलमा प्रविष्टि छैन भने, हामीले पूर्वनिर्धारित रूपमा ० फर्काउनेछौं। ## Q-लर्निङ सुरु गरौँ अब हामी पिटरलाई सन्तुलन कायम गर्न सिकाउन तयार छौं! 1. पहिले, केहि हाइपरप्यारामिटरहरू सेट गरौं: (कोड ब्लक 10) ```python # हाइपरप्यारामिटरहरू alpha = 0.3 gamma = 0.9 epsilon = 0.90 ``` यहाँ, `alpha` **शिक्षण दर** हो जुन हरेक चरणमा Q-टेबलका हालको मानहरू कति समायोजन गर्ने भन्ने जनाउँछ। अघिल्लो पाठमा हामीले १ बाट सुरु गर्यौं, र त्यसपछि प्रशिक्षणमा `alpha` घटायौं। यहाँ उदाहरणका लागि हामी यसलाई स्थिर राख्छौं, तर तपाईं पछि `alpha` मानहरू समायोजन गरी प्रयोग गर्न सक्नुहुन्छ। `gamma` **छुटको कारक** हो जसले भविष्यको पुरस्कारलाई हालको पुरस्कार भन्दा कति प्राथमिकता दिने जनाउँछ। `epsilon` **पत्ता लगाउने/फाइदा उठाउने कारक** हो जुन पत्ता लगाउने वा फाइदा उठाउने पक्षलाई प्राथमिकता दिने जनाउँछ। हाम्रो एल्गोरिदममा, हामी `epsilon` प्रतिशत अवस्थामा Q-टेबल मान अनुसार अर्को कार्य चयन गर्नेछौं, बाँकी अवस्थामा बेतरतीब् कार्य गर्नेछौं। यसले हामीलाई पहिले कहिल्यै नदेखेका खोज क्षेत्रहरूको अन्वेषण गर्न मद्दत गर्नेछ। ✅ सन्तुलनका सन्दर्भमा - बेतरतीब् कार्य (अन्वेषण) गलत दिशामा एक बेतरतीब् प्रहार जस्तै हुनेछ, र पोलहरूले ती "गल्तीहरू" बाट सन्तुलन पुनःप्राप्ति सिक्नुपर्नेछ। ### एल्गोरिदम सुधार हामीले अघिल्लो पाठबाट हाम्रो एल्गोरिदममा दुई सुधार पनि गर्न सक्छौं: - **औसत संचयी पुरस्कार गणना गर्नुहोस्**, धेरै अनुकरणहरूमा। हामी प्रत्येक ५००० पुनरावृत्तिमा प्रगति मुद्रित गर्नेछौं, र त्यो अवधिमा हुने संचयी पुरस्कारको औसत निकाल्नेछौं। यसको अर्थ यदि हामीले १९५ भन्दा बढी अंक पायौं भने - हामी समस्यालाई समाधान गरिएको मान्न सक्छौं, अझ राम्रो गुणस्तरसहित। - **अधिकतम औसत संचयी परिणाम गणना गर्नुहोस्**, `Qmax` भन्ने, र त्यो परिणामसँग मिल्ने Q-टेबल भण्डारण गर्नेछौं। प्रशिक्षण चलाउँदा कहिलेकाहीं औसत संचयी परिणाम घट्न सक्छ, र हामी प्रशिक्षणको क्रममा देखिएका उत्कृष्ट मोडेलसँग मेल खाने Q-टेबल मानहरू राख्न चाहन्छौं। 1. प्रत्येक अनुकरणमा सबै संचयी पुरस्कारहरू `rewards` भेक्टरमा सङ्कलन गर्नुहोस् ताकि पछि प्लटिङ गर्न सकियोस। (कोड ब्लक 11) ```python def probs(v,eps=1e-4): v = v-v.min()+eps v = v/v.sum() return v Qmax = 0 cum_rewards = [] rewards = [] for epoch in range(100000): obs = env.reset() done = False cum_reward=0 # == अनुकरण गर्नुहोस् == while not done: s = discretize(obs) if random.random() Qmax: Qmax = np.average(cum_rewards) Qbest = Q cum_rewards=[] ``` तपाईंलाई ती परिणामहरूबाट देख्न सकिने कुराहरू: - **हाम्रो लक्ष्य नजिकै**। हामी १०० भन्दा बढी लगातार अनुकरण रनहरूमा १९५ संचयी पुरस्कार प्राप्त गर्ने लक्ष्य नजिक छौं, वा सायद प्राप्त गरिसकेका छौं! यदि सानो मानहरू प्राप्त भएपनि, हामीले ५००० रनको औसत लिइरहेका छौं र आधिकारिक मापदण्डमा कागजी रूपमा १०० रन पुग्न पुग्छ। - **पुरस्कार घट्न शुरु हुन्छ**। कहिलेकाहीं पुरस्कार घट्न थाल्छ, जसको अर्थ हामीले पहिले सिकेका Q-टेबल मूल्यहरू नोक्सान गर्न सकिरहेका छौं जुन स्थिति खराब पार्छ। प्रशिक्षण प्रगतिको प्लट गरेपछि यो अवलोकन अझ प्रष्ट देखिन्छ। ## प्रशिक्षण प्रगति प्लटिङ प्रशिक्षणका दौरान, हामी प्रत्येक पुनरावृत्तिमा संचयी पुरस्कार सङ्कलन गर्यौं `rewards` भेक्टरमा। तल यसलाई पुनरावृत्ति सङ्ख्याको विरुद्ध प्लट गर्नुको तरिका छ: ```python plt.plot(rewards) ``` ![कच्चा प्रगति](../../../../translated_images/ne/train_progress_raw.2adfdf2daea09c59.webp) यस ग्राफबाट केही भन्न सकिन्न किनकि संख्यात्मक प्रशिक्षण प्रक्रियाको स्वभावले प्रशिक्षण सत्रहरूको लम्बाइ धेरै फरक हुन्छ। यसको अर्थ बुझ्न, हामी श्रृंखलाबद्ध प्रयोगहरूको **चलिरहेको औसत** गणना गर्न सक्छौं, जस्तै १००। यो सजिलै `np.convolve` प्रयोग गरेर गर्न सकिन्छ: (कोड ब्लक 12) ```python def running_average(x,window): return np.convolve(x,np.ones(window)/window,mode='valid') plt.plot(running_average(rewards,100)) ``` ![प्रशिक्षण प्रगति](../../../../translated_images/ne/train_progress_runav.c71694a8fa9ab359.webp) ## हाइपरप्यारामिटरहरू परिवर्तन गर्दै सिकाइलाई स्थिर बनाउन, हामीले प्रशिक्षणका दौरान हाम्रा केहि हाइपरप्यारामिटरहरू समायोजन गर्न सक्छौं। विशेषतः: - **शिक्षण दर `alpha` को लागि**, हामी सुरुमा १ नजिकको मानबाट सुरु गर्न सक्छौं, त्यसपछि यो घटाउन सक्छौं। समयसँगै, हामीले Q-टेबलमा राम्रो सम्भाव्यता मानहरू पाइरहेका छौं, त्यसैले सानोतिनो समायोजन ठीक छ, पूर्ण नयाँ मानहरूले नबद्लिने। - **`epsilon` बढाउनुहोस्**। हामी बिस्तारै `epsilon` बढाउन सक्छौं, यसरी अन्वेषण कम र फाइदा उठाउने बढी हुनेछ। सम्भावित रूपमा `epsilon` सानो मानले सुरु गर्नु र लगभग १ सम्म पुर्याउनु ठीक हुन्छ। > **कार्य १**: हाइपरप्यारामिटर मानहरू मिलाएर हेर्नुहोस् र उच्च संचयी पुरस्कार प्राप्त गर्न सक्नुहुन्छ कि छैन। के तपाईं १९५ भन्दा माथि पुग्नुहुन्छ? > **कार्य २**: समस्यालाई औपचारिक रूपमा समाधान गर्नको लागि, तपाईले १०० लगातार रनहरूमा १९५ औसत पुरस्कार पाउनुपर्छ। तालिमको दौरान त्यसलाई मापन गर्नुहोस् र पक्का गर्नुहोस् कि तपाईले औपचारिक रूपमा समस्यालाई समाधान गर्नुभएको छ! ## परिणामलाई प्रत्यक्षमा हेर्नुहोस् तालिम प्राप्त मोडेल कस्तो व्यवहार गर्छ भनेर वास्तविक रुपमा हेर्न रोचक हुने थियो। आउनुहोस् सिमुलेशन चलाउँ र तालिमको समयमा जस्तै कार्य चयन रणनीति पालन गरौं, Q-टेबलमा रहेको सम्भावनाको वितरण अनुसार नमूनाको चयन गरौं: (कोड ब्लक १३) ```python obs = env.reset() done = False while not done: s = discretize(obs) env.render() v = probs(np.array(qvalues(s))) a = random.choices(actions,weights=v)[0] obs,_,done,_ = env.step(a) env.close() ``` तपाईलाई यस प्रकार केही देखिनु पर्छ: ![a balancing cartpole](../../../../8-Reinforcement/2-Gym/images/cartpole-balance.gif) --- ## 🚀चुनौती > **कार्य ३**: यहाँ, हामीले Q-टेबलको अन्तिम कपी प्रयोग गरिरहेका थियौं, जुन उत्तम छैन पनि सक्छ। याद गर्नुहोस् कि हामीले सबैभन्दा राम्रो प्रदर्शन गर्ने Q-टेबललाई `Qbest` परिवर्तनशीलमा भण्डारण गरेका छौं! `Qbest` लाई `Q` मा कपी गरेर उत्तम प्रदर्शन गर्ने Q-टेबलसँग उही उदाहरण प्रयास गर्नुहोस् र के फरक छ भनेर हेर्नुहोस्। > **कार्य ४**: यहाँ हामी प्रत्येक कदममा सबैभन्दा राम्रो कार्य चयन गरिरहेका थियैनौं, बरु सम्बद्ध सम्भावना वितरण अनुसार नमूना गर्दै थियौं। के सधैं सबैभन्दा राम्रो कार्य, जसको Q-टेबल मान सबैभन्दा बढी छ, चयन गर्दा बढी मतलब लाग्दछ? यो `np.argmax` फङ्सन प्रयोग गरेर सबैभन्दा बढी Q-टेबल मान भएको कार्य नम्बर थाहा पाउन सकिन्छ। यो रणनीति कार्यान्वयन गर्नुहोस् र हेर्नुहोस् के यसले सन्तुलन सुधार्छ कि होइन। ## [पाठ-पछि क्विज](https://ff-quizzes.netlify.app/en/ml/) ## असाइन्मेन्ट [एउटा माउन्टेन कार तालिम गर्नुहोस्](assignment.md) ## निष्कर्ष हामीले अब सिक्यौं कसरी एजेन्टहरुलाई राम्रो नतिजा पाउनको लागि एउटा पुरस्कार कार्य प्रदान गरेर, जुन खेलको इच्छित अवस्थालाई परिभाषित गर्छ, र उनीहरुलाई बुद्धिमत्तापूर्वक खोज क्षेत्र अनुसन्धान गर्ने अवसर दिएर प्रशिक्षित गर्ने। हामीले Q-लर्निङ एल्गोरिदमलाई द्विसंख्य र निरन्तर वातावरणहरूमा सफलतापूर्वक लागू गरेका छौं, तर द्विसंख्य क्रियाहरुसँग। त्यस्तै, यस्तो अवस्था अध्ययन गर्नु पनि महत्त्वपूर्ण छ जहाँ क्रिया अवस्था पनि निरन्तर हुन्छ, र अवलोकन क्षेत्र धेरै जटिल हुन्छ, जस्तै एटारी गेम स्क्रिनबाट आएका छविहरू। ती समस्याहरुमा सामान्यतः प्रभावकारी नतिजा प्राप्त गर्न अधिक सक्षम मेसिन लर्निङ प्रविधिहरु, जस्तै न्यूरल नेटवर्कहरू प्रयोग गर्नुपर्ने हुन्छ। ती उन्नत विषयहरू हाम्रो आगामी उन्नत AI कोर्सको विषय हुन्। --- **अस्वीकरण**: यो दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) प्रयोग गरेर अनुवाद गरिएको हो। हामी सही हुन प्रयास गर्छौं, तर कृपया जानकार हुनुस् कि स्वचालित अनुवादमा त्रुटिहरू वा अशुद्धताहरू हुन सक्छन्। मूल दस्तावेज़ यसको मूल भाषामा आधिकारिक स्रोत मानिनुपर्छ। महत्वपूर्ण जानकारीका लागि व्यावसायिक मानव अनुवाद सिफारिस गरिन्छ। यस अनुवादको प्रयोगबाट उत्पन्न कुनै पनि गलत बुझाइ वा त्रुटिको लागि हामी जिम्मेवार छैनौं।