网上的教程也有,这里就不详细说了。这次主要是参看了这个博客搭建好的环境(虽然以前已经搭建过了,但是太久了都不知道怎么搭的了,所以重新搭建一遍)。
大概流程就是:
mlagents-learn config/trainer_config.yaml --run-id=3dball --train
其中,config/trainer_config.yaml是配置文件。id=后面,即“3dball”,为训练的id,可以改成自己喜欢的。最后会在model文件夹中生成一个用id命名的文件,训练完的模型就会在里面。
回车之后不出意外的话会出现以下画面,最后一行字就是请在Unity编辑器中按下播放。==确保这个时候academy中的control是勾上的,==因为现在要训练而不是运行结果。
既然能够成功的训练官方案例了,那么就来做一个简单的案例吧。主要是参照这个博客(不过也改了些东西),做一个小球自动去寻找靠近目标的AI。这貌似是类似HelloWord的第一个案例,找到好多个按这个思路的教程,也很简单。
然后就开始写代码了,一共只创建两个脚本。
using MLAgents;
using UnityEngine;
// 原博客的代码又很多注释,这里简洁一点就删掉了,以及一些小小的修改
public class RollerAgent : Agent
{
public Transform Target;
Rigidbody rBody;
public float speed = 10;
void Start()
{
rBody = GetComponent<Rigidbody>();
}
public override void AgentReset()
{
if (transform.localPosition.y < 0)
{
rBody.angularVelocity = Vector3.zero;
rBody.velocity = Vector3.zero;
transform.localPosition = new Vector3(0, 0.5f, 0);
}
Target.localPosition = new Vector3(Random.Range(-4.5f,4.5f),
0.5f,
Random.Range(-4.5f, 4.5f));
}
public override void CollectObservations()
{
AddVectorObs(Target.localPosition - transform.localPosition);
AddVectorObs(rBody.velocity.z);
AddVectorObs(rBody.velocity.x);
}
public override void AgentAction(float[] vectorAction, string textAction)
{
Vector3 controlSignal = Vector3.zero;
controlSignal.x = vectorAction[0];
controlSignal.z = vectorAction[1];
rBody.AddForce(controlSignal * speed);
if (transform.localPosition.y < 0)
{
Done();
}
}
private void OnCollisionEnter(Collision other) {
if(other.transform.tag == "goal"){
SetReward(1.0f);
Done();
}
}
}
其中的一些函数的意义
public override void AgentReset()
{
// 执行Done()之后会调用。就是一次重置,可以在这个函数中重新设置下一次训练的内容
}
public override void CollectObservations()
{
// 收集信息。在这里给tensorflow传递要用的参数,会影响到Brain设置中Vector Observation的设置。
}
public override void AgentAction(float[] vectorAction, string textAction)
{
// 根据处理得出的结果进行动作。
// vectorAction是得出向量,跟Brain设置中Vector Action的设置有影响。用这些结果再次进行控制小球的运动。
// textAction还不知道是干嘛的
}
需要创建一个LearningBrain,名字取什么都可以。
然后这个LearningBrain的设置如下,Vector Observation中的Space Size是5(原博客中是8,因为我改了下代码,去掉了3个分量,所以是5),Vector Action中的Space Size是2。对应的就是代码中传入的数据和得出的数据的个数(不是变量的个数,而是具体分量的个数,比如一个Vector3再加两个float就是5了)。这时候下面提示说没有模型,但是可以训练。这是当然的,因为我们还没有训练怎么会有模型嘛,如果是执行训练的结果就必须要有模型了,而且Brain和模型(Model)向量不匹配的话也是会提示的。
然后把这个Brain分别放到RollerAcademy和RollerAgent中的对应位置(RollerAcademy中如果没有的话就先add New一下)。然后勾上后面的Control等待我们的训练。
接下来就是配置一下相关的训练信息(不设置也行,就会使用默认的,不同的案例设置一个对应合适的训练信息训练效果会更好。不过设置成什么样就需要机器学习的跟多知识了,我也只是略知一二)。在根目录的config文件夹中有一个trainer_config.yaml文件,打开它可以看到其他的案例的训练信息。我们在后面加上一段下面这个:
SingleRollerBallLearningBrain:
batch_size: 10
buffer_size: 100
max_steps: 2.0e4
第一行就是创建的LearningBrain的名称,创建的是啥就写啥,训练前MLAgents会自己到这个配置文件中寻找和大脑对应的训练信息。
batch_size,根据我浅薄的知识储备这应该是一次喂入网络中数据的数量。
buffer_size,这个就猜不出来了。
max_steps,这个最好理解,就是最多训练多少回。用的是科学计数法,2.0e4就是两万的意思。
要注意冒号之后是有空格的。
接下来就可以开始训练了(就跟刚才训练官方案例一模一样)。
同样的先把在命令提示符中把路径设置到mlagents的根目录,然后输入一下的指令,回车。
mlagents-learn config/trainer_config.yaml --run-id=RollerBall --train
这句话的意思同理上面训练官方案例的时候。
然后提示运行Unity编辑器。运行之后等待训练结束。
这里有个小插曲,在跟着做的时候发现怎么训练都训练的一塌糊涂。也找不出问题在哪里,后来下载原博客的工程仔细比对才发现原来RollerAgent中的Decision Interval和别人的不一样。我这里自带默认就是1,别人是10,改过来之后就好了。(下面有个Obstacles是因为想加一个躲避障碍的功能,结果训练了半天也得不到好的结果)
把训练出来的模型放到Brain中,去掉Control。运行。
第一个小案例就做好了。