AI+Python:解鎖人形機器人訓練術
譯者 | 朱先忠
審校 | 重樓
引言
人形機器人,是指外形和動作都與人體相似的機器,旨在與人類協同工作并與我們的工具進行交互。雖然這項技術仍處于發展初期,但據預測,到2050年,人形機器人的數量將達到數十億。目前,最先進的原型機包括:1XTech公司的??NEO???、特斯拉公司的??Optimus???、波士頓動力公司的??Atlas???以及中國宇創科技的??G1??。
機器人執行任務的方式有兩種:手動控制(即預先編寫程序控制其行為)和人工智能(即通過反復嘗試學習如何完成任務)。具體來說,強化學習使機器人能夠通過試錯法學習達成目標的最佳行動方案,從而在沒有預先設定計劃的情況下,通過學習獎勵和懲罰機制來適應不斷變化的環境。
實際上,讓一個真正的機器人學習如何執行任務成本極其高昂。因此,目前最先進的方法是在仿真環境中進行學習,因為仿真環境的數據生成速度快、成本低,然后將學習到的知識遷移到真正的機器人上(“仿真到真實”/“仿真優先”方法)。這使得在仿真環境中并行訓練多個模型成為可能。
當前,市面上最常用的3D物理模擬器包括:??PyBullet???(入門級)、??Webots???(中級)、??MuJoCo???(高級)和??Gazebo???(專業級)。你可以將它們作為獨立軟件使用,也可以通過??Gym??庫來使用。Gym是由OpenAI開發的強化學習算法庫,它基于不同的物理引擎構建。
在本教程中,我將展示如何構建一個具有人工智能的人形機器人的3D仿真模型。我將提供一些實用的Python代碼,這些代碼可以輕松應用于其他類似場景(只需復制、粘貼、運行),并逐行講解代碼,以便你能夠復現此示例(文章末尾附有示例工程的完整的源代碼的鏈接)。
設置
環境是一個模擬空間,智能體可以在其中進行交互并學習執行任務。它具有明確的觀察空間(智能體接收的信息)和行動空間(可能采取的行動集合)。
我將使用Gym(pip install gymnasium)加載使用MuJoCo(多關節動力學與接觸)創建的??默認環境??之一。
pip install mujoco
import gymnasium as gym
env = gym.make("Humanoid-v4", render_mode="human")
obs, info = env.reset()
env.render()
該智能體是一個能夠像人類一樣移動的3D雙足機器人。它有12個連桿(剛性部件)和17個關節(柔性部件)。你可以在這里查看完整描述。
在開始新的模擬之前,必須使用`setenv`命令重置環境obs, info = env.reset()。該命令會返回有關智能體初始狀態的信息。通常,info還包含有關機器人的額外信息。

雖然這個obs是智能體(例如通過傳感器)所看到的,但人工智能模型需要處理這些觀察結果才能決定采取什么行動。

通常,所有??Gym環境??都具有相同的結構。首先要檢查的是動作空間,即所有可能動作的集合。對于人形機器人模擬,一個動作代表施加在其17個關節之一上的力(范圍在-0.4到+0.4之間,以指示推力的方向)。
env.action_space
env.action_space.sample()
模擬至少應涵蓋一個完整回合,即智能體與環境交互的完整過程,從開始到結束。每個回合都是一個循環:reset() -> step() -> render()。讓我們舉一個例子,讓類人機器人做隨機動作,而不是人工智能。
import time
env = gym.make("Humanoid-v4", render_mode="human")
obs, info = env.reset()
reset = False #如果人形機器人摔倒或這一部分動作結束,則重置
episode = 1
total_reward, step = 0, 0
for _ in range(240):
## 動作
step += 1
action = env.action_space.sample() #隨機動作
obs, reward, terminated, truncated, info = env.step(action)
## 獎勵
total_reward += reward
## 渲染
env.render() #render physics step (CPU speed = 0.1 seconds)
time.sleep(1/240) #減慢到實時情況下 (240 steps × 1/240 second sleep = 1 second)
if (step == 1) or (step % 100 == 0): #打印第一步和每100步
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
## 重置
if reset:
if terminated or truncated: #打印最后一步
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
obs, info = env.reset()
episode += 1
total_reward, step = 0, 0
print("------------------------------------------")
env.close()

隨著游戲進程的推進,機器人不斷移動,我們會獲得獎勵。在這種情況下,如果機器人保持站立或向前移動,則獲得正獎勵;如果機器人跌倒并觸地,則受到負懲罰。獎勵是人工智能中最重要的概念,因為它定義了目標。它是每次動作后我們從環境獲得的反饋信號,指示該動作是否有效。因此,我們可以利用獎勵,通過強化學習來優化機器人的決策。
強化學習
在模擬的每一步,智能體都會觀察當前情況(即其在環境中的位置),決定采取什么行動(即移動某個關節),并收到正面或負面的反饋(獎勵或懲罰)。這個循環不斷重復,直到模擬結束。強化學習是一種機器學習方法,它通過反復試錯使智能體最大化獎勵。因此,如果成功,機器人就能知道最佳行動方案是什么。
從數學角度來看,強化學習基于馬爾可夫決策過程;其中,未來僅取決于當前情況,而與過去無關。簡單來說,智能體無需記憶之前的步驟即可決定下一步行動。例如,機器人只需知道其當前位置和速度即可選擇下一步移動,無需記住它是如何到達那里的。
強化學習的核心在于最大化獎勵。因此,構建模擬系統的關鍵在于設計一個能夠真正反映預期結果的獎勵函數(這里的目標是避免失敗)。最基本的強化學習算法會在獲得正獎勵后更新首選動作列表。更新的速度就是學習率:如果學習率過高,智能體會過度修正;如果學習率過低,智能體則會不斷犯同樣的錯誤,學習速度極其緩慢。
首選行動的更新也受到探索率的影響,探索率是隨機選擇的頻率,本質上反映了人工智能的好奇心。通常,探索率在初期(智能體一無所知時)相對較高,隨著機器人不斷積累知識,探索率會逐漸下降。
import gymnasium as gym
import time
import numpy as np
env = gym.make("Humanoid-v4", render_mode="human")
obs, info = env.reset()
reset = True #如果人形機器人摔倒或這一部分動作結束,則重置
episode = 1
total_reward, step = 0, 0
exploration_rate = 0.5
preferred_action = np.zeros(env.action_space.shape) #知識隨著經驗而更新
for _ in range(1000):
## 動作
step += 1
exploration = np.random.normal(loc=0, scale=exploration_rate, size=env.action_space.shape) #add random noise
action = np.clip(a=preferred_action+exploration, a_min=-1, a_max=1)
obs, reward, terminated, truncated, info = env.step(action)
## 獎勵
total_reward += reward
if reward > 0:
preferred_action += (action-preferred_action)*0.05 #學習率
exploration_rate = max(0.05, exploration_rate*0.99) #min_exploration=0.05, decay_exploration=0.99
## 渲染
env.render()
time.sleep(1/240)
if (step == 1) or (step % 100 == 0):
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
## 重置
if reset:
if terminated or truncated:
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
obs, info = env.reset()
episode += 1
total_reward, step = 0, 0
print("------------------------------------------")
env.close()

顯然,對于像人形機器人這樣復雜的環境來說,這太簡單了;所以,即使智能體更新了首選動作,它仍然會不斷跌倒。
深度強化學習
當行為與獎勵之間的關系是非線性的時,就需要神經網絡。深度強化學習能夠處理高維輸入,并利用深度神經網絡的強大功能來估計行為的預期未來獎勵。
在Python中,使用深度強化學習算法最簡單的方法是通過??StableBaseline???,它收集了最知名的模型,這些模型已經預先實現,可以直接使用。請注意,StableBaseline分為兩個版本:StableBaseline(用TensorFlow編寫)和StableBaselines3(用??PyTorch??編寫)。目前,大家都在使用后者。
pip install torch
pip install stable-baselines3近端策略優化(??PPO??)是深度強化學習中最常用的算法之一,因為它簡單且穩定。PPO的目標是在保持策略穩定增長的前提下,通過對策略進行微小的更新來最大化預期總獎勵。
我將使用StableBaseline在Gym Humanoid環境下訓練一個PPO模型。以下幾點需要注意:
- 我們不需要對環境進行圖形渲染,因此訓練可以加快速度。
- 必須將Gym環境封裝起來DummyVecEnv,使其與StableBaseline矢量化格式兼容。
- 關于神經網絡模型,PPO使用多層感知器(MlpPolicy)處理數值輸入,使用卷積神經網絡(CnnPolicy)處理圖像,使用組合模型(MultiInputPolicy)處理混合類型的觀測值。
- 由于我沒有渲染人形模型,我發現使用??TensorBoard??(一個用于實時可視化統計數據的工具包pip install tensorboard)來查看訓練進度非常有用。我創建了一個名為“logs”的文件夾,然后就可以tensorboard --logdir=logs/在終端運行命令來在本地查看儀表盤http://localhost:6006/了。
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
## 環境
env = gym.make("Humanoid-v4") #無需加速渲染
env = DummyVecEnv([lambda:env])
## 訓練
print("Training START")
model = PPO(policy="MlpPolicy", env=env, verbose=0,
learning_rate=0.005, ent_coef=0.005, #探索
tensorboard_log="logs/") #>tensorboard --logdir=logs/
model.learn(total_timesteps=3_000_000, #1h
tb_log_name="model_humanoid", log_interval=10)
print("Training DONE")
## 保存
model.save("model_humanoid")
訓練完成后,我們可以加載新模型并在渲染環境中進行測試。此時,智能體將不再更新首選動作,而是使用訓練好的模型,根據當前狀態預測下一個最佳動作。
env = gym.make("Humanoid-v4", render_mode="human")
model = PPO.load(path="model_humanoid", env=env)
obs, info = env.reset()
reset = False #如果人形機器人摔倒或這一部分動作結束;則重置
episode = 1
total_reward, step = 0, 0
for _ in range(1000):
## 動作
step += 1
action, _ = model.predict(obs)
obs, reward, terminated, truncated, info = env.step(action)
## 獎勵
total_reward += reward
## 渲染
env.render()
time.sleep(1/240)
if (step == 1) or (step % 100 == 0): #打印第一步和每100步
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
## 重置
if reset:
if terminated or truncated: #打印最后一步
print(f"EPISODE {episode} - Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}")
obs, info = env.reset()
episode += 1
total_reward, step = 0, 0
print("------------------------------------------")
env.close()
請注意,本教程中我們從未專門編寫程序讓機器人保持站立。我們并沒有控制機器人;機器人只是對環境的獎勵函數做出反應。事實上,如果你訓練強化學習模型更長時間(例如3000萬個時間步),你不僅會看到機器人完美地站立起來,還會看到它向前行走。因此,在訓練人工智能智能體時,3D世界的設計及其規則比構建機器人本身更為重要。
結論
本文旨在介紹MuJoCo和Gym,以及如何創建用于機器人的3D仿真模型。我們使用人形機器人環境來學習強化學習的基礎知識。具體地說,我們訓練了一個深度神經網絡來教會機器人如何避免跌倒。后續還將推出使用更高級機器人的教程。
本文完整源代碼:??GitHub??
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。

















