Agents設(shè)計(jì)
Agent是一個(gè)能夠觀察其所在的環(huán)境并使用這些觀察結(jié)果來(lái)決定最佳行動(dòng)方案的行動(dòng)者。 在Unity中通過(guò)擴(kuò)展Agent類創(chuàng)建agents待诅。 對(duì)于增強(qiáng)學(xué)習(xí)來(lái)說(shuō)春宣,要?jiǎng)?chuàng)建可以成功學(xué)習(xí)的agents,最重要的方面是独榴,agents收集的觀察結(jié)果和你分配的reward贮尉,其中reward用于評(píng)估智能體當(dāng)前狀態(tài)對(duì)完成其任務(wù)的價(jià)值块饺。
Agent將其觀察結(jié)果傳遞給其Brain耻陕。 然后,Brain做出決定并將選定的動(dòng)作傳遞回agent刨沦。 你的agent代碼必須執(zhí)行該動(dòng)作诗宣,例如,將agent向一個(gè)方向或另一個(gè)方向移動(dòng)想诅。 為了使用增強(qiáng)學(xué)習(xí)來(lái)訓(xùn)練agent召庞,必須在每次行動(dòng)中計(jì)算對(duì)agent的獎(jiǎng)勵(lì)值。 該獎(jiǎng)勵(lì)用于發(fā)現(xiàn)最佳決策策略来破。(對(duì)于已經(jīng)訓(xùn)練好的agent或模仿學(xué)習(xí)不會(huì)使用獎(jiǎng)勵(lì)篮灼。)
Brain類從agent本身抽象出決策邏輯,以便對(duì)多個(gè)agents中使用同一個(gè)Brain徘禁。 Brain如何做出決策取決于它的Brain類型诅诱。 External Brain簡(jiǎn)單地將來(lái)自agent的觀察結(jié)果傳遞給外部進(jìn)程,然后外部進(jìn)程的決策結(jié)果再傳回給agent送朱。 Internal brain使用訓(xùn)練完成的策略參數(shù)來(lái)制定決策(并且不再調(diào)整參數(shù)以尋找更好的決策)娘荡。其他類型的Brain不直接涉及訓(xùn)練干旁,但你可能會(huì)發(fā)現(xiàn)它們作為訓(xùn)練項(xiàng)目的一部分很有用。
決策 Decisions
你可以配置模擬步數(shù)炮沐,使得“觀察-決策-動(dòng)作-獎(jiǎng)勵(lì)”這個(gè)周期在一定的模擬步數(shù)后執(zhí)行一次(頻率默認(rèn)為每步一次)(這句話根據(jù)自己的理解翻譯的)争群。 你還可以設(shè)置agent根據(jù)需求請(qǐng)求決策。 以固定步長(zhǎng)間隔進(jìn)行決策通常最適合基于物理學(xué)的模擬大年。 根據(jù)需求做出決策通常適用于agent僅響應(yīng)特定事件或采取不同持續(xù)時(shí)間的行動(dòng)的情況换薄。 例如,機(jī)器人模擬器中的agent必須提供關(guān)節(jié)力矩的精確控制翔试,因此應(yīng)該在模擬的每一步中做出決定轻要。 另一方面,只有在特定游戲或模擬事件發(fā)生時(shí)垦缅,agent才需要使用按需決策(on-demand decision making)伦腐。
要控制基于step決策的頻率,請(qǐng)?jiān)赨nity Inspector窗口中設(shè)置Agent對(duì)象的決策頻率值(Decision Frequency)失都。具有相同Brain實(shí)例的agents可以使用不同的頻率。在沒(méi)有決策請(qǐng)求的模擬步驟中幸冻,agent收到的是與先前決策所選擇的相同動(dòng)作粹庞。
按需決策 On Demand Decision Making
按需決策允許agetns只在需要時(shí)才從Brain請(qǐng)求決策,而不是以固定頻率接收決策洽损。 當(dāng)agent承諾采取可變數(shù)量的步數(shù)或者agents無(wú)法同時(shí)作出決策時(shí)庞溜,這非常有用。 這種情況通常是基于回合的游戲碑定,該游戲中agetns必須對(duì)事件作出反應(yīng)流码,或者游戲中agetns做動(dòng)作之間的時(shí)間間隔是變化的情況。(多看幾個(gè)例子會(huì)對(duì)這里有更好的理解)
當(dāng)你打開agent的按需決策時(shí)延刘,agent代碼必須調(diào)用Agent.RequestDecision()函數(shù)漫试。 該函數(shù)調(diào)用開啟了一次“觀察-決策-動(dòng)作-獎(jiǎng)勵(lì)”周期的迭代。Brain調(diào)用agent的CollectObservations()方法碘赖,做出決策驾荣,然后通過(guò)調(diào)用AgentAction()方法返回它。 然后普泡,在開始下一次迭代之前播掷,Brain等待agent來(lái)請(qǐng)求下一次的決策。
觀察 Observations
為了做出決策撼班,agent必須觀察其環(huán)境以確定其當(dāng)前狀態(tài)歧匈。狀態(tài)觀察可以采取以下形式:
連續(xù)矢量(Continuous Vector) - 由數(shù)字?jǐn)?shù)組組成的特征矢量。
離散矢量(Discrete Vector) - 一個(gè)狀態(tài)表的索引(通常只對(duì)最簡(jiǎn)單的環(huán)境有用)砰嘁。
視覺(jué)觀察(Visual Observations) - 一個(gè)或多個(gè)相機(jī)圖像件炉。
當(dāng)agent使用連續(xù)或離散矢量觀察空間時(shí)勘究,請(qǐng)實(shí)現(xiàn)Agent.CollectObservations()方法以創(chuàng)建特征矢量或狀態(tài)索引。 當(dāng)使用Visual Observations時(shí)妻率,你只需確定哪個(gè)Unity Camera對(duì)象將提供圖像乱顾,Agent基類會(huì)處理其他事情的。 當(dāng)agent使用視覺(jué)觀察時(shí)(除非它也使用矢量觀測(cè))宫静,則不需要實(shí)現(xiàn)CollectObservations()方法走净。
連續(xù)觀察向量空間:特征向量
對(duì)于使用連續(xù)狀態(tài)空間的agent,可以創(chuàng)建一個(gè)特征向量來(lái)表示agent在模擬的每個(gè)步驟中的觀察結(jié)果孤里。 Brain類調(diào)用其每個(gè)agent的CollectObservations()方法伏伯。 你的這個(gè)函數(shù)的實(shí)現(xiàn)必須調(diào)用AddVectorObs來(lái)添加矢量觀察值。
觀察必須包括agent完成任務(wù)所需的所有信息捌袜。 沒(méi)有足夠的相關(guān)信息说搅,agent可能學(xué)習(xí)得不好,或者根本不會(huì)學(xué)習(xí)虏等。 確定應(yīng)包含哪些信息的一個(gè)合理方法是考慮你需要計(jì)算問(wèn)題的解決方案弄唧。
有關(guān)各種狀態(tài)觀察功能的示例,可以查看ML-Agents SDK中包含的示例環(huán)境霍衫。 例如候引,3DBall示例使用平臺(tái)的旋轉(zhuǎn),球的相對(duì)位置以及球的速度作為其狀態(tài)觀察敦跌。 作為一個(gè)實(shí)驗(yàn)澄干,你可以從觀察中移除速度分量并重新訓(xùn)練3DBall代理。 雖然它也會(huì)學(xué)會(huì)怎樣平衡球柠傍,但沒(méi)有使用速度的agent表現(xiàn)明顯更差麸俘。
public GameObject ball;
private List<float> state = new List<float>();
public override void CollectObservations()
{
AddVectorObs(gameObject.transform.rotation.z);
AddVectorObs(gameObject.transform.rotation.x);
AddVectorObs((ball.transform.position.x - gameObject.transform.position.x));
AddVectorObs((ball.transform.position.y - gameObject.transform.position.y));
AddVectorObs((ball.transform.position.z - gameObject.transform.position.z));
AddVectorObs(ball.transform.GetComponent<Rigidbody>().velocity.x);
AddVectorObs(ball.transform.GetComponent<Rigidbody>().velocity.y);
AddVectorObs(ball.transform.GetComponent<Rigidbody>().velocity.z);
}
特征向量必須包含相同數(shù)量的元素,并且觀察值必須始終位于列表中的相同位置惧笛。 如果環(huán)境中觀察到的實(shí)體的數(shù)量可能會(huì)發(fā)生變化从媚,則可以將該次觀察中的任何缺失實(shí)體填充為零,或者可以將agent的觀察限制為固定子集患整。例如静檬,不是觀察環(huán)境中的每個(gè)敵方agent,只能觀察最近的五個(gè)敵人agent并级。
當(dāng)你在Unity Editor中設(shè)置Agent的Brain時(shí)拂檩,請(qǐng)?jiān)O(shè)置以下屬性以使用連續(xù)矢量觀察:
Space Size 空間大小 - 狀態(tài)大小必須與特征向量的長(zhǎng)度相匹配。
Space Type 空間類型 - 設(shè)置為連續(xù)嘲碧。
Brain Type 大腦類型 - 訓(xùn)練期間設(shè)置為External; 使用訓(xùn)練好的模型時(shí)設(shè)置為Internal稻励。
觀察特征向量是浮點(diǎn)數(shù)列表,這意味著您必須將任何其他數(shù)據(jù)類型轉(zhuǎn)換為浮點(diǎn)數(shù)或浮點(diǎn)數(shù)列表。
整數(shù)可以直接添加到觀察向量中望抽。你必須將布爾值顯式轉(zhuǎn)換為數(shù)字:
AddVectorObs(isTrueOrFalse ? 1 : 0);
對(duì)于位置和旋轉(zhuǎn)等實(shí)體加矛,你可以將其組件單獨(dú)添加到特征列表中。 例如:
Vector3 speed = ball.transform.GetComponent<Rigidbody>().velocity;
AddVectorObs(speed.x);
AddVectorObs(speed.y);
AddVectorObs(speed.z);
類型枚舉應(yīng)該以one-hot風(fēng)格進(jìn)行編碼煤篙。 也就是說(shuō)斟览,為枚舉的每個(gè)元素添加一個(gè)元素到特征向量中,將表示觀察到的成員的元素設(shè)置為1辑奈,并將剩余的元素設(shè)置為零苛茂。 例如,如果你的枚舉包含[Sword鸠窗,Shield妓羊,Bow]并且agent觀察到當(dāng)前項(xiàng)是Bow,則可以將元素:0,0,1添加到特征向量中稍计。 以下代碼示例說(shuō)明了如何添加:
enum CarriedItems { Sword, Shield, Bow, LastItem }
private List<float> state = new List<float>();
public override void CollectObservations()
{
for (int ci = 0; ci < (int)CarriedItems.LastItem; ci++)
{
AddVectorObs((int)currentItem == ci ? 1.0f : 0.0f);
}
}
歸一化 Normalization
為了在訓(xùn)練時(shí)獲得最佳效果躁绸,應(yīng)將特征向量的分量歸一化到[-1,+1]或[0,1]范圍內(nèi)臣嚣。 當(dāng)你將這些值歸一化時(shí)净刮,PPO神經(jīng)網(wǎng)絡(luò)通常可以更快地收斂到解硅则。 請(qǐng)注意淹父,將這些推薦范圍歸一化并不總是必要的,但在使用神經(jīng)網(wǎng)絡(luò)時(shí)這被認(rèn)為是最佳實(shí)踐抢埋。 觀察部分之間的范圍變化越大,訓(xùn)練受到的影響就越大督暂。
旋轉(zhuǎn)和角度也應(yīng)該標(biāo)準(zhǔn)化揪垄。 對(duì)于0到360度之間的角度,可以使用以下公式:
Quaternion rotation = transform.rotation;
Vector3 normalized = rotation.eulerAngles / 180.0f - Vector3.one; // [-1,1]
Vector3 normalized = rotation.eulerAngles / 360.0f; // [0,1]`
對(duì)于可能超出范圍[0,360]的角度逻翁,或者減小角度饥努,或者增加標(biāo)準(zhǔn)化公式中使用的最大值。
多個(gè)視覺(jué)觀察 Multiple Visual Observations
Camera Observations使用場(chǎng)景中一個(gè)或多個(gè)camera渲染的紋理八回。Brain將紋理向量化并將它們送到神經(jīng)網(wǎng)絡(luò)中酷愧。 你可以同時(shí)使用Camera Observations和連續(xù)特征向量或離散狀態(tài)觀測(cè)。
使用相機(jī)圖像的agent可以捕獲任意復(fù)雜的狀態(tài)缠诅,并且在狀態(tài)難以用數(shù)字描述時(shí)很有用溶浴。可以捕獲任意復(fù)雜的狀態(tài)管引,并且在狀態(tài)難以用數(shù)字描述時(shí)很有用士败。 但是,他們通常效率較低,訓(xùn)練速度較慢谅将,有時(shí)甚至無(wú)法成功漾狼。
要向agent添加Visual Observations,請(qǐng)單擊agent inspector中的Add Camera按鈕饥臂。 然后將要添加的相機(jī)拖到相機(jī)區(qū)域逊躁。一個(gè)agent可以連接多臺(tái)攝像機(jī)。
另外隅熙,請(qǐng)確保agent的Brain期望進(jìn)行視覺(jué)觀察稽煤。 在Brain Inspector中,在Brain Parameters -> Visual Observations下猛们,指定agent用于視覺(jué)觀察的攝像機(jī)數(shù)量念脯。對(duì)于每個(gè)視覺(jué)觀察,設(shè)置圖像的寬度和高度(以像素為單位)以及觀察結(jié)果是彩色還是灰度(當(dāng)選中“ Black And White”時(shí))弯淘。
離散觀察向量空間:查找表 Discrete Vector Observation Space: Table Lookup
當(dāng)agent只有有限數(shù)量的可能狀態(tài)時(shí)绿店,可以使用離散觀察向量空間,并且這些狀態(tài)可以由單個(gè)數(shù)字枚舉庐橙。例如假勿,ML-Agents中的Basic示例環(huán)境定義了一個(gè)具有離散向量觀察空間的agent。該agent的狀態(tài)是兩個(gè)線性目標(biāo)之間的整數(shù)步驟态鳖。在Basic示例中转培,agent學(xué)習(xí)到的是,如何移動(dòng)到提供最大獎(jiǎng)勵(lì)的目標(biāo)浆竭。
更一般地浸须,離散觀察向量標(biāo)識(shí)符是可能狀態(tài)表中的索引。 然而邦泄,隨著環(huán)境變得越來(lái)越復(fù)雜删窒,查找表格很快變得笨拙。 例如顺囊,即使像井字游戲這樣的簡(jiǎn)單游戲也有765種可能的狀態(tài)(如果不能通過(guò)將旋轉(zhuǎn)或反射的方式來(lái)減少觀察次數(shù)肌索,則可能更多)。
要實(shí)現(xiàn)離散狀態(tài)觀察特碳,請(qǐng)執(zhí)行Agent子類的CollectObservations()方法并返回一個(gè)List诚亚,該list中每一個(gè)數(shù)字都標(biāo)識(shí)一個(gè)狀態(tài):
public override void CollectObservations()
{
AddVectorObs(stateIndex); // stateIndex is the state identifier
}
動(dòng)作向量 Vector Actions
動(dòng)作是agent執(zhí)行的Brain指令。 當(dāng)Academy調(diào)用agent的AgentAction()函數(shù)時(shí)午乓,該操作將作為參數(shù)傳遞給agent站宗。 當(dāng)動(dòng)作向量空間是連續(xù)時(shí),傳遞給agent的行動(dòng)參數(shù)是一個(gè)長(zhǎng)度等于矢量動(dòng)作空間的control signals數(shù)組益愈。 當(dāng)動(dòng)作向量空間是離散時(shí)份乒,動(dòng)作參數(shù)是一個(gè)僅包含單個(gè)值的數(shù)組,即列表或命令表中的索引。 在離散動(dòng)作向量空間類型中或辖,Vector Action Space Size大小是行動(dòng)表中元素的數(shù)量瘾英。 在agent的Brain對(duì)象上(使用Unity Editor Inspector窗口)設(shè)置Vector Action Space大小和Vector Action Space類型屬性。
Brain和訓(xùn)練算法都不知道動(dòng)作值本身的含義颂暇。訓(xùn)練算法簡(jiǎn)單地嘗試動(dòng)作列表中不同的值缺谴,并觀察在時(shí)間和訓(xùn)練episode上累積獎(jiǎng)勵(lì)的效果。因此耳鸯,AgentAction()函數(shù)中只定義了agent唯一的place actions(這里不太明白)湿蛔。 在ActionAct()中,只需根據(jù)動(dòng)作向量空間的類型县爬,取出Brain返回的動(dòng)作值阳啥,然后對(duì)agent應(yīng)用收到的值。
例如财喳,如果你將agent設(shè)計(jì)為以二維方式移動(dòng)察迟,則可以使用連續(xù)或離散向量操作。 在連續(xù)的情況下耳高,您可以將動(dòng)作向量大小設(shè)置為2(每個(gè)維度一個(gè))扎瓶,并且agent的Brain會(huì)創(chuàng)建一個(gè)具有兩個(gè)浮點(diǎn)值的動(dòng)作。在離散情況下泌枪,您可以將動(dòng)作向量大小設(shè)置為4(每個(gè)方向一個(gè))概荷,Brain將創(chuàng)建一個(gè)動(dòng)作數(shù)組,其中包含一個(gè)值介于0到4之間的單個(gè)元素碌燕。
請(qǐng)注意误证,當(dāng)你正在編寫agent的動(dòng)作時(shí),使用Player 類型的Barin來(lái)測(cè)試你的動(dòng)作邏輯通常很有幫助修壕,它可以讓您將鍵盤命令映射到操作愈捅。
3DBall和Area示例環(huán)境的設(shè)置是連續(xù)或離散動(dòng)作矢量空間。
連續(xù)動(dòng)作空間 Continuous Action Space
當(dāng)Agent使用設(shè)置為連續(xù)動(dòng)作向量空間的Brain時(shí)叠殷,傳遞給AgentAction()函數(shù)的動(dòng)作參數(shù)是一個(gè)長(zhǎng)度等于Brain對(duì)象的動(dòng)作矢量空間大小的數(shù)組改鲫。數(shù)組中的各個(gè)值具有你賦予它們的任何意義诈皿。 例如林束,如果將數(shù)組中的某個(gè)元素指定為agent的速度,則訓(xùn)練過(guò)程通過(guò)此參數(shù)學(xué)習(xí)控制agent的速度稽亏。
Reacher示例使用四個(gè)控制值定義了一個(gè)連續(xù)的動(dòng)作空間壶冒。
這些控制值作為扭矩施加到構(gòu)成手臂的身體上:
public override void AgentAction(float[] act)
{
float torque_x = Mathf.Clamp(act[0], -1, 1) * 100f;
float torque_z = Mathf.Clamp(act[1], -1, 1) * 100f;
rbA.AddTorque(new Vector3(torque_x, 0f, torque_z));
torque_x = Mathf.Clamp(act[2], -1, 1) * 100f;
torque_z = Mathf.Clamp(act[3], -1, 1) * 100f;
rbB.AddTorque(new Vector3(torque_x, 0f, torque_z));
}
你應(yīng)該將連續(xù)動(dòng)作值限制在合理值(通常為[-1,1])以避免在使用PPO算法對(duì)代理進(jìn)行訓(xùn)練時(shí)引入不穩(wěn)定性。 如上所示截歉,您可以在clamp操作之后根據(jù)需要調(diào)整控制值胖腾。
離散動(dòng)作空間 Discrete Action Space
當(dāng)agent使用設(shè)置為離散動(dòng)作向量空間的Brain時(shí),傳遞給AgentAction()函數(shù)的動(dòng)作參數(shù)是包含單個(gè)元素的數(shù)組。 該值是您的表格或操作列表中操作的索引咸作。使用離散向量動(dòng)作空間時(shí)锨阿,Vector Action Space Size表示動(dòng)作表中的動(dòng)作數(shù)量。
Area示例(這里應(yīng)該是PushBlock示例)為離散矢量動(dòng)作空間定義了五個(gè)動(dòng)作:跳躍動(dòng)作和每個(gè)基本方向的動(dòng)作:
// Get the action index
int movement = Mathf.FloorToInt(act[0]);
// Look up the index in the action list:
if (movement == 1) { directionX = -1; }
if (movement == 2) { directionX = 1; }
if (movement == 3) { directionZ = -1; }
if (movement == 4) { directionZ = 1; }
if (movement == 5 && GetComponent<Rigidbody>().velocity.y <= 0) { directionY = 1; }
// Apply the action results to move the agent
gameObject.GetComponent<Rigidbody>().AddForce(
new Vector3(
directionX * 40f, directionY * 300f, directionZ * 40f));`
請(qǐng)注意记罚,上面的代碼示例是AreaAgent類(現(xiàn)在已經(jīng)找不到了墅诡,可能文檔有點(diǎn)老,參考PushAgentBasic類)的簡(jiǎn)化提取桐智,它為離散動(dòng)作空間和連續(xù)動(dòng)作空間的實(shí)現(xiàn)提供了參考末早。
回報(bào)/獎(jiǎng)勵(lì) Rewards
在增強(qiáng)學(xué)習(xí)中,獎(jiǎng)勵(lì)是agent正確做事的信號(hào)说庭。 PPO增強(qiáng)學(xué)習(xí)算法通過(guò)優(yōu)化agent所做的選擇來(lái)工作然磷,以便agent隨著時(shí)間的推移獲得最高的累積獎(jiǎng)勵(lì)。你的獎(jiǎng)勵(lì)機(jī)制越好刊驴,你的agent就會(huì)學(xué)得越好姿搜。
注意:在使用已經(jīng)訓(xùn)練好的策略進(jìn)行推理時(shí),不會(huì)使用獎(jiǎng)勵(lì)缺脉,也不會(huì)在模仿學(xué)習(xí)中使用獎(jiǎng)勵(lì)痪欲。
也許最好的建議是從簡(jiǎn)單開始,只根據(jù)需要增加復(fù)雜性攻礼。一般來(lái)說(shuō)业踢,你應(yīng)該獎(jiǎng)勵(lì)結(jié)果,而不是你認(rèn)為會(huì)導(dǎo)致期望結(jié)果的行動(dòng)礁扮。為了幫助開發(fā)獎(jiǎng)勵(lì)知举,你可以使用Monitor類來(lái)顯示agent收到的累計(jì)獎(jiǎng)勵(lì)。你甚至可以使用玩家大腦來(lái)控制agent太伊,同時(shí)觀察它如何積累獎(jiǎng)勵(lì)雇锡。
通過(guò)調(diào)用AgentAction()函數(shù)中的AddReward()方法為agent分配獎(jiǎng)勵(lì)。在任何步驟中分配的獎(jiǎng)勵(lì)應(yīng)該在[-1,1]的范圍內(nèi)僚焦。超出此范圍的值可能導(dǎo)致不穩(wěn)定的訓(xùn)練锰提。獎(jiǎng)勵(lì)值在每一步都重置為零。
示例 Examples
你可以查看示例環(huán)境中定義的AgentAction()函數(shù)芳悲,以了解這些項(xiàng)目如何分配獎(jiǎng)勵(lì)立肘。
GridWorld示例中的GridAgent類使用一個(gè)非常簡(jiǎn)單的獎(jiǎng)勵(lì)系統(tǒng):
Collider[] hitObjects = Physics.OverlapBox(trueAgent.transform.position,
new Vector3(0.3f, 0.3f, 0.3f));
if (hitObjects.Where(col => col.gameObject.tag == "goal").ToArray().Length == 1)
{
AddReward(1.0f);
Done();
}
if (hitObjects.Where(col => col.gameObject.tag == "pit").ToArray().Length == 1)
{
AddReward(-1f);
Done();
}
agent在達(dá)到目標(biāo)時(shí)會(huì)收到正值的獎(jiǎng)勵(lì),并在掉入坑時(shí)收到負(fù)值的獎(jiǎng)勵(lì)名扛。否則谅年,它不會(huì)得到回報(bào)。 這是一個(gè)稀疏獎(jiǎng)勵(lì)系統(tǒng)的例子肮韧。Agent必須做很多的探索才能找到不經(jīng)常發(fā)生的獎(jiǎng)勵(lì)融蹂。
相比之下旺订,Area Area中的AreaAgent每一步都會(huì)得到一個(gè)小的負(fù)回報(bào)。 為了獲得最大的回報(bào)超燃,agent必須盡快完成到達(dá)目標(biāo)區(qū)域的任務(wù):
AddReward( -0.005f);
MoveAgent(act);
if (gameObject.transform.position.y < 0.0f ||
Mathf.Abs(gameObject.transform.position.x - area.transform.position.x) > 8f ||
Mathf.Abs(gameObject.transform.position.z + 5 - area.transform.position.z) > 8)
{
Done();
AddReward(-1f);
}
如果從平臺(tái)上掉落的話区拳,Agent也會(huì)受到更大的負(fù)值懲罰。
3DBall中的Ball3DAgent采用類似的方法意乓,但只要agent平衡著小球劳闹,就會(huì)分配一個(gè)小的積極獎(jiǎng)勵(lì)。 Agent可以通過(guò)將球保持在平臺(tái)上來(lái)最大化其獎(jiǎng)勵(lì):
if (IsDone() == false)
{
SetReward(0.1f);
}
// When ball falls mark agent as done and give a negative penalty
if ((ball.transform.position.y - gameObject.transform.position.y) < -2f ||
Mathf.Abs(ball.transform.position.x - gameObject.transform.position.x) > 3f ||
Mathf.Abs(ball.transform.position.z - gameObject.transform.position.z) > 3f)
{
Done();
SetReward(-1f);
}
Agent Properties
大腦 Brain - 注冊(cè)該agent的大腦洽瞬。使用編輯器添加本涕。
視覺(jué)觀測(cè) Visual Observations - 將用于生成觀測(cè)的相機(jī)列表。
最大步驟 - 每個(gè)agent的最大步數(shù)伙窃。一旦達(dá)到此數(shù)字菩颖,如果選中了Reset On Done,agent將被重置为障。
完成時(shí)重置 Reset On Done - 當(dāng)agent達(dá)到其最大步數(shù)時(shí)應(yīng)否調(diào)用代理的AgentReset()函數(shù)晦闰,或者是否在代碼中標(biāo)記為已完成。
-
按需決策 - agent是否以固定步長(zhǎng)間隔請(qǐng)求決策或通過(guò)調(diào)用RequestDecision()明確請(qǐng)求決策鳍怨。
如果未選中呻右,agent將按照 Decision Frequency 的步數(shù)設(shè)置來(lái)請(qǐng)求一個(gè)新決策并執(zhí)行一次動(dòng)作。在上面的例子中鞋喇,CollectObservations()每5步調(diào)用一次声滥,AgentAction()將在每一步調(diào)用。這意味著該agent將重復(fù)使用Brain給出的決定侦香。
-
如果選中落塑,agent控制何時(shí)接收決策并采取行動(dòng)。為此罐韩,agent可以使用以下兩種方法:
RequestDecision()表示agent正在請(qǐng)求做出決定憾赁。這導(dǎo)致agent收集其觀察結(jié)果,并要求Brain在模擬的下一步中做出決策散吵。請(qǐng)注意龙考,當(dāng)agent請(qǐng)求決定時(shí),它也會(huì)請(qǐng)求執(zhí)行動(dòng)作矾睦。這是為了確保所有決策都會(huì)在訓(xùn)練期間引發(fā)動(dòng)作晦款。
RequestAction()表示agent正在請(qǐng)求動(dòng)作。在這種情況下向agent提供的動(dòng)作與上次提出請(qǐng)求做出決策時(shí)提供的動(dòng)作相同顷锰。
決策頻率 Decision Frequency - 決策請(qǐng)求之間的步數(shù)柬赐。如果按需決策勾選的話亡问,則不使用官紫。
監(jiān)測(cè)Agents Monitoring Agents
我們創(chuàng)建了一個(gè)有用的Monitor類肛宋,可以使Unity環(huán)境中的變量可視化。 雖然這是為了在整個(gè)訓(xùn)練過(guò)程中監(jiān)控agent的值函數(shù)而建立的束世,但我們認(rèn)為它可能更為廣泛有用酝陈。 你可以在這里了解更多(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Feature-Monitor.md)。
運(yùn)行時(shí)實(shí)例化Agent Instantiating an Agent at Runtime
要在運(yùn)行時(shí)將agent添加到環(huán)境中毁涉,請(qǐng)使用Unity GameObject.Instantiate函數(shù)沉帮。 從Prefab實(shí)例化agent通常是最容易的(否則,你必須單獨(dú)實(shí)例化組成agent的每個(gè)GameObject和Component)贫堰。 另外穆壕,你必須將Brain實(shí)例分配給新Agent,并通過(guò)調(diào)用其AgentReset()方法來(lái)初始化它其屏。 例如喇勋,以下函數(shù)根據(jù)Prefab,Brain實(shí)例偎行,位置和方向創(chuàng)建新agent:
private void CreateAgent(GameObject agentPrefab, Brain brain, Vector3 position, Quaternion orientation)
{
GameObject agentObj = Instantiate(agentPrefab, position, orientation);
Agent agent = agentObj.GetComponent<Agent>();
agent.GiveBrain(brain);
agent.AgentReset();
}
銷毀Agent Destroying an Agent
在銷毀Agent游戲?qū)ο笾按ū常惚仨殞⑵錁?biāo)記為已完成(并等待模擬中的下一步),以便Brain知道此agent不再處于活動(dòng)狀態(tài)蛤袒。因此熄云,銷毀Agent的最佳位置在Agent.AgentOnDone()函數(shù)中:
public override void AgentOnDone()
{
Destroy(gameObject);
}
請(qǐng)注意,為了調(diào)用AgentOnDone()妙真,agent的ResetOnDone屬性必須為false缴允。 你可以在agent的Inspector或代碼中設(shè)置ResetOnDone。