DeepChem教程27: 使用强化学习来玩Pong

本教程我们展示一下用强化学习来训练agentPong。这个任务并不与化学直接相关,但是视频游戏可以展示强化学习技术。

安装

你应该用pip install 'gym[atari]'安装gym。(我们需要修饰器因为我们将使用atari游戏)。

In [ ]:

!curl -Lo conda_installer.py https://raw.githubusercontent.com/deepchem/deepchem/master/scripts/colab_install.py

import conda_installer

conda_installer.install()

!/root/miniconda/bin/conda info -e

In [ ]:

!pip install --pre deepchem

import deepchem

deepchem.__version__

In [ ]:

!pip install 'gym[atari]'

强化学习

强化学习调用agent与环境交互。这种情况下,环境是视频游戏,agent是玩家。通过不断试错,agent学习到了执行一些任务(赢得游戏)的策略。随着游戏的进行,它接收环境反馈的rewards,告诉它做得好坏。这种情况下,如果得分了就是接收了正的reward,如     果另一个玩家得分了它就得了负的reward

第一步是创建执行环境的任务。幸运的是,OpenAI Gym已经提供了Pong的实施(以及其它的强化学习任务) DeepChem GymEnvironment类提供了一个容易的方法来从OpenAI Gym使用环境。我们只需直接使用它,但是这个例子中我们子类化它并预处理屏幕图像以使学习更容易。

In [ ]:

import deepchem as dc

import numpy as np

 

class PongEnv(dc.rl.GymEnvironment):

  def __init__(self):

    super(PongEnv, self).__init__('Pong-v0')

    self._state_shape = (80, 80)

 

  @property

  def state(self):

    # Crop everything outside the play area, reduce the image size,

    # and convert it to black and white.

    cropped = np.array(self._state)[34:194, :, :]

    reduced = cropped[0:-1:2, 0:-1:2]

    grayscale = np.sum(reduced, axis=2)

    bw = np.zeros(grayscale.shape)

    bw[grayscale != 233] = 1

    return bw

 

  def __deepcopy__(self, memo):

    return PongEnv()

 

env = PongEnv()

接下来我们创建模型来执行策略。这个模型接收当前的环境状态(此时屏幕显示的的像素)作为它的输入。给定输入,它会决定执行哪个行动。Pong中有三种可能的行动:向上移动桨,向下移动,或保持位置。策略模型为这些行动产生概率分布。它也产生value输出,这是当前状态好坏的解释。这实证明是有效学习的重点。

由二个处理图像的卷积层开始。接着是全链接层来提供许多游戏逻辑能力。我们也加一个小的Gated Recurrent Unit (GRU)。这会给游戏增加一点记忆,它可以追踪球向哪移动。仅从屏幕图像,你无法告知球向左还是向右移,所以有记忆很重要。

我们联接全链接屋和GRU输出,用来作为最后两层作为网格输出的输入。一个计算行动的概率,另一个计算状态值函数。

我们也为GRU的初始状态提供输入,最后返回最终的状态。这需要学习算法。

In [ ]:

import tensorflow as tf

from tensorflow.keras.layers import Input, Concatenate, Conv2D, Dense, Flatten, GRU, Reshape

 

class PongPolicy(dc.rl.Policy):

    def __init__(self):

        super(PongPolicy, self).__init__(['action_prob', 'value', 'rnn_state'], [np.zeros(16)])

 

    def create_model(self, **kwargs):

        state = Input(shape=(80, 80))

        rnn_state = Input(shape=(16,))

        conv1 = Conv2D(16, kernel_size=8, strides=4, activation=tf.nn.relu)(Reshape((80, 80, 1))(state))

        conv2 = Conv2D(32, kernel_size=4, strides=2, activation=tf.nn.relu)(conv1)

        dense = Dense(256, activation=tf.nn.relu)(Flatten()(conv2))

        gru, rnn_final_state = GRU(16, return_state=True, return_sequences=True, time_major=True)(

            Reshape((-1, 256))(dense), initial_state=rnn_state)

        concat = Concatenate()([dense, Reshape((16,))(gru)])

        action_prob = Dense(env.n_actions, activation=tf.nn.softmax)(concat)

        value = Dense(1)(concat)

        return tf.keras.Model(inputs=[state, rnn_state], outputs=[action_prob, value, rnn_final_state])

 

policy = PongPolicy()

我们需要用Advantage Actor Critic (A2C)算法来优化策略。此处我们有很多超参数需要指明,但是大部分采用默认值也能工作得很好。我们唯一需要指定的是学习速率。

In [ ]:

from deepchem.models.optimizers import Adam

a2c = dc.rl.A2C(env, policy, model_dir='model', optimizer=Adam(learning_rate=0.0002))

尽量优化到你可以接受的时间。一百成步以后你为看到学习信号。通过3百万步以后它偶尔会击败AI游戏。七百万步以后它就会几乎赢得所有游戏。在笔记本电脑上,每一百成步大概需要20分钟。

In [ ]:

# Change this to train as many steps as you have patience for.

a2c.fit(1000)

我们来看它如何玩,并看一下它的表现。

In [ ]:

# This code doesn't work well on Colab

env.reset()

while not env.terminated:

    env.env.render()

    env.step(a2c.select_action(env.state))

 

下载全文请到www.data-vision.net,技术联系电话13712566524

猜你喜欢

转载自blog.csdn.net/lishaoan77/article/details/114376771