上一篇中引出了深度強化學習這個大坑,本篇淺淺填一下~~~~
目錄
6. 深度強化學習概述
6.1. 基本概念
6.2. 發展歷史
6.3. 基本公式
6.4. Python實現
6.5. 運行原理
6.5.1. 核心要素
6.5.2. 運行原理
6.5.3. 典型算法
6.5.4. Python實現代碼
6.6. 優缺點
6.6.1. 優點
6.6.2. 缺點
6.7. 游戲AI中的應用實例
6. 深度強化學習概述
6.1. 基本概念
深度強化學習(Deep Reinforcement Learning, DRL)是強化學習(Reinforcement Learning, RL)與深度學習(Deep Learning)的結合。
在強化學習中,智能體(Agent)通過與環境(Environment)的交互來學習如何完成任務。
它通過學習策略(Policy)來最大化從環境中獲得的累積獎勵(Reward)。
深度學習在這里用于估計策略或值函數(Value Function),使得強化學習能夠在高維空間(如圖像或語音)中進行有效的決策。
6.2. 發展歷史
深度強化學習的發展可以追溯到2013年DeepMind發表的DQN(Deep Q-Network)論文,該論文首次展示了深度學習模型可以在強化學習任務中成功應用,并實現了在Atari游戲上的超人類表現。
此后,DRL在AlphaGo等項目中大放異彩,進一步推動了其研究和應用。
6.3. 基本公式
- 策略(Policy):π(a|s),表示在狀態s下采取動作a的概率。
- 狀態值函數(State Value Function):Vπ(s),表示從狀態s開始,遵循策略π的期望回報。
- 動作值函數(Action Value Function):Qπ(s, a),表示在狀態s下采取動作a,然后遵循策略π的期望回報。
- 貝爾曼方程(Bellman Equation):
- Vπ(s) = E[R(s,a) + γVπ(s') | s0=s]
- Qπ(s, a) = E[R(s,a) + γmax_a' Qπ(s', a') | s0=s, a0=a]
其中,R是獎勵,γ是折扣因子,s'是下一個狀態。
6.4. Python實現
以下是一個簡單的深度Q網絡實現示例,使用PyTorch框架:
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import random class DQN(nn.Module): def __init__(self, input_size, output_size): super(DQN, self).__init__() self.fc1 = nn.Linear(input_size, 24) self.fc2 = nn.Linear(24, 24) self.fc3 = nn.Linear(24, output_size) def forward(self, x): x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) return self.fc3(x) class Agent: def __init__(self, input_size, output_size): self.network = DQN(input_size, output_size) self.optimizer = optim.Adam(self.network.parameters(), lr=0.001) self.loss_fn = nn.MSELoss() self.replay_memory = [] self.gamma = 0.99 self.epsilon = 1.0 self.epsilon_decay = 0.995 self.epsilon_min = 0.01 def act(self, state): if random.random() < self.epsilon: return random.randint(0, output_size-1) else: with torch.no_grad(): return self.network(state).argmax().item() def replay(self, batch_size): minibatch = random.sample(self.replay_memory, batch_size) states, actions, rewards, next_states, dones = zip(*minibatch) states = torch.tensor(states) actions = torch.tensor(actions) rewards = torch.tensor(rewards) next_states = torch.tensor(next_states) dones = torch.tensor(dones) q_vals = self.network(states).collect() next_q_vals = self.network(next_states).max(dim=1)[0].detach() expected_q_vals = rewards + self.gamma * next_q_vals * (1 - dones) loss = self.loss_fn(q_vals[range(len(actions)), actions], expected_q_vals) self.optimizer.zero_grad() loss.backward() self.optimizer.step() self.epsilon = max(self.epsilon_min, self.epsilon * self.epsilon_decay) # 實例化環境、代理等,并運行訓練循環
6.5. 運行原理
在游戲AI中,DRL允許AI智能體通過與環境互動,學習并優化其行為策略,以最大化累積獎勵。
6.5.1. 核心要素
DRL的核心要素包括:
- 智能體(Agent):執行動作的主體,通過與環境互動來學習。
- 環境(Environment):智能體所處的外部世界,可以是游戲世界、物理模擬器或現實世界的一部分。
- 狀態(State):環境的當前快照,包含智能體決策所需的所有信息。
- 動作(Action):智能體在特定狀態下可以采取的行為。
- 獎勵(Reward):環境對智能體動作的反饋,用于衡量動作的好壞。
- 策略(Policy):從狀態到動作的映射,指導智能體在給定狀態下應采取何種動作。
6.5.2. 運行原理
- 觀察(Observations):智能體在每個時間步驟上從環境中獲取狀態信息。
- 選擇動作(Action Selection):根據當前狀態和策略選擇執行的動作。
- 執行動作(Action Execution):智能體執行選定的動作,環境狀態隨之改變。
- 接收獎勵(Reward Reception):環境根據智能體的動作給出獎勵信號。
- 更新策略(Policy Update):智能體根據獎勵信號更新其策略,以最大化累積獎勵。
6.5.3. 典型算法
在游戲AI中,常用的DRL算法包括:
- 深度Q網絡(DQN):使用神經網絡來近似Q值函數,通過迭代更新Q值來學習最優策略。
- 策略梯度方法(Policy Gradient Methods):直接優化策略函數,如PPO(Proximal Policy Optimization)算法,通過最小化目標策略和原策略的對數似然差來優化策略。
- Actor-Critic方法:結合值函數和策略函數,一方面估計狀態-動作值函數,另一方面優化策略函數,如DDPG(Deep Deterministic Policy Gradient)算法。
6.5.4. Python實現代碼
?下面是一個簡化的Python代碼示例,展示了游戲AI使用深度強化學習的完整運行原理。這個例子使用了一個非常簡單的環境(比如一個格子世界),智能體(Agent)的目標是移動到這個格子的終點。我們將使用DQN(深度Q網絡)作為我們的強化學習算法。
import numpy as np
import random
from collections import deque
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam class DQNAgent: def __init__(self, state_size, action_size): self.state_size = state_size self.action_size = action_size self.memory = deque(maxlen=2000) self.gamma = 0.95 # discount rate self.epsilon = 1.0 # exploration rate self.epsilon_min = 0.01 self.epsilon_decay = 0.995 self.learning_rate = 0.001 self.model = self._build_model() def _build_model(self): # Neural Net for Deep-Q learning Model model = Sequential() model.add(Dense(24, input_dim=self.state_size, activation='relu')) model.add(Dense(24, activation='relu')) model.add(Dense(self.action_size, activation='linear')) model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate)) return model def remember(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) def act(self, state): if np.random.rand() <= self.epsilon: return random.randrange(self.action_size) act_values = self.model(state) return np.argmax(act_values[0]) # returns action def replay(self, batch_size): minibatch = random.sample(self.memory, batch_size) for state, action, reward, next_state, done in minibatch: target = reward if not done: target = (reward + self.gamma * np.amax(self.model.predict(next_state)[0])) target_f = self.model.predict(state) target_f[0][action] = target self.model.fit(state, target_f, epochs=1, verbose=0) if self.epsilon > self.epsilon_min: self.epsilon *= self.epsilon_decay class GridEnvironment: def __init__(self): self.state_size = 10 # assuming a simple grid world of size 10 self.action_size = 4 # move left, right, up, down def reset(self): return np.array([0] * self.state_size) # start state def step(self, action, state): # simple grid world logic if action == 0: # move left next_state = np.array(state - 1 if state > 0 else 0) elif action == 1: # move right next_state = np.array(state + 1 if state < self.state_size - 1 else self.state_size - 1) # add more actions as needed... reward = 1 if next_state == self.state_size - 1 else 0 # reward for reaching the end done = True if next_state == self.state_size - 1 else False return next_state, reward, done # Initialize environment and agent
env = GridEnvironment()
agent = DQNAgent(env.state_size, env.action_size) # Training loop
batch_size = 32
epochs = 1000 for e in range(epochs): state = env.reset() state = np.reshape(state, [1, env.state_size]) for time_t in range(50): # max steps per epoch action = agent.act(state) next_state, reward, done = env.step(action, state[0]) reward = reward if not done else -10 # penalty for ending the game next_state = np.reshape(next_state, [1, env.state_size]) agent.remember(state, action, reward, next_state, done) state = next_state if done: print("epoch: {}/{}, score: {}, e: {:.2}" .format(e, epochs, time_t, agent.epsilon)) break if len(agent.memory) > batch_size: agent.replay(batch_size)
這段代碼定義了一個簡單的格子世界環境和一個使用DQN的深度強化學習智能體。
智能體通過與環境互動來學習如何達到格子的終點,并在此過程中優化其策略。
代碼包括初始化環境和智能體、定義智能體的動作、對智能體動作的反饋獎勵、觀察、選擇動作、接收獎勵以及更新策略的所有步驟。
6.6. 優缺點
6.6.1. 優點
- 自主學習能力:DRL允許智能體通過與環境互動自主學習并優化策略,無需顯式編程復雜的規則。
- 適應性:能夠適應不同的環境變化,具有一定的泛化能力。
- 解決復雜任務:可以處理高維、非線性狀態和動作空間的問題,適用于復雜的游戲任務。
- 提高游戲體驗:通過模擬人類的學習過程,可以創造更有趣、更挑戰性的游戲。
- 發現創新策略:在游戲、機器人控制等領域,DRL能夠發現人類未曾預見的創新策略。
6.6.2. 缺點
- 訓練時間長:深度學習模型通常需要大量的樣本和計算資源,特別是對于復雜的任務,訓練可能非常耗時。
- 不穩定收斂:強化學習的回報往往不穩定,可能導致訓練過程不穩定或收斂困難。
- 解釋性較差:由于決策過程依賴于黑箱模型,理解模型如何做出決策有時較難。
- 過度擬合:沒有足夠的探索,模型可能會過度依賴已有的經驗,導致在新環境中表現不佳。
- 需要大量標注數據:盡管是無監督學習,但在某些領域仍需輔助指導,如預訓練的策略網絡。
- 倫理問題:在某些領域,如自動駕駛和金融交易中,DRL可能面臨倫理問題,如如何處理緊急情況、避免不當行為等。
6.7. 游戲AI中的應用實例
深度強化學習已被廣泛應用于各種游戲中,如Atari游戲、圍棋(AlphaGo)、星際爭霸II(AlphaStar)等。在這些應用中,DRL模型通過學習游戲中的策略,逐漸提高游戲水平,并最終達到或超過人類玩家的水平。
在實際應用中,需要根據具體游戲的特點設計狀態表示、獎勵函數等,以及選擇合適的DRL算法進行訓練。
以下是一個使用PyTorch實現的簡單深度Q網絡(DQN)代碼,用于訓練一個智能體在玩一個簡單的游戲(比如CartPole)時的策略。
請注意,為了運行此代碼,你需要先安裝gym
和pytorch
庫。
import gym
import torch
import torch.nn as nn
import torch.optim as optim
import random
from collections import deque class DQN(nn.Module): def __init__(self, input_size, output_size): super(DQN, self).__init__() self.fc1 = nn.Linear(input_size, 24) self.fc2 = nn.Linear(24, 24) self.fc3 = nn.Linear(24, output_size) def forward(self, x): x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) return self.fc3(x) class Agent: def __init__(self, state_size, action_size): self.state_size = state_size self.action_size = action_size self.memory = deque(maxlen=2000) self.model = DQN(state_size, action_size) self.optimizer = optim.Adam(self.model.parameters(), lr=0.001) self.loss_fn = nn.MSELoss() self.gamma = 0.99 self.epsilon = 1.0 self.epsilon_decay = 0.995 self.epsilon_min = 0.01 def act(self, state): if random.random() < self.epsilon: return random.randint(0, self.action_size - 1) else: with torch.no_grad(): state = torch.FloatTensor(state).unsqueeze(0) action_values = self.model(state) return action_values.argmax().item() def replay(self, batch_size): if len(self.memory) < batch_size: return minibatch = random.sample(self.memory, batch_size) state_batch, action_batch, reward_batch, next_state_batch, done_batch = zip(*minibatch) state_batch = torch.FloatTensor(state_batch) action_batch = torch.LongTensor(action_batch) reward_batch = torch.FloatTensor(reward_batch) next_state_batch = torch.FloatTensor(next_state_batch) done_batch = torch.BoolTensor(done_batch) q_vals = self.model(state_batch).collect() next_q_vals = self.model(next_state_batch).max(dim=1)[0].detach() expected_q_vals = reward_batch + self.gamma * next_q_vals * (1 - done_batch) loss = self.loss_fn(q_vals[range(len(action_batch)), action_batch], expected_q_vals) self.optimizer.zero_grad() loss.backward() self.optimizer.step() self.epsilon = max(self.epsilon_min, self.epsilon * self.epsilon_decay) def remember(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) # Initialize gym environment and the agent
env = gym.make('CartPole-v1')
state_size = env.observation_space.shape[0]
action_size = env.action_space.n
agent = Agent(state_size, action_size) # Training loop
num_episodes = 1000
for e in range(num_episodes): state = env.reset() for timestep in range(1000): action = agent.act(state) next_state, reward, done, _ = env.step(action) agent.remember(state, action, reward, next_state, done) state = next_state if done: print("episode: {}/{}, score: {}, e: {:.2}" .format(e, num_episodes, timestep, agent.epsilon)) break agent.replay(32)
這段代碼首先定義了一個簡單的DQN網絡,然后定義了一個Agent類,該類包含了DQN模型、優化器、損失函數以及一些用于訓練和決策的方法。
在訓練循環中,智能體通過與環境交互來學習如何玩游戲。每當智能體采取一個動作,它都會記住這個經驗(狀態、動作、獎勵、下一個狀態、是否結束),并定期使用這些經驗來更新它的模型。
這個代碼是基于CartPole游戲開發的。CartPole是OpenAI Gym庫中的一個經典控制問題,用于測試強化學習算法。在CartPole游戲中,目標是通過左右移動一個底部裝有單擺的小車,來保持單擺豎直向上。如果單擺偏離垂直位置太遠,或者小車移動出屏幕,游戲就會結束。
在提供的代碼中,通過定義一個DQN(深度Q網絡)模型和一個Agent類,實現了智能體與環境(CartPole游戲)的交互,并通過強化學習的方法(如經驗回放和ε-貪心策略)來訓練智能體,使其學會如何玩CartPole游戲。
值得注意的是,雖然原始問題可能詢問的是類似貪吃蛇這樣的經典游戲,但提供的代碼實際上是針對CartPole游戲的一個實現示例。這可能是因為CartPole游戲因其簡單性和易于實現,在強化學習領域被廣泛用作測試基準。而貪吃蛇游戲雖然也是一個經典的游戲,但其實現可能涉及更復雜的游戲邏輯和圖形界面處理,因此在強化學習的入門示例中可能較少見到。不過,使用Pygame等庫也可以實現貪吃蛇游戲的圖形界面和基本邏輯。