Google是如何教会机器玩Atari游戏的

本文介绍了Google如何利用深度强化学习让机器自学玩Atari 2600游戏,打破人类纪录。算法通过游戏屏幕图像和得分作为输入,通过卷积神经网络和强化学习策略,逐渐学习最佳游戏策略。通过Q-learning和Temporal Difference方法,算法在没有监督的情况下自我学习和改进,最终达到高水平游戏表现。
摘要由CSDN通过智能技术生成


今年上半年(2015年2月),Google在Nature上发表了一篇论文:Human-level control through deep reinforcement learning。文章描述了如何让电脑自己学会打Atari 2600电子游戏。Atari 2600是80年代风靡美国的游戏机,总共包括49个独立的游戏,其中不乏我们熟悉的Breakout(打砖块),Galaxy Invaders(小蜜蜂)等经典游戏。Google算法的输入只有游戏屏幕的图像和游戏的得分,在没有人为干预的情况下,电脑自己学会了游戏的玩法,而且在29个游戏中打破了人类玩家的记录。

Google到底是如何做到的呢?答案当然是深度学习了。

先来看看Google给出的神经网络架构。


网络的最左边是输入,右边是输出。游戏屏幕的图像(实际上是4幅连续的图像,可以理解为4个通道的图像)经过2个卷积层(论文中写的是3个),然后经过2个全连接层,最后映射到游戏手柄所有可能的动作。各层之间使用ReLU激活函数。

这个网络怎么看着这么眼熟?这和我们识别MNIST数字时用的卷积神经网络是一样一样的

可是转念又一想,还是不对。我们识别MNIST数字的时候,是Supervised Learning(监督学习)。每个图像对应的输出是事先知道的。可是在游戏中并不是这样,游戏环境给出的只是得分。算法需要根据得分的变化来推断之前做出的动作是不是有利的。

这就像训练宠物一样。当宠物做出了指定动作之后,我们给它一些食物作为奖励,使它更加坚信只要做出那个动作就会得到奖励。这种训练叫做Reinforcement Learning(强化学习)。

强化学习并没有指定的输出,环境只对算法做出的动作给出相应的奖励,由算法来主动发现什么时间做出什么动作是合适的。强化学习的难处在于,奖励往往是有延时的。比如在一个飞机游戏中,玩家指挥自己的飞机在合适的时机发射子弹,相应的奖励要等到子弹击中敌机才会给出。从发射子弹到击中敌机之间有一个时间延迟。那么算法如何跨越这个时间延迟,把击中敌机所得到的奖励映射到之前发射子弹的这个动作上呢?

要解释这个问题,我们需要首先来谈一下强化学习是怎么一回事。

Reinforcement Learning(强化学习)

先借用一下维基百科的描述:

强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益。其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予的奖励或惩罚的刺激下,逐步形成对刺激的预期,产生能获得最大利益的习惯性行为。


在强化学习的世界里,我们的算法(或者说人工智能)被称为Agent,它与环境发生交互。Agent从环境中获取状态(state),并决定自己要做出的动作(action)。环境会根据其自身的逻辑给Agent予以奖励(reward)。这个奖励有正向和反向之分。比如动物生活在大自然中,吃到食物即是一个正向的奖励,而挨饿甚至失去生命就是反向的奖励。动物们靠着自己的本能趋利避害,增大自己得到正向奖励的机会。如果反过来说,就是避免得到反向的奖励,而挨饿什么的最终会导致死亡。所以动物生存的唯一目的其实就是避免死亡。

在电子游戏世界(特指Atari 2600这一类的简单游戏。不包括推理解密类的游戏)中:

  • 环境指的是游戏本身,包括其内部的各种逻辑;
  • Agent指的是操作游戏的玩家,当然也可以是指操作游戏的AI算法;
  • 状态就是指游戏在屏幕上展现的画面。游戏通过屏幕画面把状态信息传达给Agent。如果是棋类游戏,状态是离散的,状态的数量是有限的。但在动作类游戏(如打飞机)中,状态是画面中的每个物体(飞机,敌人,子弹等等)所处的位置和运动速度的组合。状态是连续的,而且数量几乎是无限的。
  • 动作是指手柄的按键组合,包括方向键和按钮的组合,当然也包括什么都不按(不做任何动作)。
  • 奖励是指游戏的得分,每击中一个敌人都可以得到一些得分的奖励。
  • 策略是Agent脑子里从状态到动作的映射。也就是说,每当Agent看到一个游戏画面(状态),就应该知道该如何操纵手柄(动作)。Reinforcement Learning算法的任务就是找到最佳的策略。策略的表示方法可以有很多。比如:
    1. 当状态的个数是有限的情况下,我们可以给每个状态指定一个最佳动作,以后只要看到某种状态
强化学习Atari游戏是一种基于深度强化学习算法的方法,其中使用了深度Q学习算法。这种方法通过将游戏界面作为输入,直接从游戏界面中学习,以实现对Atari游戏的学习和耍。 具体来说,深度Q学习算法使用了经验回放和目标网络的技术。经验回放是一种存储和重复使用过去的经验的方法,它可以帮助算法更好地学习和记忆。目标网络是一个用于计算目标Q值的网络,它的参数是固定的,以减少目标Q值的变化。 在实现强化学习Atari游戏的过程中,可以使用深度强化学习框架,如TensorFlow或PyTorch,来构建深度Q网络。该网络将游戏界面作为输入,并输出每个动作的Q值。然后,根据Q值选择最佳动作,并执行该动作。通过不断与环境交互,更新网络参数,以优化Q值的估计。 以下是一个示例代码,演示了如何使用深度Q学习算法Atari游戏中的Pong: ```python import gym import numpy as np import tensorflow as tf # 创建环境 env = gym.make('Pong-v0') # 定义深度Q网络 model = tf.keras.Sequential([ tf.keras.layers.Conv2D(32, (8, 8), strides=(4, 4), activation='relu', input_shape=(84, 84, 4)), tf.keras.layers.Conv2D(64, (4, 4), strides=(2,2), activation='relu'), tf.keras.layers.Conv2D(64, (3, 3), strides=(1, 1), activation='relu'), tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(env.action_space.n) ]) # 定义经验回放缓冲区 replay_buffer = [] # 定义训练参数 epsilon = 1.0 # 探索率 epsilon_decay = 0.99 # 探索率衰减率 epsilon_min = 0.01 # 最小探索率 gamma = 0.99 # 折扣因子 batch_size = 32 # 批量大小 # 定义优化器和损失函数 optimizer = tf.keras.optimizers.Adam(learning_rate=0.001) loss_fn = tf.keras.losses.MeanSquaredError() # 定义目标网络 target_model = tf.keras.models.clone_model(model) target_model.set_weights(model.get_weights()) # 定义训练函数 def train(): # 从经验回放缓冲区中随机采样一批数据 batch = np.random.choice(len(replay_buffer), size=batch_size, replace=False) states, actions, rewards, next_states, dones = zip(*[replay_buffer[i] for i in batch]) states = np.array(states) actions = np.array(actions) rewards = np.array(rewards) next_states = np.array(next_states) dones = np.array(dones) # 计算目标Q值 q_values_next = target_model.predict(next_states) targets = rewards + gamma * np.max(q_values_next, axis=1) * (1 - dones) # 计算当前Q值 with tf.GradientTape() as tape: q_values = model(states) q_values_actions = tf.reduce_sum(q_values * tf.one_hot(actions, env.action_space.n), axis=1) loss = loss_fn(targets, q_values_actions) # 更新网络参数 grads = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 开始训练 for episode in range(1000): state = env.reset() state = preprocess(state) # 预处理游戏界面 done = False total_reward = 0 while not done: # 选择动作 if np.random.rand() < epsilon: action = env.action_space.sample() # 随机动作 else: q_values = model.predict(np.expand_dims(state, axis=0)) action = np.argmax(q_values) # 执行动作 next_state, reward, done, _ = env.step(action) next_state = preprocess(next_state) # 预处理游戏界面 # 存储经验 replay_buffer.append((state, action, reward, next_state, done)) # 更新状态和总奖励 state = next_state total_reward += reward # 训练网络 if len(replay_buffer) >= batch_size: train() # 更新目标网络 if episode % 10 == 0: target_model.set_weights(model.get_weights()) # 衰减探索率 epsilon = max(epsilon * epsilon_decay, epsilon_min) # 打印结果 print('Episode: {}, Total Reward: {}'.format(episode, total_reward)) # 演示游戏 state = env.reset() state = preprocess(state) done = False total_reward = 0 while not done: q_values = model.predict(np.expand_dims(state, axis=0)) action = np.argmax(q_values) next_state, reward, done, _ = env.step(action) next_state = preprocess(next_state) state = next_state total_reward += reward env.render() print('Total Reward: {}'.format(total_reward)) env.close() ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值