
~minDistance 初期化の落とし穴~
Unityの ML-Agents で強化学習を作っているとき、
こんなコードを書いていませんか?
float minDistance = float.MaxValue;
そしてこれを CollectObservations() 内でそのまま追加。
sensor.AddObservation(minDistance);
すると…
infiniteError(Infinity / NaN系エラー)
が出る。
今回はその原因と対処法をまとめます。
何が起きているのか?
問題の流れ
-
最小距離を求めたい
-
初期値として
float.MaxValueを入れる -
何もヒットしなかった場合、その値のまま
-
観測値に追加
-
学習時にエラー
なぜ 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正規化が基本