在本文中,我們將介紹在 Reacher 環境中訓練智慧代理控制雙關節機械手臂,這是使用 Unity ML-Agents 工具包開發的基於 Unity 的模擬程式。我們的目標是高精準度的到達目標位置,所以這裡我們可以使用專為連續狀態和動作空間設計的最先進的Deep Deterministic Policy Gradient (DDPG) 演算法。
機械手臂在製造業、生產設施、空間探索和搜救行動中發揮關鍵作用。控制機械手臂的高精度和靈活性是非常重要的。透過採用強化學習技術,可以使這些機器人系統即時學習和調整其行為,從而提高性能和靈活性。強化學習的進步不僅有助於我們對人工智慧的理解,而且有可能徹底改變產業並對社會產生有意義的影響。
而Reacher是一種機械手臂模擬器,常用於控制演算法的開發和測試。它提供了一個虛擬環境,模擬了機械手臂的物理特性和運動規律,使得開發者可以在不需要實際硬體的情況下進行控制演算法的研究和實驗。
Reacher的環境主要由以下幾個部分組成:
Reacher模擬器是一個非常實用的工具,可以幫助開發者在不需要實際硬體的情況下,快速測試並最佳化控制演算法。
Reacher 使用 Unity ML-Agents 工具包構建,我們的代理可以控制雙關節機械手臂。目標是引導手臂朝向目標位置並盡可能長時間地保持在目標區域內的位置。該環境具有 20 個同步代理,每個代理獨立運行,這有助於在訓練期間有效地收集經驗。
了解狀態和動作空間對於設計有效的強化學習演算法至關重要。在 Reacher 環境中,狀態空間由 33 個連續變數組成,這些變數提供有關機械手臂的信息,例如其位置、旋轉、速度和角速度。動作空間也是連續的,四個變數對應於施加在機械手臂兩個關節上的扭矩。每個動作變數都是介於 -1 和 1 之間的實數。
Reacher 任務被認為是片段式的,每個片段都包含固定數量的時間步長。代理的目標是在這些步驟中最大化其總獎勵。手臂末端執行器保持在目標位置的每一步都會獲得 0.1 的獎勵。當代理人在連續 100 次操作中的平均得分達到 30 分或以上時,就認為成功。
了解了環境,以下我們將探討 DDPG 演算法、它的實現,以及它如何有效地解決這種環境中的連續控制問題。
當涉及像Reacher問題這樣的連續控制任務時,演算法的選擇對於實現最佳效能至關重要。在這個專案中,我們選擇了DDPG演算法,因為這是一種專門設計用於處理連續狀態和動作空間的actor-critic方法。
DDPG演算法透過結合兩個神經網絡,結合了基於策略和基於值的方法的優勢:行動者網絡(Actor network)決定給定當前狀態下的最佳行為,批評家網絡(Critic network)估計狀態-行為值函數(Q-function)。這兩個網絡都有目標網絡,透過在更新過程中提供一個固定的目標來穩定學習過程。
透過使用Critic網路估計q函數,使用Actor網路確定最優行為,DDPG演算法有效地融合了策略梯度方法和DQN的優點。這種混合方法允許代理在連續控制環境中有效地學習。
<code>import random from collections import deque import torch import torch.nn as nn import numpy as np from actor_critic import Actor, Critic class ReplayBuffer: def __init__(self, buffer_size, batch_size): self.memory = deque(maxlen=buffer_size) self.batch_size = batch_size def add(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) def sample(self): batch = random.sample(self.memory, self.batch_size) states, actions, rewards, next_states, dones = zip(*batch) return states, actions, rewards, next_states, dones def __len__(self): return len(self.memory) class DDPG: def __init__(self, state_dim, action_dim, hidden_dim, buffer_size, batch_size, actor_lr, critic_lr, tau, gamma): self.actor = Actor(state_dim, hidden_dim, action_dim, actor_lr) self.actor_target = Actor(state_dim, hidden_dim, action_dim, actor_lr) self.critic = Critic(state_dim, action_dim, hidden_dim, critic_lr) self.critic_target = Critic(state_dim, action_dim, hidden_dim, critic_lr) self.memory = ReplayBuffer(buffer_size, batch_size) self.batch_size = batch_size self.tau = tau self.gamma = gamma self._update_target_networks(tau=1)# initialize target networks def act(self, state, noise=0.0): state = torch.tensor(state, dtype=torch.float32).unsqueeze(0) action = self.actor(state).detach().numpy()[0] return np.clip(action + noise, -1, 1) def store_transition(self, state, action, reward, next_state, done): self.memory.add(state, action, reward, next_state, done) def learn(self): if len(self.memory) </code>
上面的程式碼也使用了Replay Buffer,這可以提高學習效率和穩定性。 Replay Buffer本質上是一種儲存固定數量的過去經驗或過渡的記憶體資料結構,由狀態、動作、獎勵、下一狀態和完成資訊組成。使用它的主要優點是使代理人能夠打破連續經驗之間的相關性,從而減少有害的時間相關性的影響。
透過從緩衝區中抽取隨機的小批量經驗,代理可以從一組不同的轉換中學習,這有助於穩定和概括學習過程。 Replay Buffer還可以讓代理程式多次重複使用過去的經驗,從而提高資料效率並促進從與環境的有限互動中更有效地學習。
DDPG演算法是一個很好的選擇,因為它能夠有效地處理連續的動作空間,這是這個環境的關鍵方面。此演算法的設計允許有效地利用多個代理程式收集的並行經驗,從而實現更快的學習和更好的收斂。就像上面介紹的Reacher 可以同時運行20個代理,所以我們可以使用這20個代理進行分享經驗,集體學習,提高學習速度。
完成了演算法,以下我們將介紹、超參數選擇和訓練過程。
為了更好地理解演算法在環境中的有效性,我們需要仔細研究學習過程中涉及的關鍵組件和步驟。
DDPG演算法採用兩個神經網絡,Actor 和Critic。兩個網路都包含兩個隱藏層,每個隱藏層包含400個節點。隱藏層使用ReLU (Rectified Linear Unit)來啟動函數,而Actor網路的輸出層則使用tanh激活函數產生範圍為-1到1的動作。 Critic網路的輸出層沒有活化函數,因為它直接估計q函數。
以下是網路的程式碼:
<code>import numpy as np import torch import torch.nn as nn import torch.optim as optim class Actor(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim, learning_rate=1e-4): super(Actor, self).__init__() self.fc1 = nn.Linear(input_dim, hidden_dim) self.fc2 = nn.Linear(hidden_dim, hidden_dim) self.fc3 = nn.Linear(hidden_dim, output_dim) self.tanh = nn.Tanh() self.optimizer = optim.Adam(self.parameters(), lr=learning_rate) def forward(self, state): x = torch.relu(self.fc1(state)) x = torch.relu(self.fc2(x)) x = self.tanh(self.fc3(x)) return x class Critic(nn.Module): def __init__(self, state_dim, action_dim, hidden_dim, learning_rate=1e-4): super(Critic, self).__init__() self.fc1 = nn.Linear(state_dim, hidden_dim) self.fc2 = nn.Linear(hidden_dim + action_dim, hidden_dim) self.fc3 = nn.Linear(hidden_dim, 1) self.optimizer = optim.Adam(self.parameters(), lr=learning_rate) def forward(self, state, action): x = torch.relu(self.fc1(state)) x = torch.relu(self.fc2(torch.cat([x, action], dim=1))) x = self.fc3(x) return x</code>
選擇的超參數對於高效學習至關重要。在這個專案中,我們的Replay Buffer大小為200,000,批次大小為256。演員Actor的學習率為5e-4,Critic的學習率為1e-3,soft update參數(tau)為5e-3,gamma為0.995。最後也加入了動作噪音,初始噪音標度為0.5,噪音衰減率為0.998。
訓練過程涉及兩個網絡之間的持續交互,並且20個平行代理共享相同的網絡,模型會從所有代理收集的經驗中集體學習。這種設定加快了學習過程,提高了效率。
<code>from collections import deque import numpy as np import torch from ddpg import DDPG def train_ddpg(env, agent, episodes, max_steps, num_agents, noise_scale=0.1, noise_decay=0.99): scores_window = deque(maxlen=100) scores = [] for episode in range(1, episodes + 1): env_info = env.reset(train_mode=True)[brain_name] states = env_info.vector_observations agent_scores = np.zeros(num_agents) for step in range(max_steps): actions = agent.act(states, noise_scale) env_info = env.step(actions)[brain_name] next_states = env_info.vector_observations rewards = env_info.rewards dones = env_info.local_done for i in range(num_agents): agent.store_transition(states[i], actions[i], rewards[i], next_states[i], dones[i]) agent.learn() states = next_states agent_scores += rewards noise_scale *= noise_decay if np.any(dones): break avg_score = np.mean(agent_scores) scores_window.append(avg_score) scores.append(avg_score) if episode % 10 == 0: print(f"Episode: {episode}, Score: {avg_score:.2f}, Avg Score: {np.mean(scores_window):.2f}") # Saving trained Networks torch.save(agent.actor.state_dict(), "actor_final.pth") torch.save(agent.critic.state_dict(), "critic_final.pth") return scores if __name__ == "__main__": env = UnityEnvironment(file_name='Reacher_20.app') brain_name = env.brain_names[0] brain = env.brains[brain_name] state_dim = 33 action_dim = brain.vector_action_space_size num_agents = 20 # Hyperparameter suggestions hidden_dim = 400 batch_size = 256 actor_lr = 5e-4 critic_lr = 1e-3 tau = 5e-3 gamma = 0.995 noise_scale = 0.5 noise_decay = 0.998 agent = DDPG(state_dim, action_dim, hidden_dim=hidden_dim, buffer_size=200000, batch_size=batch_size,actor_lr=actor_lr, critic_lr=critic_lr, tau=tau, gamma=gamma) episodes = 200 max_steps = 1000 scores = train_ddpg(env, agent, episodes, max_steps, num_agents, noise_scale=0.2, noise_decay=0.995)</code>
訓練過程中的關鍵步驟如下所示:
初始化網路:代理人使用隨機權重初始化共享的 Actor 和 Critic 網路及其各自的目標網路。目標網路在更新期間提供穩定的學習目標。
我們的agent使用DDPG演算法成功地學會了在Racher環境下控制雙關節機械手臂。在整個訓練過程中,我們根據所有20個代理的平均得分來監控代理的表現。隨著智能體探索環境和收集經驗,其預測獎勵最大化最佳行為的能力顯著提高。
可以看到代理在任務中表現出了顯著的熟練程度,平均得分超過了解決環境所需的閾值(30 ),雖然代理的表現在整個訓練過程中有所不同,但整體趨勢呈上升趨勢,顯示學習過程是成功的。
下圖顯示了20個代理程式的平均分數:
可以看到我們實作的DDPG演算法,有效地解決了Racher環境的問題。代理能夠調整自己的行為,並在任務中達到預期的表現。
本項目中的超參數是根據文獻和實證測試的建議組合選擇的。還可以透過系統超參數調優的進一步最佳化可能會帶來更好的效能。
多agent並行訓練:在這個專案中,我們使用20個agent同時收集經驗。使用更多代理程式對整個學習過程的影響可能會導致更快的收斂或提高表現。
批歸一化:為了進一步增強學習過程,在神經網路架構中實現批歸一化是值得探索的。透過在訓練過程中對每一層的輸入特徵進行歸一化,批歸一化可以幫助減少內部協變量移位,加速學習,並潛在地提高泛化。將批次歸一化加入Actor和Critic網路可能會導致更穩定和有效的訓練,但這個需要進一步測試。
以上是使用Actor-Critic的DDPG強化學習演算法控制雙關節機械手臂的詳細內容。更多資訊請關注PHP中文網其他相關文章!