team_22 / eval /eval_liquid_policy.py
Antigravity Agent
Deploy Neuro-Flyt 3D Training
6083286
"""
Evaluate a trained PPO Liquid Neural Network policy on the DroneWindEnv environment.
This script loads a saved PPO model with liquid policy and runs evaluation episodes,
printing statistics about average reward and episode length.
"""
import os
import sys
import argparse
import numpy as np
from stable_baselines3 import PPO
# Add project root to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from env.drone_env import DroneWindEnv
def main():
"""Main evaluation function."""
parser = argparse.ArgumentParser(description="Evaluate PPO Liquid NN agent on DroneWindEnv")
parser.add_argument(
"--model-path",
type=str,
default="models/liquid_policy.zip",
help="Path to the trained model (default: models/liquid_policy.zip)"
)
parser.add_argument(
"--episodes",
type=int,
default=10,
help="Number of evaluation episodes (default: 10)"
)
parser.add_argument(
"--render",
action="store_true",
help="Print environment state to console during evaluation"
)
parser.add_argument(
"--seed",
type=int,
default=None,
help="Random seed for evaluation (default: None)"
)
args = parser.parse_args()
print("=" * 60)
print("Evaluating PPO Liquid NN Agent on DroneWindEnv")
print("=" * 60)
print(f"Model path: {args.model_path}")
print(f"Number of episodes: {args.episodes}")
print("=" * 60)
# Check if model file exists
if not os.path.exists(args.model_path):
print(f"\nError: Model file not found at {args.model_path}")
print("Please train a model first using:")
print(" python train/train_liquid_ppo.py")
return
# Create environment
print("\nCreating environment...")
env = DroneWindEnv()
# Load the model
print(f"Loading model from {args.model_path}...")
try:
model = PPO.load(args.model_path, env=env)
print("Model loaded successfully!")
except Exception as e:
print(f"\nError loading model: {e}")
return
# Run evaluation episodes
print(f"\nRunning {args.episodes} evaluation episodes...")
print("-" * 60)
rewards = []
episode_lengths = []
for episode in range(args.episodes):
obs, info = env.reset(seed=args.seed)
done = False
truncated = False
total_reward = 0.0
step_count = 0
if args.render:
print(f"\nEpisode {episode + 1}:")
env.render()
while not (done or truncated):
# Get action from the model (deterministic)
action, _ = model.predict(obs, deterministic=True)
# Step the environment
obs, reward, done, truncated, info = env.step(action)
total_reward += reward
step_count += 1
if args.render:
env.render()
rewards.append(total_reward)
episode_lengths.append(step_count)
status = "terminated" if done else "truncated"
print(f"Episode {episode + 1}: Reward = {total_reward:.2f}, "
f"Length = {step_count} steps ({status})")
# Print statistics
print("\n" + "=" * 60)
print("Evaluation Results")
print("=" * 60)
print(f"Average reward: {np.mean(rewards):.2f} ± {np.std(rewards):.2f}")
print(f"Average episode length: {np.mean(episode_lengths):.1f} ± {np.std(episode_lengths):.1f}")
print(f"Average survival time: {np.mean(episode_lengths):.1f} steps")
print(f"Min reward: {np.min(rewards):.2f}")
print(f"Max reward: {np.max(rewards):.2f}")
print(f"Min episode length: {np.min(episode_lengths)}")
print(f"Max episode length: {np.max(episode_lengths)}")
print("=" * 60)
# Print per-episode rewards
print("\nPer-episode rewards:")
for i, reward in enumerate(rewards, 1):
print(f" Episode {i}: {reward:.2f}")
# Optional: Try to plot if matplotlib is available
try:
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 5))
# Plot 1: Episode rewards
plt.subplot(1, 2, 1)
plt.plot(range(1, len(rewards) + 1), rewards, 'o-', linewidth=2, markersize=6)
plt.axhline(y=np.mean(rewards), color='r', linestyle='--', label=f'Mean: {np.mean(rewards):.2f}')
plt.xlabel('Episode')
plt.ylabel('Total Reward')
plt.title('Episode Rewards (Liquid NN)')
plt.grid(True, alpha=0.3)
plt.legend()
# Plot 2: Episode lengths
plt.subplot(1, 2, 2)
plt.plot(range(1, len(episode_lengths) + 1), episode_lengths, 's-',
linewidth=2, markersize=6, color='green')
plt.axhline(y=np.mean(episode_lengths), color='r', linestyle='--',
label=f'Mean: {np.mean(episode_lengths):.1f}')
plt.xlabel('Episode')
plt.ylabel('Episode Length')
plt.title('Episode Lengths (Liquid NN)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.savefig('eval_liquid_results.png', dpi=150, bbox_inches='tight')
print("\n✓ Evaluation plots saved to eval_liquid_results.png")
print(" (Close the plot window to continue)")
plt.show(block=False)
plt.pause(2) # Show for 2 seconds
plt.close()
except ImportError:
# Matplotlib not available, skip plotting
pass
except Exception as e:
print(f"\nNote: Could not generate plots: {e}")
if __name__ == "__main__":
main()