## आवश्यकताहरू यस पाठमा, हामी **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/) द्वारा व्यवस्थापन गरिन्छ। यस जिम प्रयोग गरेर हामी विभिन्न **पर्यावरणहरू** सिर्जना गर्न सक्छौं, जस्तै cartpole अनुकरणदेखि Atari खेलहरूसम्म। > **Note**: तपाईं 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 ``` ## अभ्यास - cartpole वातावरण आरम्भ गर्नुहोस् cartpole सन्तुलन समस्यामा काम गर्न, हामीले सम्बन्धित वातावरण आरम्भ गर्न आवश्यक छ। प्रत्येक वातावरणसँग निम्न कुरा सम्बन्धित हुन्छ: - **Observation space** जसले वातावरणबाट प्राप्त हुने जानकारीको संरचना परिभाषित गर्दछ। cartpole समस्याको लागि, हामी पोलको स्थिति, वेग र केही अन्य मानहरू प्राप्त गर्छौं। - **Action space** जसले सम्भावित कार्यहरू परिभाषित गर्दछ। हाम्रो केसमा, action space discrete छ, र दुई कार्यहरू समावेश गर्दछ - **बायाँ** र **दायाँ**। (कोड ब्लक 2) 1. आरम्भ गर्न, निम्न कोड टाइप गर्नुहोस्: ```python env = gym.make("CartPole-v1") print(env.action_space) print(env.observation_space) print(env.action_space.sample()) ``` वातावरण कसरी काम गर्छ हेर्न, 100 चरणहरूको लागि छोटो अनुकरण चलाऔं। प्रत्येक चरणमा, हामीले कार्यहरू प्रदान गर्नुपर्छ - यस अनुकरणमा हामी `action_space` बाट जस्तोसुकै कार्य चयन गर्छौं। 1. तलको कोड चलाउनुहोस् र यसले के परिणाम दिन्छ हेर्नुहोस्। ✅ यो कोड स्थानीय Python स्थापना मा चलाउनु राम्रो हुन्छ! (कोड ब्लक 3) ```python env.reset() for i in range(100): env.render() env.step(env.action_space.sample()) env.close() ``` तपाईंले निम्न चित्र जस्तै केही देख्नुपर्छ: ![non-balancing cartpole](../../../../8-Reinforcement/2-Gym/images/cartpole-nobalance.gif) 1. अनुकरणको क्रममा, हामीले निर्णय गर्नको लागि अवलोकनहरू प्राप्त गर्न आवश्यक छ। वास्तवमा, `step` कार्यले वर्तमान अवलोकनहरू, पुरस्कार कार्य, र `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) ``` तपाईंले यो पनि देख्न सक्नुहुन्छ कि प्रत्येक अनुकरण चरणमा पुरस्कार मान सधैं 1 हुन्छ। यसको कारण हाम्रो लक्ष्य यथासम्भव लामो समयसम्म जीवित रहनु हो, अर्थात पोललाई यथासम्भव ठाडो स्थितिमा राख्नु। ✅ वास्तवमा, CartPole अनुकरणलाई समाधान गरिएको मानिन्छ यदि हामीले 100 लगातार प्रयासहरूमा 195 को औसत पुरस्कार प्राप्त गर्न सफल भयौं। ## अवस्था डिस्क्रिटाइजेसन Q-Learning मा, हामीले Q-Table निर्माण गर्न आवश्यक छ जसले प्रत्येक अवस्थामा के गर्ने परिभाषित गर्दछ। यो गर्नको लागि, अवस्था **डिस्क्रिट** हुनुपर्छ, अधिक स्पष्ट रूपमा, यसले सीमित संख्याका डिस्क्रिट मानहरू समावेश गर्नुपर्छ। त्यसैले, हामीले कुनै प्रकारले हाम्रो अवलोकनहरू **डिस्क्रिटाइज** गर्न आवश्यक छ, तिनीहरूलाई सीमित सेटको अवस्थाहरूमा म्याप गर्दै। यसलाई गर्नका लागि केही तरिकाहरू छन्: - **बिनहरूमा विभाजन गर्नुहोस्**। यदि हामीलाई कुनै मानको अन्तराल थाहा छ भने, हामी यस अन्तराललाई केही **बिनहरू** मा विभाजन गर्न सक्छौं, र त्यसपछि मानलाई यो बिन नम्बरले प्रतिस्थापन गर्न सक्छौं। यो numpy [`digitize`](https://numpy.org/doc/stable/reference/generated/numpy.digitize.html) विधि प्रयोग गरेर गर्न सकिन्छ। यस अवस्थामा, हामीलाई राज्यको आकार ठीकसँग थाहा हुनेछ, किनकि यो डिजिटलाइजेसनका लागि चयन गरिएको बिनहरूको संख्यामा निर्भर हुनेछ। ✅ हामीले मानहरूलाई केही सीमित अन्तरालमा (जस्तै, -20 देखि 20 सम्म) ल्याउन र त्यसपछि ती संख्याहरूलाई गोल गरेर पूर्णांकमा रूपान्तरण गर्न रेखीय इन्टरपोलेशन प्रयोग गर्न सक्छौं। यसले राज्यको आकारमा थोरै कम नियन्त्रण दिन्छ, विशेष गरी यदि हामीलाई इनपुट मानहरूको सटीक दायरा थाहा छैन। उदाहरणका लागि, हाम्रो केसमा 4 मध्ये 2 मानहरूको माथिल्लो/तल्लो सीमा छैन, जसले असीमित संख्याका अवस्थाहरू परिणाम दिन सक्छ। हाम्रो उदाहरणमा, हामी दोस्रो दृष्टिकोण अपनाउनेछौं। तपाईंले पछि देख्न सक्नुहुनेछ, अपरिभाषित माथिल्लो/तल्लो सीमाहरूको बाबजुद, ती मानहरू विरलै निश्चित सीमित अन्तराल बाहिर मानहरू लिन्छन्, त्यसैले ती चरम मानहरू भएका अवस्थाहरू धेरै दुर्लभ हुनेछन्। 1. यहाँ एउटा कार्य छ जसले हाम्रो मोडेलबाट अवलोकन लिन्छ र 4 पूर्णांक मानहरूको टपल उत्पादन गर्दछ: (कोड ब्लक 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)] # intervals of values for each parameter nbins = [20,20,10,10] # number of bins for each parameter 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-आधारित हुन्छ। त्यसैले इनपुट चरको मानहरू 0 वरिपरि हुँदा यसले अन्तरालको बीचबाट नम्बर फर्काउँछ (10)। `discretize` मा, हामीले आउटपुट मानहरूको दायराको बारेमा ध्यान दिएनौं, तिनीहरूलाई नकारात्मक हुन अनुमति दिँदै, त्यसैले राज्य मानहरू सरेका छैनन्, र 0 0 सँग मेल खान्छ। (कोड ब्लक 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-Learning प्रक्रियाको क्रममा यो "अदृश्य" कार्यान्वयन प्रयोग गर्नेछौं। ## Q-Table संरचना अघिल्लो पाठमा, अवस्था 0 देखि 8 सम्मका संख्याहरूको साधारण जोडी थियो, र यसैले Q-Table लाई 8x8x2 आकारको numpy टेन्सरद्वारा प्रतिनिधित्व गर्न सुविधाजनक थियो। यदि हामी बिन डिस्क्रिटाइजेसन प्रयोग गर्छौं भने, हाम्रो राज्य भेक्टरको आकार पनि थाहा छ, त्यसैले हामी समान दृष्टिकोण प्रयोग गर्न सक्छौं र राज्यलाई 20x20x10x10x2 आकारको एरेद्वारा प्रतिनिधित्व गर्न सक्छौं (यहाँ 2 कार्य स्थानको आयाम हो, र पहिलो आयामहरू अवलोकन स्थानमा प्रत्येक प्यारामिटरको लागि चयन गरिएको बिनहरूको संख्यालाई प्रतिनिधित्व गर्दछ)। तर, कहिलेकाहीं अवलोकन स्थानको सटीक आयामहरू थाहा हुँदैन। `discretize` कार्यको मामलामा, हामी कहिल्यै निश्चित हुन सक्दैनौं कि हाम्रो अवस्था निश्चित सीमाहरू भित्र रहन्छ, किनकि केही मूल मानहरू बाधित छैनन्। त्यसैले, हामी अलि फरक दृष्टिकोण प्रयोग गर्नेछौं र Q-Table लाई शब्दकोशद्वारा प्रतिनिधित्व गर्नेछौं। 1. जोडी *(state,action)* लाई शब्दकोश कुञ्जीको रूपमा प्रयोग गर्नुहोस्, र मान Q-Table प्रविष्टि मानसँग मेल खानेछ। (कोड ब्लक 9) ```python Q = {} actions = (0,1) def qvalues(state): return [Q.get((state,a),0) for a in actions] ``` यहाँ हामीले `qvalues()` नामक कार्य पनि परिभाषित गरेका छौं, जसले Q-Table मानहरूको सूची फर्काउँछ जुन दिइएको अवस्थाका लागि सबै सम्भावित कार्यहरूसँग मेल खान्छ। यदि प्रविष्टि Q-Table मा उपस्थित छैन भने, हामी डिफल्टको रूपमा 0 फर्काउनेछौं। ## अब Q-Learning सुरु गरौं अब हामी पिटरलाई सन्तुलन सिकाउन तयार छौं! 1. पहिले, केही हाइपरप्यारामिटरहरू सेट गरौं: (कोड ब्लक 10) ```python # hyperparameters alpha = 0.3 gamma = 0.9 epsilon = 0.90 ``` यहाँ, `alpha` **सिकाइ दर** हो जसले प्रत्येक चरणमा Q-Table को वर्तमान मानहरू कति हदसम्म समायोजन गर्नुपर्छ भनेर परिभाषित गर्दछ। अघिल्लो पाठमा हामीले 1 बाट सुरु गरेका थियौं, र त्यसपछि प्रशिक्षणको क्रममा `alpha` लाई कम मानहरूमा घटाएका थियौं। यस उदाहरणमा हामी यसलाई स्थिर राख्नेछौं केवल सरलताको लागि, र तपाईं पछि `alpha` मानहरू समायोजन गरेर प्रयोग गर्न सक्नुहुन्छ। `gamma` **डिस्काउन्ट फ्याक्टर** हो जसले भविष्यको पुरस्कारलाई वर्तमान पुरस्कारभन्दा कति प्राथमिकता दिनुपर्छ भनेर देखाउँछ। `epsilon` **अन्वेषण/शोषण फ्याक्टर** हो जसले हामीले अन्वेषणलाई शोषणमा प्राथमिकता दिनुपर्छ कि उल्टो भनेर निर्धारण गर्दछ। हाम्रो एल्गोरिदममा, हामी `epsilon` प्रतिशत केसहरूमा Q-Table मानहरू अनुसार अर्को कार्य चयन गर्नेछौं, र बाँकी केसहरूमा हामी जस्तोसुकै कार्य कार्यान्वयन गर्नेछौं। यसले हामीलाई खोज स्थानका क्षेत्रहरू अन्वेषण गर्न अनुमति दिनेछ जुन हामीले पहिले कहिल्यै देखेका छैनौं। ✅ सन्तुलनको सन्दर्भमा - जस्तोसुकै कार्य चयन गर्नु (अन्वेषण) गलत दिशामा एक प्रकारको अनियमित धक्का जस्तै कार्य गर्नेछ, र पोलले ती "गल्तीहरू" बाट सन्तुलन पुन: प्राप्त गर्न सिक्नुपर्नेछ। ### एल्गोरिदम सुधार गर्नुहोस् हामी अघिल्लो पाठबाट हाम्रो एल्गोरिदममा दुई सुधारहरू गर्न सक्छौं: - **औसत संचयी पुरस्कार गणना गर्नुहोस्**, धेरै अनुकरणहरूमा। हामी प्रत्येक 5000 पुनरावृत्तिमा प्रगति प्रिन्ट गर्नेछौं, र हामी त्यस अवधिको समयको लागि हाम्रो संचयी पुरस्कारलाई औसत गर्नेछौं। यसको मतलब यदि हामीले 195 भन्दा बढी अंक प्राप्त गर्यौं भने - हामीले समस्या समाधान गरेको मान्न सक्छौं, आवश्यकताभन्दा उच्च गुणस्तरको साथ। - **अधिकतम औसत संचयी परिणाम गणना गर्नुहोस्**, `Qmax`, र हामीले प्रशिक्षणको क्रममा देखिएको सबैभन्दा राम्रो मोडेलसँग मेल खाने Q-Table भण्डारण गर्नेछौं। जब तपाईंले प्रशिक्षण चलाउनुहुन्छ, तपाईंले देख्नुहुनेछ कि कहिलेकाहीं औसत संचयी परिणाम घट्न थाल्छ, र हामीले Q-Table को मानहरू राख्न चाहन्छौं जुन खराब स्थिति बनाउने मानहरूसँग मेल खान्छ। 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 # == do the simulation == while not done: s = discretize(obs) if random.random() Qmax: Qmax = np.average(cum_rewards) Qbest = Q cum_rewards=[] ``` तपाईंले ती परिणामहरूबाट निम्न कुरा देख्न सक्नुहुन्छ: - **हाम्रो लक्ष्य नजिक**। हामी 100+ लगातार अनुकरणहरूको औसत पुरस्कार 195 प्राप्त गर्ने लक्ष्य प्राप्त गर्न धेरै नजिक छौं, वा हामीले वास्तवमा यसलाई प्राप्त गर्यौं! यदि हामीले साना संख्याहरू प्राप्त गर्यौं भने पनि, हामी अझै थाहा पाउँदैनौं, किनकि हामी 5000 रनहरूमा औसत गर्छौं, र औपचारिक मापदण्डमा केवल 100 रन आवश्यक छ। - **पुरस्कार घट्न थाल्छ**। कहिलेकाहीं पुरस्कार घट्न थाल्छ, जसको मतलब हामीले Q-Table मा पहिले सिकेका मानहरूलाई "नष्ट" गर्न सक्छौं जसले स्थिति खराब बनाउने मानहरूसँग मेल खान्छ। यो अवलोकन अझ स्पष्ट रूपमा देखिन्छ यदि हामी प्रशिक्षण प्रगति प्लट गर्छौं। ## प्रशिक्षण प्रगति प्लटिङ प्रशिक्षणको क्रममा, हामीले प्रत्येक पुनरावृत्तिमा संचयी पुरस्कार मानलाई `rewards` भेक्टरमा संकलन गरेका छौं। यहाँ यो पुनरावृत्ति नम्बरको विरुद्धमा प्लट गर्दा कस्तो देखिन्छ: ```python plt.plot(rewards) ``` ![raw progress](../../../../8-Reinforcement/2-Gym/images/train_progress_raw.png) यस ग्राफबाट केही भन्न सम्भव छैन, किनकि स्टोकेस्टिक प्रशिक्षण प्रक्रियाको प्रकृतिका कारण प्रशिक्षण सत्रहरूको लम्बाइ धेरै भिन्न हुन्छ। यस ग्राफलाई अझ अर्थपूर्ण बनाउन, हामी 100 जस्तै प्रयोगहरूको श्रृंखलामा **चलिरहेको औसत** गणना गर्न सक्छौं। यो `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)) ``` ![training progress](../../../../8-Reinforcement/2-Gym/images/train_progress_runav.png) ## हाइपरप्यारामिटरहरू फरक पार्दै सिकाइलाई अझ स्थिर बनाउन, प्रशिक्षणको क्रममा केही हाइपरप्यारामिटरहरू समायोजन गर्नु उपयुक्त हुन्छ। विशेष गरी: - **सिकाइ दरको लागि**, `alpha`, हामी 1 नजिकको मानबाट सुरु गर्न सक्छौं, र त्यसपछि प्यारामिटर घटाउन जारी राख्न सक्छौं। समयसँगै, हामीले Q-Table मा राम्रो सम्भावना मानहरू प्राप्त गर्नेछौं, र त्यसैले हामीले तिनीहरूलाई थोरै समायोजन गर्नुपर्छ, र नयाँ मानहरूसँग पूर्ण रूपमा ओभरराइट गर्नु हुँदैन। - **epsilon बढाउनुहोस्**। हामीले `epsilon` लाई बिस्तारै बढाउन चाहन सक्छौं, कम अन्वेषण गर्न र बढी शोषण गर्न। सम्भवतः `epsilon` को कम मानबाट सुरु गर्नु र लगभग 1 सम्म बढाउनु उपयुक्त हुन्छ। > **कार्य १**: हाइपरप्यारामिटरका मानहरू परिवर्तन गरेर खेल्नुहोस् र उच्च क्युमुलेटिभ पुरस्कार प्राप्त गर्न सक्नुहुन्छ कि हेर्नुहोस्। के तपाईं १९५ भन्दा माथि प्राप्त गर्दै हुनुहुन्छ? > **कार्य २**: समस्यालाई औपचारिक रूपमा समाधान गर्न, तपाईंले १०० लगातार रनहरूमा १९५ औसत इनाम प्राप्त गर्नुपर्नेछ। प्रशिक्षणको क्रममा यो मापन गर्नुहोस् र सुनिश्चित गर्नुहोस् कि तपाईंले समस्यालाई औपचारिक रूपमा समाधान गर्नुभएको छ! ## नतिजा कार्यान्वयनमा हेर्दै यो हेर्न रोचक हुनेछ कि प्रशिक्षित मोडेल कसरी व्यवहार गर्छ। आउनुहोस्, सिमुलेशन चलाउँछौं र प्रशिक्षणको क्रममा जस्तै कार्य चयन रणनीति अनुसरण गरौं, Q-Table मा रहेको सम्भाव्यता वितरण अनुसार नमूना लिऔं: (कोड ब्लक १३) ```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() ``` तपाईंले केही यस प्रकारको देख्नुहुनेछ: ![एक सन्तुलित कार्टपोल](../../../../8-Reinforcement/2-Gym/images/cartpole-balance.gif) --- ## 🚀चुनौती > **कार्य ३**: यहाँ हामीले Q-Table को अन्तिम प्रतिलिपि प्रयोग गरिरहेका थियौं, जुन सधैं उत्तम नहुन सक्छ। सम्झनुहोस् कि हामीले सबैभन्दा राम्रो प्रदर्शन गर्ने Q-Table लाई `Qbest` भेरिएबलमा भण्डारण गरेका छौं! `Qbest` लाई `Q` मा प्रतिलिपि गरेर, उही उदाहरण प्रयास गर्नुहोस् र के तपाईंले कुनै फरक देख्नुहुन्छ कि हेर्नुहोस्। > **कार्य ४**: यहाँ हामीले प्रत्येक चरणमा सबैभन्दा राम्रो कार्य चयन गरिरहेका थिएनौं, बरु सम्बन्धित सम्भाव्यता वितरणसँग नमूना लिइरहेका थियौं। के यो सधैं सबैभन्दा राम्रो कार्य चयन गर्न अधिक उपयुक्त हुनेछ, जसको Q-Table मान सबैभन्दा उच्च छ? यो `np.argmax` फंक्शन प्रयोग गरेर, सबैभन्दा उच्च Q-Table मानसँग सम्बन्धित कार्य नम्बर पत्ता लगाएर गर्न सकिन्छ। यो रणनीति कार्यान्वयन गर्नुहोस् र के यसले सन्तुलन सुधार गर्छ कि हेर्नुहोस्। ## [पोस्ट-व्याख्यान क्विज](https://ff-quizzes.netlify.app/en/ml/) ## असाइनमेन्ट [माउन्टेन कारलाई प्रशिक्षण दिनुहोस्](assignment.md) ## निष्कर्ष हामीले अब एजेन्टहरूलाई राम्रो नतिजा प्राप्त गर्न कसरी प्रशिक्षण दिने भनेर सिकेका छौं, केवल तिनीहरूलाई खेलको इच्छित अवस्थालाई परिभाषित गर्ने इनाम फंक्शन प्रदान गरेर, र तिनीहरूलाई खोज स्थानलाई बुद्धिमानीपूर्वक अन्वेषण गर्ने अवसर दिएर। हामीले Q-Learning एल्गोरिदमलाई छुट्टै र निरन्तर वातावरणहरूको अवस्थामा सफलतापूर्वक लागू गरेका छौं, तर छुट्टै कार्यहरूसँग। यो पनि अध्ययन गर्नु महत्त्वपूर्ण छ कि जहाँ कार्य अवस्था पनि निरन्तर हुन्छ, र अवलोकन स्थान धेरै जटिल हुन्छ, जस्तै Atari खेलको स्क्रिनबाट आएको छवि। यस्ता समस्याहरूमा हामीले प्रायः राम्रो नतिजा प्राप्त गर्न थप शक्तिशाली मेसिन लर्निङ प्रविधिहरू, जस्तै न्यूरल नेटवर्कहरू, प्रयोग गर्न आवश्यक पर्छ। ती थप उन्नत विषयवस्तुहरू हाम्रो आगामी उन्नत AI पाठ्यक्रमको विषयवस्तु हुन्। --- **अस्वीकरण**: यो दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) प्रयोग गरेर अनुवाद गरिएको छ। हामी शुद्धताको लागि प्रयास गर्छौं, तर कृपया ध्यान दिनुहोस् कि स्वचालित अनुवादमा त्रुटिहरू वा अशुद्धताहरू हुन सक्छ। यसको मूल भाषा मा रहेको मूल दस्तावेज़लाई आधिकारिक स्रोत मानिनुपर्छ। महत्वपूर्ण जानकारीको लागि, व्यावसायिक मानव अनुवाद सिफारिस गरिन्छ। यस अनुवादको प्रयोगबाट उत्पन्न हुने कुनै पनि गलतफहमी वा गलत व्याख्याको लागि हामी जिम्मेवार हुने छैनौं।