強化學習和監督學習、無監督學習的區別RL解決什麼問題RL如何解決問題實例視頻openAI and DeepMind馬爾科夫時序差分(Temporal-Difference)分類Model-freeModel-base基於概率基於價值回合更新單步更新在線學習 on-Policy離線學習 off-PolicyQ-learningQ-learning 實例Q-learning 算法更新Q-learning 思維決策sarsa 思維決策DQN 算法更新DQN 神經網絡 (Tensorflow)
learning route
AI = DL(Deep Learning) + RL(Reinforcement Learning) == DRL(Deep Reinforcement Learning)什麼是強化學習?強化學習是學習該如何去做(learning what to do)即學習如何從一個狀態映射到某一個行為,來最大化某一個數值的獎勵信號。強化學習算法主體是智能體,環境是老師,老師僅僅是評分,不告訴智能體為什麼錯,為什麼對?智能體不斷的試錯,不斷的嘗試,累計經驗,學習經驗。記住高分的行為,避免低分的行為。強化學習作為一門靈感來源於心理學中的行為主義理論的學科,其內容涉及概率論、統計學、逼近論、凸分析、計算複雜性理論、運籌學等多學科知識,難度之大,門檻之高,導致其發展速度特別緩慢。強化學習特徵:試錯:agent需要不斷的嘗試,通過reward的反饋學習策略。延遲獎勵:某一時刻action可能會對後面時刻reward有影響。強化學習局限性強化學習非常依賴狀態state的概念,state既是策略函數和價值函數的輸入,又是環境模型model的輸入和輸出。強化學習適合解決什麼問題強化學習適合於解決模型未知,且當前決策會影響環境狀態的(序列)決策問題。強化學習和監督學習、無監督學習的區別
監督學習一般有標籤信息,而且是單步決策問題,比如分類問題。監督學習的樣本一般是獨立 同分布的。無監督學習沒有任何標籤信息,一般對應的是聚類問題。強化學習介於監督和無監督學習之間,每一步決策之後會有一個標量的反饋信號,即回報。通過最大化回報以獲得一個最優策略。因此強化學習一般是多步決策,並且樣本之間有強的相關性。強化學習的損失函數累計回報:依賴於不同的問題設定,累積回報具有不同的形式。比如對於有限長度的MDP問題直接用回報和作為優化目標。對於無限長的問題,為了保證求和是有意義的,需要使用折扣累積回報或者平均回報。深度學習算是函數:多個獨立同分布樣本預測值和標籤值的誤差,需要最小化。強化學習 的損失函數是軌跡上的累積和,需要最大化。強化學習
RL解決什麼問題
就是需要連續不斷地做出決策,才能實現最終目標的問題。RL如何解決問題
強化學習算法是根據與環境的交互產生的反饋,從而達到最終目標實例
實例視頻
1.機器人炒股模擬人誇障礙學習抓取東西學會抓取學穿衣服openAI and DeepMind
https://openai.com/openai:開源庫 gym基礎
基礎概念:state、 action、 reward function value function 、policy、modle of the environment在炒股機器人中:動作(action)是買還是賣,或者更具體的,買多少,賣多少。狀態(state)是機器人對環境的觀察,這就非常多樣,比如說某支股票的漲跌現狀、各種技術面的特徵、基本面的特徵等等。獎勵(reward function)是機器人每做一次買賣決策之後,帶來的實際收益;回報(return):一般用表示,形式化定義: ,回報的定義很有趣,即某一系列決策後,長期的獎勵累加,我們給後面的獎勵一個折扣係數,即對未來可能賺的錢,我們的興趣相對少一些;價值函數(value function)是我們對回報的期望,用來衡量處於某個狀態有多好;環境模型(model)用來模擬環境的行為,給定一個狀態和動作,模型可以預測下一個狀態和獎勵。也就是說,如果我們有一個環境模型,那麼每次機器人做了一次交易之後,我們就可以預測出它的下一個狀態是什麼,收到的獎勵有多少(這個觀點在炒股票這個例子中聽起來不太可行)。policy:狀態到行為的映射,定義agent在某一個狀態下應該如何採取行為,state-> action構建智能體import randomclassEnvironment:def__init__(self): self.steps_left = 100defget_observation(self):return [0.0, 0.0, 0.0]defget_actions(self):return [0, 1]defis_done(self):return self.steps_left == 0defaction(self, action):if self.is_done():raise Exception("Game is over") self.steps_left -= 1return random.random()classAgent:def__init__(self): self.total_reward = 0.0defstep(self, env): current_obs = env.get_observation() actions = env.get_actions() reward = env.action(random.choice(actions)) self.total_reward += rewardif __name__ == "__main__": env = Environment() agent = Agent()whilenot env.is_done(): agent.step(env) print("Total reward got: %.4f" % agent.total_reward)智能體演示import gymif __name__ == "__main__": env = gym.make("CartPole-v0") env = gym.wrappers.Monitor(env, "recording") total_reward = 0.0 total_steps = 0 obs = env.reset()whileTrue: action = env.action_space.sample() obs, reward, done, _ = env.step(action) total_reward += reward total_steps += 1if done:break print("Episode done in %d steps, total reward %.2f" % (total_steps, total_reward)) env.close() env.env.close()模型import torchimport torch.nn as nnclassOurModule(nn.Module):def__init__(self, num_inputs, num_classes, dropout_prob=0.3): super(OurModule, self).__init__() self.pipe = nn.Sequential( nn.Linear(num_inputs, 5), nn.ReLU(), nn.Linear(5, 20), nn.ReLU(), nn.Linear(20, num_classes), nn.Dropout(p=dropout_prob), nn.Softmax(dim=1) )defforward(self, x):return self.pipe(x)if __name__ == "__main__": net = OurModule(num_inputs=2, num_classes=3) print(net) v = torch.FloatTensor([[2, 3]]) out = net(v) print(out) print("Cuda's availability is %s" % torch.cuda.is_available())if torch.cuda.is_available(): print("Data from cuda: %s" % out.to('cuda'))馬爾科夫
Markov Reward Processes(MRPs)Markov Decision Processes (MDPs)動態規劃(Dynamic Programming):理論上完美,但需要很強的算力和準確的環境model。蒙特卡洛(Monte Carlo Methods):不需要模型,可操作性強,但不太適合一步一步的增量計算。差分學習(Temporal-Difference Learning):不需要模型,也是增量式的,但分析起來很複雜。解決辦法POMDP:部分可觀測馬爾科夫決策問題。馬爾科夫過程表示一個狀態序列,每一個狀態是一個隨機變量,變量之間滿足馬爾科夫性,表示為 一個元組<S, P>,S是狀態,P表示轉移概率。MDP表示為一個五元組<S, A, P, R, >,S是狀態集合,A是動作集合,P表示轉移概率,即模型, R是回報函數,表示折扣因子。時序差分(Temporal-Difference)
時序差分是強化學習的核心觀點。時序差分是DP和MC方法的結合。TD往往比MC高效;TD和MC都使用經驗(experience)來解決預測問題。強化學習方法
分類
Model-free
不理解環境Q learning, Sarsa, Policy GradientsModel-base
理解環境基於概率
基於概率是強化學習中最直接的一種, 他能通過感官分析所處的環境, 直接輸出下一步要採取的各種動作的概率, 然後根據概率採取行動, 所以每種動作都有可能被選中, 只是可能性不同.連續的動作基於概率的方法是有效的Policy Gradients,基於價值
基於價值的方法輸出則是所有動作的價值, 我們會根據最高價值來選著動作, 相比基於概率的方法, 基於價值的決策部分更為鐵定, 毫不留情, 就選價值最高的。連續的動作基於價值的方法是無能為力的Q learning, SarsaActor-Critic, actor 會基於概率做出動作, 而 critic 會對做出的動作給出動作的價值, 這樣就在原有的 policy gradients 上加速了學習過程.回合更新
學習效率低Monte-carlo learning 和基礎版的 policy gradients單步更新
學習效率高Qlearning, Sarsa, 升級版的 policy gradients 等在線學習 on-Policy
智能體:邊玩邊總結學習最典型的在線學習就是 Sarsa離線學習 off-Policy
智能體:從歷史的記錄中學習,看別人的棋譜最典型的離線學習就是 Q learning, 後來人也根據離線學習的屬性, 開發了更強大的算法, 比如讓計算機學會玩電動的 Deep-Q-Network.Q-learning
Q-learning
2da3885da644cb681fcc4adb2be47ac7.pngQ learning 的迷人之處就是 在 Q(s1, a2) 現實 中, 也包含了一個 Q(s2) 的最大估計值, 將對下一步的衰減的最大估計和當前所得到的獎勵當成這一步的現實, 很奇妙吧. 最後我們來說說這套算法中一些參數的意義. Epsilon greedy 是用在決策上的一種策略, 比如 epsilon = 0.9 時, 就說明有90% 的情況我會按照 Q 表的最優值選擇行為, 10% 的時間使用隨機選行為. alpha是學習率, 來決定這次的誤差有多少是要被學習的, alpha是一個小於1 的數. gamma 是對未來 reward 的衰減值.572458142e9790b40543a859135490c5.png重寫一下 Q(s1) 的公式, 將 Q(s2) 拆開, 因為Q(s2)可以像 Q(s1)一樣,是關於Q(s3) 的, 所以可以寫成這樣, 然後以此類推, 不停地這樣寫下去, 最後就能寫成這樣, 可以看出Q(s1) 是有關於之後所有的獎勵, 但這些獎勵正在衰減, 離 s1 越遠的狀態衰減越嚴重. 不好理解? 行, 我們想像 Qlearning 的機器人天生近視眼, gamma = 1 時, 機器人有了一副合適的眼鏡, 在 s1 看到的 Q 是未來沒有任何衰變的獎勵, 也就是機器人能清清楚楚地看到之後所有步的全部價值, 但是當 gamma =0, 近視機器人沒了眼鏡, 只能摸到眼前的 reward, 同樣也就只在乎最近的大獎勵, 如果 gamma 從 0 變到 1, 眼鏡的度數由淺變深, 對遠處的價值看得越清楚, 所以機器人漸漸變得有遠見, 不僅僅只看眼前的利益, 也為自己的未來著想.Q-learning 實例
# -*- coding:utf-8 -*-# /usr/bin/python'''---- File Name : Q_learning_class Description : AIM: Functions: 1. 2. Envs : python == pip install numpy pandas -i https://pypi.douban.com/simple Author : errol Date : 2020/5/18 14:35 CodeStyle : 規範,簡潔,易懂,可閱讀,可維護,可移植!---- Change Activity: 2020/5/18 : 新建----'''import timeimport numpy as npimport pandas as pdnp.random.seed(2) # 隨機因子class QL(object): def __init__(self,):''' 定義變量 ''' self.N_STATES = 6 # 探索世界的寬度 self.ACTIONS = ['left', 'right'] # 智能體的行為 self.EPSILON = 0.9 # 貪婪度 self.LR = 0.2 # 學習率 self.GAMMA = 0.9 # 獎勵遞減值 self.MAX_EPISODES = 13 # 最大回合數 self.FRESH_TIME = 0.3 # 移動每步的時間 def build_q_label(self,n_states,actions):''' Q values (行為值) 放在 q_table :param n_states: 狀態 :param actions: 行為 :return: table ''' table = pd.DataFrame(np.zeros((n_states, len(actions))), # q_table 全 0 初始 columns=actions,) # columns 對應的是行為名稱)# print('table\n', table)return table# 某個state地點,選擇行為 def choose_action(self,state, q_table):''' 智能體選擇動作:嚴格意義上講,智能體在前期探索階段需要把貪婪值設低些,隨著時間的增長貪婪值增加。 本例子:固定成 EPSILON = 0.9, 90% 的時間是選擇最優策略, 10% 的時間來探索. :param state: 狀態 :param q_table: 行為表 :return: action_name 行為名字 ''' state_actions = q_table.iloc[state, :] # 選出這個 state 的所有 action 值if (np.random.uniform() > self.EPSILON) or (state_actions.all() == 0): # 非貪婪 or 或者這個 state 還沒有探索過 action_name = np.random.choice(self.ACTIONS)else: action_name = state_actions.idxmax() # 貪婪模式return action_name def get_env_feedback(self,S,A):''' 環境也要給我們的行為一個反饋, 反饋出下個 state (S_) 和 在上個 state (S) 做出 action (A) 所得到的 reward (R) 本例子:O一定到T得到獎勵R = 1,其他都是R=0.01 :param S:state :param A: action :return: R : 獎勵 '''# This is how agent will interact with the environmentif A == 'right': # move rightif S == self.N_STATES - 2: # terminate S_ = 'terminal' R = 1else: S_ = S + 1 R = 0.01 # 越向右獎勵就獲得else: # move left R = 0if S == 0: S_ = S # reach the wall R = 0 # 撞牆獎勵設置為0else: S_ = S - 1 R = -0.01 # 向左 獎勵倒扣return S_, R def update_env(self,S, episode, step_counter):''' 環境更新 :param S: state :param episode: 回合數 :param step_counter: 步驟數 :return: '''# This is how environment be updated env_list = ['-']*(self.N_STATES-1) + ['T'] # '----T' our environmentif S == 'terminal': interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)print('\r{}'.format(interaction), end='') time.sleep(2)print('\r ', end='')else: env_list[S] = 'o' interaction = ''.join(env_list)print('\r{}'.format(interaction), end='') time.sleep(self.FRESH_TIME) def qlearing(self):''' 主函數:循環 :return: ''' q_table = self.build_q_label(self.N_STATES,self.ACTIONS) # 初始化q_tableprint('q_table:\n',q_table)for episode in range(self.MAX_EPISODES): # 回合 step_counter = 0 S = 0 # 回合初始位置 is_terminated = False # 是否回合結束 self.update_env(S, episode, step_counter) # 環境更新while not is_terminated: A = self.choose_action(S, q_table) # 選行為 S_, R = self.get_env_feedback(S, A) # 實施行為並得到環境的反饋print('\n S',S,'\n A',A) q_predict = q_table.loc[S, A] # 估算的(狀態-行為)值if S_ != 'terminal': q_target = R + self.GAMMA * q_table.iloc[S_, :].max() # 實際的(狀態-行為)值 (回合沒結束)else: q_target = R # 實際的(狀態-行為)值 (回合結束) is_terminated = True # terminate this episode q_table.loc[S, A] += self.LR * (q_target - q_predict) # q_table 更新 S = S_ # 探索者移動到下一個 state self.update_env(S, episode, step_counter + 1) # 環境更新 step_counter += 1return q_tableif __name__ == "__main__": new = QL() q_table = new.qlearing()print('\r\nQ-table:\n')print(q_table)Q-learning 算法更新
# -*- coding:utf-8 -*-# /usr/bin/python'''---- File Name : main Description : AIM: Functions: 1. 2. Envs : python == pip install -i https://pypi.douban.com/simple Author : errol Date : 2020/5/17 22:06 CodeStyle : 規範,簡潔,易懂,可閱讀,可維護,可移植!---- Change Activity: 2020/5/17 : 新建----'''from maze_env import Mazefrom RL_brain import QLearningTabledef update():for episode in range(100):# initial observation observation = env.reset()while True:# fresh env env.render()# RL choose action based on observation action = RL.choose_action(str(observation))# RL take action and get next observation and reward observation_, reward, done = env.step(action)# RL learn from this transition RL.learn(str(observation), action, reward, str(observation_))# swap observation observation = observation_# break while loop when end of this episodeifdone:break# end of gameprint('game over') env.destroy()if __name__ == "__main__": env = Maze() RL = QLearningTable(actions=list(range(env.n_actions))) env.after(100, update) env.mainloop()Q-learning 思維決策
# -*- coding:utf-8 -*-# /usr/bin/python'''---- File Name : RL_brain Description : AIM: Functions: 1. 大腦更新 2. Envs : python == pip install -i https://pypi.douban.com/simple Author : errol Date : 2020/5/17 22:03 CodeStyle : 規範,簡潔,易懂,可閱讀,可維護,可移植!---- Change Activity: 2020/5/17 : 新建----'''import numpy as npimport pandas as pdclass QLearningTable: def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9): self.actions = actions # a list self.lr = learning_rate self.gamma = reward_decay self.epsilon = e_greedy self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64) def choose_action(self, observation): self.check_state_exist(observation)# action selectionif np.random.uniform() < self.epsilon:# choose best action state_action = self.q_table.loc[observation, :]# some actions may have the same value, randomly choose on in these actions action = np.random.choice(state_action[state_action == np.max(state_action)].index)else:# choose random action action = np.random.choice(self.actions)return action def learn(self, s, a, r, s_): self.check_state_exist(s_) q_predict = self.q_table.loc[s, a]if s_ != 'terminal': q_target = r + self.gamma * self.q_table.loc[s_, :].max() # next state is not terminalelse: q_target = r # next state is terminal self.q_table.loc[s, a] += self.lr * (q_target - q_predict) # update def check_state_exist(self, state):if state not in self.q_table.index:# append new state to q table self.q_table = self.q_table.append( pd.Series( [0]*len(self.actions), index=self.q_table.columns, name=state, ) )Sarsa
與Q-Learning的不同:離線學習,Sarsa:是實施每個估計,在線學習,』保命為主『
sarsa 思維決策
Sarsa(lambda)
回合更新lambda 是腳步衰減值, 都是一個在 0 和 1 之間的數,認為距離獎勵越遠的步驟越不重要。如果 lambda = 0, Sarsa-lambda 就是 Sarsa, 只更新獲取到 reward 前經歷的最後一步.如果 lambda = 1, Sarsa-lambda 更新的是 獲取到 reward 前所有經歷的步.DQN
Deep Q Network 簡稱為 DQN. Google Deep mind 團隊就是靠著這 DQN 使計算機玩電動玩得比我們還厲害Q learning 是一種 off-policy 離線學習法, 它能學習當前經歷著的, 也能學習過去經歷過的, 甚至是學習別人的經歷. 所以每次 DQN 更新的時候, 我們都可以隨機抽取一些之前的經歷進行學習.Fixed Q-targets 也是一種打亂相關性的機理。DQN 算法更新
Q learning 主框架上加了些裝飾.這些裝飾包括:記憶庫 (用於重複學習)神經網絡計算 Q 值暫時凍結 q_target 參數 (切斷相關性)DQN 神經網絡 (Tensorflow)
OpenAI gym 環境庫
python --versionpython=2.7 $ pip install gympython=3.5 $ pip install gymos# MacOS:$ brew install cmake boost boost-python sdl2 swig wget# Ubuntu 14.04:$ apt-get install -y python-numpy python-dev cmake zlib1g-dev libjpeg-dev xvfb libav-tools xorg-dev python-opengl libboost-all-dev libsdl2-dev swigPrioritized Experience Replay (DQN)
使用 Prioritized replay, 就會重視這種少量的, 但值得學習的樣本.Dueling DQN
它將每個動作的 Q 拆分成了 state 的 Value 加上 每個動作的 Advantage.