Django Girls and Boys 備忘録

Python、Selenium、Django、java、iPhoneアプリ、Excelマクロなどで気付いたこと、覚えておきたいことなどを載せていきます。

【Unity ML-Agents】float.MaxValue を観測に入れたら infinite エラーが出た話

~minDistance 初期化の落とし穴~

Unityの ML-Agents で強化学習を作っているとき、
こんなコードを書いていませんか?

 
float minDistance = float.MaxValue;

 

そしてこれを CollectObservations() 内でそのまま追加。

 
sensor.AddObservation(minDistance);

 

すると…

infiniteError(Infinity / NaN系エラー)

が出る。

今回はその原因と対処法をまとめます。


何が起きているのか?

問題の流れ

  1. 最小距離を求めたい

  2. 初期値として float.MaxValue を入れる

  3. 何もヒットしなかった場合、その値のまま

  4. 観測値に追加

  5. 学習時にエラー


なぜ float.MaxValue がダメなのか?

float.MaxValue は:

 
3.402823E+38

 

という 極端に大きい値 です。

ML-Agents の内部では:

  • 正規化

  • 標準化

  • 重み計算

  • 勾配計算

が行われます。

ここに極端な値が入ると、

  • 演算オーバーフロー

  • Infinity

  • NaN

  • infiniteError

が発生します。


よくあるケース(距離計算)

例えば:

 
float minDistance = float.MaxValue;

foreach (var enemy in enemies)
{
    float dist = Vector3.Distance(transform.position, enemy.position);
    if (dist < minDistance)
    {
        minDistance = dist;
    }
}

 

敵が1体もいない場合、

 
minDistance = float.MaxValue のまま

 

になります。


float.MaxValueではなくたとえば 999999.9f ならなぜ動くのか?

 
float minDistance = 999999.9f;

 

これは:

  • 大きい

  • でも演算可能範囲

  • オーバーフローしにくい

ため、エラーになりません。


でも本当のベスト解は?

✅ 観測値は「現実的な範囲」に収めるべき

強化学習では:

観測値のスケールは極めて重要

です。


おすすめ修正版

① 最大距離を決めてクランプする

 
float maxDistance = 100f;
float minDistance = maxDistance;

foreach (var enemy in enemies)
{
    float dist = Vector3.Distance(transform.position, enemy.position);
    minDistance = Mathf.Min(minDistance, dist);
}

// 上限保証
minDistance = Mathf.Clamp(minDistance, 0f, maxDistance);
sensor.AddObservation(minDistance / maxDistance);

 

これで何が良い?

  • 上限が固定

  • 正規化済み(0〜1)

  • 学習が安定

  • infiniteエラー防止


ML-Agentsでやってはいけないこと

❌ float.MaxValue を観測に入れる
❌ Infinity を入れる
❌ NaN を入れる
❌ 極端にスケールの違う値を混在させる


なぜ強化学習では致命的なのか?

ニューラルネットは:

 
大きすぎる値 → 重み爆発 → 勾配爆発 → 学習崩壊

 

を起こします。

infiniteError は
「モデルが壊れかけています」という警告です。


まとめ

  • float.MaxValue は便利な初期値

  • でも ML-Agents の観測には危険

  • 観測値は必ずスケールを揃える

  • 0〜1正規化が基本