遷移指南 - v0.21 到 v1.0.0¶
誰應該閱讀本指南?¶
如果您是 Gymnasium 的新使用者:您可以跳過此頁面!本指南適用於從舊版本 OpenAI Gym 遷移的使用者。如果您剛開始接觸強化學習,請轉到基本用法。
如果您正在從 OpenAI Gym 遷移:本指南將幫助您更新程式碼以與 Gymnasium 相容。這些更改意義重大,但一旦您理解了其背後的原因,就會發現它們很簡單。
如果您正在更新舊教程:許多線上強化學習教程使用舊的 v0.21 API。本指南將向您展示如何使這些程式碼現代化。
為什麼 API 發生了變化?¶
Gymnasium 是 OpenAI Gym v0.26 的一個分支,該版本引入了與 Gym v0.21 不相容的重大更改。這些更改並非輕率而為——它們解決了導致強化學習研究和開發更加困難的重要問題。
舊版 API 的主要問題包括: - 回合結束的歧義:單個 done 標誌無法區分“任務完成”和“達到時間限制” - 不一致的隨機種子:隨機數生成不可靠且難以復現 - 渲染複雜性:在不同視覺模式之間切換不必要的複雜 - 復現性問題:細微的錯誤使得研究結果難以復現
對於仍在使用 v0.21 API 的環境,請參閱相容性指南。
快速參考:完整更改表¶
元件 |
v0.21 (舊) |
v0.26+ (新) |
影響 |
|---|---|---|---|
包匯入 |
|
|
所有程式碼 |
環境重置 |
|
|
訓練迴圈 |
隨機種子 |
|
|
復現性 |
步進函式 |
|
|
強化學習演算法 |
回合結束 |
|
|
訓練迴圈 |
渲染模式 |
|
|
視覺化 |
時間限制檢測 |
|
|
強化學習演算法 |
價值自舉 |
|
|
強化學習正確性 |
程式碼並排比較¶
舊版 v0.21 程式碼¶
import gym
# Environment creation and seeding
env = gym.make("LunarLander-v3", options={})
env.seed(123)
observation = env.reset()
# Training loop
done = False
while not done:
action = env.action_space.sample()
observation, reward, done, info = env.step(action)
env.render(mode="human")
env.close()
新版 v0.26+ 程式碼(包括 v1.0.0)¶
import gymnasium as gym # Note: 'gymnasium' not 'gym'
# Environment creation with render mode specified upfront
env = gym.make("LunarLander-v3", render_mode="human")
# Reset with seed parameter
observation, info = env.reset(seed=123, options={})
# Training loop with terminated/truncated distinction
done = False
while not done:
action = env.action_space.sample()
observation, reward, terminated, truncated, info = env.step(action)
# Episode ends if either terminated OR truncated
done = terminated or truncated
env.close()
關鍵更改細分¶
1. 包名稱更改¶
舊版:import gym 新版:import gymnasium as gym
原因:Gymnasium 是一個獨立專案,它維護並改進了原始 Gym 程式碼庫。
# Update your imports
# OLD
import gym
# NEW
import gymnasium as gym
2. 隨機種子和隨機數生成¶
最大的概念性變化是隨機性的處理方式。
舊版 v0.21:獨立的 seed() 方法
env = gym.make("CartPole-v1")
env.seed(42) # Set random seed
obs = env.reset() # Reset environment
新版 v0.26+:種子透過 reset() 傳遞
env = gym.make("CartPole-v1")
obs, info = env.reset(seed=42) # Seed and reset together
為什麼會改變:某些環境(特別是模擬遊戲)只能在回合開始時設定其隨機狀態,而不能在回合中間設定。舊方法可能導致不一致的行為。
實際影響:
# OLD: Seeding applied to all future episodes
env.seed(42)
for episode in range(10):
obs = env.reset()
# NEW: Each episode can have its own seed
for episode in range(10):
obs, info = env.reset(seed=42 + episode) # Each episode gets unique seed
3. 環境重置的變化¶
舊版 v0.21:僅返回觀測
observation = env.reset()
新版 v0.26+:返回觀測和資訊
observation, info = env.reset()
為什麼會改變:
info提供對除錯資訊的一致訪問seed引數實現可復現的回合options引數允許回合特定配置
常見遷移模式:
# If you don't need the new features, just unpack the tuple
obs, _ = env.reset() # Ignore info with underscore
# If you want to maintain the same random behavior as v0.21
env.reset(seed=42) # Set seed once
# Then for subsequent resets:
obs, info = env.reset() # Uses internal random state
4. 步進函式:done → terminated/truncated 分割¶
這是訓練演算法最重要的變化。
舊版 v0.21:單個 done 標誌
obs, reward, done, info = env.step(action)
新版 v0.26+:獨立的 terminated 和 truncated 標誌
obs, reward, terminated, truncated, info = env.step(action)
為什麼這很重要:
terminated:回合因任務完成或失敗而結束(智慧體達到目標、死亡等)truncated:回合因外部限制而結束(時間限制、步數限制等)
這種區分對於強化學習演算法中的價值函式自舉至關重要
# OLD (ambiguous)
if done:
# Should we bootstrap? We don't know if this was natural termination or time limit!
next_value = 0 # Assumption that may be wrong
# NEW (clear)
if terminated:
next_value = 0 # Natural ending - no future value
elif truncated:
next_value = value_function(next_obs) # Time limit - estimate future value
遷移策略:
# Simple migration (works for many cases)
obs, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
# Better migration (preserves RL algorithm correctness)
obs, reward, terminated, truncated, info = env.step(action)
if terminated:
# Episode naturally ended - use reward as-is
target = reward
elif truncated:
# Episode cut short - may need to estimate remaining value
target = reward + discount * estimate_value(obs)
更多資訊,請參閱我們關於此的部落格文章。
5. 渲染模式更改¶
舊版 v0.21:每次指定渲染模式
env = gym.make("CartPole-v1")
env.render(mode="human") # Visual window
env.render(mode="rgb_array") # Get pixel array
新版 v0.26+:建立時固定渲染模式
env = gym.make("CartPole-v1", render_mode="human") # For visual display
env = gym.make("CartPole-v1", render_mode="rgb_array") # For recording
env.render() # Uses the mode specified at creation
為什麼會改變:有些環境無法在執行時切換渲染模式。在建立時固定模式可以實現更好的最佳化並防止錯誤。
實際影響:
# OLD: Could switch modes dynamically
env = gym.make("CartPole-v1")
for episode in range(10):
# ... episode code ...
if episode % 10 == 0:
env.render(mode="human") # Show every 10th episode
# NEW: Create separate environments for different purposes
training_env = gym.make("CartPole-v1") # No rendering for speed
eval_env = gym.make("CartPole-v1", render_mode="human") # Visual for evaluation
# Or use None for no rendering, then create visual env when needed
env = gym.make("CartPole-v1", render_mode=None) # Fast training
if need_visualization:
visual_env = gym.make("CartPole-v1", render_mode="human")
TimeLimit 封裝器更改¶
TimeLimit 封裝器的行為也已更改,以符合新的終止模型。
舊版 v0.21:將 TimeLimit.truncated 新增到 info 字典 ```python obs, reward, done, info = env.step(action) if done and info.get(‘TimeLimit.truncated’, False)
# 回合因時間限制而結束
新版 v0.26+:使用 truncated 返回值
obs, reward, terminated, truncated, info = env.step(action)
if truncated:
# Episode ended due to time limit (or other truncation)
pass
if terminated:
# Episode ended naturally (success/failure)
pass
這使得時間限制檢測更加清晰和明確。
## Updating Your Training Code
### Basic Training Loop Migration
**Old v0.21 pattern**:
```python
for episode in range(num_episodes):
obs = env.reset()
done = False
while not done:
action = agent.get_action(obs)
next_obs, reward, done, info = env.step(action)
# Train agent (this may have bugs due to ambiguous 'done')
agent.learn(obs, action, reward, next_obs, done)
obs = next_obs
新版 v0.26+ 模式:
for episode in range(num_episodes):
obs, info = env.reset(seed=episode) # Optional: unique seed per episode
terminated, truncated = False, False
while not (terminated or truncated):
action = agent.get_action(obs)
next_obs, reward, terminated, truncated, info = env.step(action)
# Train agent with proper termination handling
agent.learn(obs, action, reward, next_obs, terminated)
obs = next_obs
Q-Learning 更新遷移¶
舊版 v0.21(可能不正確):
def update_q_value(obs, action, reward, next_obs, done):
if done:
target = reward # Assumes all episode endings are natural terminations
else:
target = reward + gamma * max(q_table[next_obs])
q_table[obs][action] += lr * (target - q_table[obs][action])
新版 v0.26+(正確):
def update_q_value(obs, action, reward, next_obs, terminated):
if terminated:
# Natural termination - no future value
target = reward
else:
# Episode continues - truncation has no impact on the possible future value
target = reward + gamma * max(q_table[next_obs])
q_table[obs][action] += lr * (target - q_table[obs][action])
深度強化學習框架遷移¶
大多數庫已更新,請查閱其文件以獲取更多資訊。
環境特定更改¶
已移除的環境¶
部分環境已被移動或移除
# OLD: Robotics environments in main gym
import gym
env = gym.make("FetchReach-v1") # No longer available
# NEW: Moved to separate package
import gymnasium
import gymnasium_robotics
import ale_py
gymnasium.register_envs((gymnasium_robotics, ale_py))
env = gymnasium.make("FetchReach-v1")
env = gymnasium.make("ALE/Pong-v5")
相容性助手¶
使用舊版環境¶
如果您需要使用尚未更新到新 API 的環境
```python # 對於仍使用舊版 gym 的環境 env = gym.make(“GymV21Environment-v0”, env_id=”OldEnv-v0”)
# 此封裝器自動將舊版 API 轉換為新版 API
更多詳情,請參閱相容性指南 <gym_compatibility>_。
測試您的遷移¶
遷移後,請驗證以下幾點:
[ ] 匯入語句使用
gymnasium而非gym[ ] 重置呼叫處理
(obs, info)返回格式[ ] 步進呼叫單獨處理
terminated和truncated[ ] 渲染模式在環境建立時指定
[ ] 隨機種子使用
reset()中的seed引數[ ] 訓練演算法正確區分終止型別
使用 from gymnasium.utils.env_checker import check_env 來驗證它們的實現。
獲取幫助¶
如果您在遷移過程中遇到問題:
查閱相容性指南:一些舊環境可以透過相容性封裝器使用
查閱環境文件:每個環境可能有特定的遷移說明
首先使用簡單環境進行測試:從 CartPole 開始,然後再轉移到複雜環境
比較舊版與新版行為:使用兩種 API 執行相同的程式碼以瞭解差異
常見資源:
用於錯誤報告的GitHub issues
用於提問的Discord 社群