AI相关概念原理|如何让电脑学会自己玩游戏

如何让电脑学会自己玩游戏 所用技术: 强化学习 -> Q_learning 可以解决问题的示例:

  1. 在计算机只知道它的动作只有上下左右复制粘贴这六个动作的情况下 学会如何将上一行的文字复制到输出框
  2. 走一维, 二维或三维迷宫, 或者在有陷阱,有奖励的情况下. 获得最大收益或减少成本.
  3. 让计算机玩赌博游戏. 比如猜轮盘转出来的数字,猜对有奖励, 或者选择离开赌桌. 最长期的收益则是计算机选择离开赌桌.
该技术可玩游戏类型的限制: 可玩: 状态有限, 动作有限. (其中一个 精确的解.)
【AI相关概念原理|如何让电脑学会自己玩游戏】不可玩: 状态无限 或 动作无限. (其中一个 近似的解.)
走迷宫实例参考:走迷宫 游戏名: 寻宝者找宝藏 游戏环境说明: —O————T O 代表寻宝者的所在游戏中的位置
代表路径
T 代表宝藏的位置
O 可执行的动作只有
智能体只知道: 它找到宝藏就是最大化收益
它会的动作只有
它可随机出现在整个地图上的任何位置, 并试图找到宝藏
class Game_env(): def get_env_feedback(self, state, action): ... # 输入给环境当前的状态 和 需要执行的动作 # 返回下一个状态 和 下一个状态给的奖励 # 例如输入: ---O-T状态为:3动作为: right # 那么输出: ----OT状态为:4奖励为: 0def update_env(self, state, round, step_counter): ... # 根据状态更新当前环境,并可视化. # 输入为 state=3 # 输出为 可视化当前状态 终端显示: ---O-TTreasure 宝物,财富.等意思... # round 和 step_counter 用于记录和显示 当前的回合数,和完成一回合游戏所使用的步数.可不使用class Play_game(): def build_q_table(self, n_states, actions): ... # 创建q表 用于指导智能体如何玩游戏 # stateleftright #00.00.0 #10.00.0 #20.00.0 #30.00.0 #40.00.0 # 这里可以写成活的q表 判断如果没有此状态则添加. # 这里可以扩展到 二维的迷宫游戏或其它 状态有限 动作有限 的游戏 # stateleftrightdownup #00.00.00.00.0 #10.00.00.00.0 #20.00.00.00.0 #30.00.00.00.0 #40.00.00.00.0def choose_action(self, state): ... # 根据贪婪率选择随机动作或最大收益动作(电脑自动玩游戏) # 也可玩家手动指导智能体玩游戏只需将选择动作的代码改为键盘输入即可(人工指导智能体玩游戏) # 输入当前状态 例如: ---O-T状态为: 3 # 返回输出动作 例如: left 或者 rightclass Train(): def learning_round(self): ... # 设置每个回合配置 如下: # 1. 初始状态 置零或随机 # 2. 游戏状态 置为未完成 # 3. 游戏进行步数 置零 # 4. 游戏环境初始化 # 开始学习q表def learning_steps(self, state, is_terminated, round, step_count): ... # 整个游戏初始化后就可以开始玩了. # 无限死循环 或者 玩多少步后强制退出都行 # 1. 选择一个动作 -> 得到一个动作 # 2. 获得环境的反馈 -> 得到 下一个状态 和 奖励 # 3. 得到q真实的值 -> 当前的状态 和 选择的动作 确定q真实的值 # 4. 得到q估计的值 -> 下一步动作的奖励 + 远见 * 下一个状态的所有动作值中的最大值 # 5. 更新q表的值 -> 学习率 * (q估计 - q现实) # 6. 更新当前的状态 -> 当前状态为选择动作后的下一个状态 # 7. 更新当前的环境 # 8. 当前回合步数统计, 可省略. # 进入下一个回合, 重置游戏各项参数.重新开始玩.# stateleftright #00.00.0 #10.00.0 #20.00.0 #30.00.0 #40.00.0

更新Q表:
更新后的值 = 更新前的值 + 学习率 * (奖励 + 远见 * q估计值 - q现实值) Q ( s t , a t ) ← Q ( s t , a t ) + α ? ( r t + γ ? m a x Q ( s t + 1 , a ) ? Q ( s t , a t ) ) Q\left (s_{t}, a_{t}\right) \leftarrow Q\left (s_{t}, a_{t} \right)+\alpha \cdot \left(r_{t} +\gamma \cdot maxQ \left (s_{t+1},a \right)-Q \left (s_{t}, a_{t} \right) \right) Q(st?,at?)←Q(st?,at?)+α?(rt?+γ?maxQ(st+1?,a)?Q(st?,at?))
所有代码
import time import pandas as pd import numpy as npclass Game_env(): def __init__(self, N_STATES=5, FRESH_TIME=0.3): self.N_STATES = N_STATES# the length of the 1 dimensional world状态长度 self.FRESH_TIME = FRESH_TIME# fresh time for one movedef get_env_feedback(self, state, action): if action == 'right':# move right if state == self.N_STATES - 1:# terminate 0 start next_state = 'terminal' reward = 1 else: next_state = state + 1 reward = 0 else:# move left reward = 0 if state == 0: next_state = state# reach the wall else: next_state = state - 1 return next_state, rewarddef update_env(self, state, round, step_counter): env_list = ['-']*(self.N_STATES) + ['T']# '-----T' our environment if state == 'terminal': interaction = 'Round: %sTotal_move_steps: %s' % (round+1, step_counter) print('\r{}'.format(interaction), end='') time.sleep(3) print('\r', end='') else: env_list[state] = 'o' interaction = ''.join(env_list) print('\r{}'.format(interaction), end='') time.sleep(self.FRESH_TIME)class Play_game(): def __init__(self, N_STATES=5): self.N_STATES = N_STATES# the length of the 1 dimensional world self.ACTIONS = ['left', 'right']# available actions self.EPSILON = 0.9# greedy 有多大概率选择最优动作 self.q_table = self.build_q_table(self.N_STATES, self.ACTIONS)def build_q_table(self, n_states, actions): table = pd.DataFrame(np.zeros((n_states, len(actions))), columns=actions, ) print("\n init q_table: \n", table) return tabledef choose_action(self, state): state_actions = self.q_table.iloc[state, :] if (np.random.uniform() > self.EPSILON) or ((state_actions == 0).all()): action_name = np.random.choice(self.ACTIONS) else:# act greedy action_name = state_actions.idxmax() return action_nameclass Train(): def __init__(self, learn_round=13): N_STATES = 5 self.game_env = Game_env(N_STATES) self.play = Play_game(N_STATES) self.learn_round = learn_round self.ALPHA = 0.1# learning rate self.GAMMA = 0.9# discount factor # 远见def learning_round(self): for round in range(self.learn_round): state = 0 is_terminated = False step_count = 0 self.game_env.update_env(state, round, step_count) self.learning_steps(state, is_terminated, round, step_count) # print("\n" + "=" * 20 + "\n q_table round: {}\n".format(round + 1), self.play.q_table) return self.play.q_tabledef learning_steps(self, state, is_terminated, round, step_count): while not is_terminated: action = self.play.choose_action(state) next_state, reward = self.game_env.get_env_feedback(state, action) q_predict = self.play.q_table.loc[state, action] if next_state != 'terminal': q_target = reward + self.GAMMA * self.play.q_table.iloc[next_state, :].max() else: q_target = reward# next state is terminal is_terminated = True# terminate this episodeself.play.q_table.loc[state, action] += self.ALPHA * (q_target - q_predict)# update state = next_state# move to next stateself.game_env.update_env(state, round, step_count + 1) step_count += 1if __name__ == '__main__': pass # # env show # game_env = Game_env() # action = "left" # next_state, reward = game_env.get_env_feedback(state=4, action=action) # print("下一个状态:{}\n下一个状态所给予的奖励:{}".format(next_state, reward)) # game_env.update_env(next_state, round=1, step_counter=10)# # play show # play = Play_game() # action = play.choose_action(state=4) # print("选择的动作名字:", action)# # learning # agent = Train() # learn_result = agent.learning_round() # print("\n 最后保存的q_table", learn_result)

    推荐阅读