C# ML代理不学习相对';简单';任务

C# ML代理不学习相对';简单';任务,c#,unity3d,ml-agent,C#,Unity3d,Ml Agent,我尝试创建一个简单的ML代理(ball)来学习如何向目标移动并与目标碰撞 不幸的是,代理似乎没有学习,只是在似乎是随机的位置上移动。5米步后,平均奖励保持在-1 对我做错了什么有什么建议吗 我的意见如下: /// <summary> /// Observations: /// 1: Distance to nearest target /// 3: Vector to nearest target /// 3: Target Position /// 3: Agent positi

我尝试创建一个简单的ML代理(ball)来学习如何向目标移动并与目标碰撞

不幸的是,代理似乎没有学习,只是在似乎是随机的位置上移动。5米步后,平均奖励保持在-1

对我做错了什么有什么建议吗

我的意见如下:

/// <summary>
/// Observations:
/// 1: Distance to nearest target
/// 3: Vector to nearest target
/// 3: Target Position
/// 3: Agent position
/// 1: Agent Velocity X
/// 1: Agent Velocity Y
/// //12 observations in total
/// </summary>
/// <param name="sensor"></param>
public override void CollectObservations(VectorSensor sensor)
{

    //If nearest Target is null, observe an empty array and return early
    if (target == null)
    {
        sensor.AddObservation(new float[12]);
        return;
    }

    float distanceToTarget = Vector3.Distance(target.transform.position, this.transform.position);

    //Distance to nearest target (1 observervation)
    sensor.AddObservation(distanceToTarget);

    //Vector to nearest target (3 observations)
    Vector3 toTarget = target.transform.position - this.transform.position;

    sensor.AddObservation(toTarget.normalized);


    //Target position
    sensor.AddObservation(target.transform.localPosition);

    //Current Position
    sensor.AddObservation(this.transform.localPosition);

    //Agent Velocities
    sensor.AddObservation(rigidbody.velocity.x);
    sensor.AddObservation(rigidbody.velocity.y);
}

奖励(全部在代理脚本上):

private void Update()
{
//如果特工从屏幕上掉下来,给予负面奖励,结束一集
if(此.transform.position.y<0)
{
增加奖励(-1.0f);
EndEpisode();
}
如果(目标!=null)
{
DrawLine(this.transform.position、target.transform.position、Color.green);
}
}
专用void OnCollisionEnter(碰撞)
{
//如果代理与目标发生冲突,则提供奖励
if(collidedObj.gameObject.CompareTag(“目标”))
{
增加奖励(1.0f);
摧毁(目标);
EndEpisode();
}
}
已接收公共覆盖无效OnAction(浮点[]矢量操作)
{
如果(!目标)
{
//放置并分配目标
envController.PlaceTarget();
target=envController.ProvideTarget();
}
矢量3控制信号=矢量3.0;
controlSignal.x=矢量作用[0];
controlSignal.z=矢量作用[1];
刚体.附加力(控制信号*移动速度,力模式.速度变化);
//在每一步都给予小小的负面奖励,以鼓励行动
如果(this.MaxStep>0)添加奖励(-1f/this.MaxStep);
}

您认为您的环境有多艰难?如果很少达到目标,代理将无法学习。在这种情况下,当代理朝着正确的方向行动时,您需要添加一些内在的奖励。这样,即使奖励很少,代理也可以学习


从您设计奖励的方式来看,奖励黑客也可能存在问题。如果代理无法找到目标以获得更大的奖励,最有效的方法是尽快从平台上摔下来,以免在每个时间段都受到小的惩罚。

你在哪里奖励好的和坏的行为?现在添加到帖子中。谢谢,这很有意义。我在随机地点生成目标和代理,现在我意识到也许我需要通过课程学习来增加任务的难度。现在就开始尝试并找到一个关于如何做到这一点的教程@我很高兴,希望能帮上忙!如果您考虑所回答的问题,请接受左侧绿色复选标记的答案。
    behaviors:
  PlayerAgent:
    trainer_type: ppo
    hyperparameters:
      batch_size: 512 #128
      buffer_size: 2048
      learning_rate: 3.0e-4
      beta: 5.0e-4
      epsilon: 0.2 #0.2
      lambd: 0.99
      num_epoch: 3 #3
      learning_rate_schedule: linear
    network_settings:
      normalize: false
      hidden_units: 32 #256
      num_layers: 2
      vis_encode_type: simple
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
      curiosity:
        strength: 0.02
        gamma: 0.99
        encoding_size: 64
        learning_rate: 3.0e-4
    #keep_checkpoints: 5
    #checkpoint_interval: 500000
    max_steps: 5000000
    time_horizon: 64
    summary_freq: 10000
    threaded: true
    framework: tensorflow
private void Update()
{

    //If Agent falls off the screen, give negative reward an end episode
    if (this.transform.position.y < 0)
    {
        AddReward(-1.0f);
        EndEpisode();
    }

    if(target != null)
    {
        Debug.DrawLine(this.transform.position, target.transform.position, Color.green);
    }

}

private void OnCollisionEnter(Collision collidedObj)
{
    //If agent collides with goal, provide reward
    if (collidedObj.gameObject.CompareTag("Goal"))
    {
        AddReward(1.0f);
        Destroy(target);
        EndEpisode();
    }
}

public override void OnActionReceived(float[] vectorAction)
{
    if (!target)
    {
        //Place and assign the target
        envController.PlaceTarget();
        target = envController.ProvideTarget();
    }

    Vector3 controlSignal = Vector3.zero;
    controlSignal.x = vectorAction[0];
    controlSignal.z = vectorAction[1];
    rigidbody.AddForce(controlSignal * moveSpeed, ForceMode.VelocityChange);

    // Apply a tiny negative reward every step to encourage action
    if (this.MaxStep > 0) AddReward(-1f / this.MaxStep);

}