日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ML-Agents案例之看图配对

發(fā)布時(shí)間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ML-Agents案例之看图配对 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本案例源自ML-Agents官方的示例,Github地址:https://github.com/Unity-Technologies/ml-agents,本文是詳細(xì)的配套講解。

本文基于我前面發(fā)的兩篇文章,需要對(duì)ML-Agents有一定的了解,詳情請(qǐng)見(jiàn):Unity強(qiáng)化學(xué)習(xí)之ML-Agents的使用、ML-Agents命令及配置大全。

我前面的相關(guān)文章有:

ML-Agents案例之Crawler

ML-Agents案例之推箱子游戲

ML-Agents案例之跳墻游戲

ML-Agents案例之食物收集者

ML-Agents案例之雙人足球

Unity人工智能之不斷自我進(jìn)化的五人足球賽

ML-Agents案例之地牢逃脫

ML-Agents案例之金字塔

ML-Agents案例之蠕蟲

ML-Agents案例之機(jī)器人學(xué)走路

環(huán)境說(shuō)明

如圖所示,這個(gè)案例官方稱其為Hallway,智能體需要根據(jù)前面給的符號(hào)來(lái)去后面選擇對(duì)應(yīng)的符號(hào),注意,這個(gè)案例的難點(diǎn)在于,智能體在選擇時(shí)是看不到給定的符號(hào)的,而我們的程序并不會(huì)幫助智能體去記錄看過(guò)的信息,這就要求智能體自己擁有記憶功能,即神經(jīng)網(wǎng)絡(luò)能夠自己學(xué)習(xí)出“以前看到過(guò)什么現(xiàn)在就選什么”這種行為模式,因此擁有記憶功能的循環(huán)神經(jīng)網(wǎng)絡(luò)中的大哥LSTM是必不可少的。而這在ML-Agents中只需要配置一下文件就能做到。

狀態(tài)輸入:首先智能體用了射線傳感器Ray Perception Sensor 3D,一共發(fā)射5條射線,檢測(cè)的標(biāo)簽有給定的O、給定的X、目標(biāo)的O、目標(biāo)的X、墻壁,一共5個(gè)標(biāo)簽。對(duì)于射線傳感器的詳細(xì)講解請(qǐng)查看ML-Agents案例之推箱子游戲。

另外,程序中還給了一個(gè)已執(zhí)行的步數(shù)除以最大步數(shù)來(lái)作為輸入,隨著游戲的運(yùn)行而增大,當(dāng)episode結(jié)束時(shí)這個(gè)值會(huì)等于1,個(gè)人認(rèn)為這個(gè)輸入作用不大,可有可無(wú)。

動(dòng)作輸出:動(dòng)作輸出只有一個(gè)離散輸出,這個(gè)輸出有0-4共5個(gè)值可供選擇。0代表什么都不做,1代表前進(jìn),2代表后退,3代表右轉(zhuǎn),4代表左轉(zhuǎn)。

因此Behavior Parameters設(shè)置如下:

代碼講解

智能體下掛載的腳本除去萬(wàn)年不變的Decesion Requester,Model Overrider,Behavior Parameters,以及剛剛說(shuō)明的Ray Perception Sensor 3D,就只剩下智能體的只有文件HallwayAgent.cs了:

初始化方法Initialize():

public override void Initialize() {// 尋找控制環(huán)境的腳本m_HallwaySettings = FindObjectOfType<HallwaySettings>();// 獲取剛體m_AgentRb = GetComponent<Rigidbody>();// 獲取渲染,便于改變材質(zhì)m_GroundRenderer = ground.GetComponent<Renderer>();// 獲取初始材質(zhì)m_GroundMaterial = m_GroundRenderer.material;// 獲取配置文件中的數(shù)據(jù)m_statsRecorder = Academy.Instance.StatsRecorder; }

狀態(tài)輸入CollectObservations方法:

public override void CollectObservations(VectorSensor sensor) {// 可在編輯器中選擇用或不用if (useVectorObs){// 輸入現(xiàn)在已執(zhí)行步數(shù)除以最大步數(shù)sensor.AddObservation(StepCount / (float)MaxStep);} }

動(dòng)作輸出方法OnActionReceived:

public override void OnActionReceived(ActionBuffers actionBuffers) {// 時(shí)間懲罰,激勵(lì)智能體越快完成越好AddReward(-1f / MaxStep);MoveAgent(actionBuffers.DiscreteActions); }public void MoveAgent(ActionSegment<int> act) {var dirToGo = Vector3.zero;var rotateDir = Vector3.zero;// 獲取神經(jīng)網(wǎng)絡(luò)的第一個(gè)也是唯一一個(gè)離散輸出var action = act[0];// 給離散輸出賦予各個(gè)值的意義switch (action){case 1:dirToGo = transform.forward * 1f;break;case 2:dirToGo = transform.forward * -1f;break;case 3:rotateDir = transform.up * 1f;break;case 4:rotateDir = transform.up * -1f;break;}// 執(zhí)行輸出transform.Rotate(rotateDir, Time.deltaTime * 150f);m_AgentRb.AddForce(dirToGo * m_HallwaySettings.agentRunSpeed, ForceMode.VelocityChange); }

每一個(gè)episode(回合)開(kāi)始時(shí)執(zhí)行的方法OnEpisodeBegin:

public override void OnEpisodeBegin() {var agentOffset = -15f;var blockOffset = 0f;// 取隨機(jī)數(shù)0或1m_Selection = Random.Range(0, 2);// 如果是0,場(chǎng)上出現(xiàn)O,位置作一定的隨機(jī)if (m_Selection == 0){symbolO.transform.position =new Vector3(0f + Random.Range(-3f, 3f), 2f, blockOffset + Random.Range(-5f, 5f))+ ground.transform.position;symbolX.transform.position =new Vector3(0f, -1000f, blockOffset + Random.Range(-5f, 5f))+ ground.transform.position;}// 如果是1,場(chǎng)上出現(xiàn)X,位置作一定的隨機(jī)else{symbolO.transform.position =new Vector3(0f, -1000f, blockOffset + Random.Range(-5f, 5f))+ ground.transform.position;symbolX.transform.position =new Vector3(0f, 2f, blockOffset + Random.Range(-5f, 5f))+ ground.transform.position;}// 初始化智能體的位置和旋轉(zhuǎn),并作一定的隨機(jī),速度歸零transform.position = new Vector3(0f + Random.Range(-3f, 3f),1f, agentOffset + Random.Range(-5f, 5f))+ ground.transform.position;transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);m_AgentRb.velocity *= 0f;// 取隨機(jī)數(shù)0或1var goalPos = Random.Range(0, 2);// 當(dāng)隨機(jī)數(shù)為0時(shí),目標(biāo)的O放右邊,X放左邊if (goalPos == 0){symbolOGoal.transform.position = new Vector3(7f, 0.5f, 22.29f) + area.transform.position;symbolXGoal.transform.position = new Vector3(-7f, 0.5f, 22.29f) + area.transform.position;}// 當(dāng)隨機(jī)數(shù)為1時(shí),目標(biāo)的O放左邊,X放右邊else{symbolXGoal.transform.position = new Vector3(7f, 0.5f, 22.29f) + area.transform.position;symbolOGoal.transform.position = new Vector3(-7f, 0.5f, 22.29f) + area.transform.position;}// 添加用于報(bào)告的統(tǒng)計(jì)信息(鍵值對(duì)),這些值將出現(xiàn)在Tensorboard中m_statsRecorder.Add("Goal/Correct", 0, StatAggregationMethod.Sum);m_statsRecorder.Add("Goal/Wrong", 0, StatAggregationMethod.Sum); }

這里需要說(shuō)明的是最后兩行代碼是在Tensorboard添加了兩個(gè)新的表格,第一個(gè)參數(shù)是表格的標(biāo)簽,即鍵,第二個(gè)是指,第三個(gè)是可選的變量,可選的有Average,MostRecent,Sum,Histogram。

當(dāng)與別的物體開(kāi)始發(fā)生碰撞執(zhí)行方法OnCollisionEnter:

void OnCollisionEnter(Collision col) {if (col.gameObject.CompareTag("symbol_O_Goal") || col.gameObject.CompareTag("symbol_X_Goal")){// 當(dāng)匹配成果時(shí)if ((m_Selection == 0 && col.gameObject.CompareTag("symbol_O_Goal")) ||(m_Selection == 1 && col.gameObject.CompareTag("symbol_X_Goal"))){// 獎(jiǎng)勵(lì)1分SetReward(1f);// 改變成綠色的材質(zhì)0.5秒StartCoroutine(GoalScoredSwapGroundMaterial(m_HallwaySettings.goalScoredMaterial, 0.5f));// 在Tensorboard成功項(xiàng)中給智能體加一分m_statsRecorder.Add("Goal/Correct", 1, StatAggregationMethod.Sum);}// 當(dāng)匹配失敗時(shí)else{SetReward(-0.1f);StartCoroutine(GoalScoredSwapGroundMaterial(m_HallwaySettings.failMaterial, 0.5f));// 在Tensorboard失敗項(xiàng)中給智能體加一分m_statsRecorder.Add("Goal/Wrong", 1, StatAggregationMethod.Sum);}// 結(jié)束游戲EndEpisode();} }// 攜程,短暫改變材質(zhì) IEnumerator GoalScoredSwapGroundMaterial(Material mat, float time) {m_GroundRenderer.material = mat;yield return new WaitForSeconds(time);m_GroundRenderer.material = m_GroundMaterial; }

當(dāng)智能體沒(méi)有模型,人想手動(dòng)錄制示例時(shí)可以采用Heuristic方法:

public override void Heuristic(in ActionBuffers actionsOut) {var discreteActionsOut = actionsOut.DiscreteActions;if (Input.GetKey(KeyCode.D)){discreteActionsOut[0] = 3;}else if (Input.GetKey(KeyCode.W)){discreteActionsOut[0] = 1;}else if (Input.GetKey(KeyCode.A)){discreteActionsOut[0] = 4;}else if (Input.GetKey(KeyCode.S)){discreteActionsOut[0] = 2;} }

配置文件

PPO算法:

behaviors:Hallway:trainer_type: ppohyperparameters:batch_size: 128buffer_size: 1024learning_rate: 0.0003beta: 0.03epsilon: 0.2lambd: 0.95num_epoch: 3learning_rate_schedule: linearnetwork_settings:normalize: falsehidden_units: 128num_layers: 2vis_encode_type: simplememory:sequence_length: 64memory_size: 128reward_signals:extrinsic:gamma: 0.99strength: 1.0keep_checkpoints: 5max_steps: 10000000time_horizon: 64summary_freq: 10000

SAC算法:

behaviors:Hallway:trainer_type: sachyperparameters:learning_rate: 0.0003learning_rate_schedule: constantbatch_size: 512buffer_size: 200000buffer_init_steps: 0tau: 0.005steps_per_update: 10.0save_replay_buffer: falseinit_entcoef: 0.1reward_signal_steps_per_update: 10.0network_settings:normalize: falsehidden_units: 128num_layers: 2vis_encode_type: simplememory:sequence_length: 64memory_size: 128reward_signals:extrinsic:gamma: 0.99strength: 1.0keep_checkpoints: 5max_steps: 4000000time_horizon: 64summary_freq: 10000

可以看到,相比也平常的配置,中間加入了一部分:

memory:sequence_length: 64memory_size: 128

默認(rèn)不加這部分的時(shí)候,我們的模型中是沒(méi)有循環(huán)神經(jīng)網(wǎng)絡(luò)的,當(dāng)我們?cè)O(shè)置了這個(gè)參數(shù)后,相當(dāng)于給模型加入了一個(gè)LSTM,sequence_length指的是需要記住的經(jīng)驗(yàn)序列長(zhǎng)度,memory_size是智能體保存的記憶大小,必須是2的倍數(shù)。我們要合理設(shè)置參數(shù),設(shè)置過(guò)大將大大降低訓(xùn)練速度,過(guò)小會(huì)導(dǎo)致記不住東西。

效果演示

后記

本案例主要探討了ML-Agents中智能體的“記憶力”是怎么實(shí)現(xiàn)的,我們可以通過(guò)在配置文件中設(shè)置相應(yīng)的參數(shù)來(lái)給我們的模型添加上LSTM,讓智能體先觀察,后做“選擇題”,就能訓(xùn)練出一個(gè)具有記憶力的智能體。

總結(jié)

以上是生活随笔為你收集整理的ML-Agents案例之看图配对的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。