[PYTHON] Renforcer l'apprentissage 12 Guide de démarrage rapide de ChainerRL Version Windows

Le guide de démarrage rapide de ChainaerRL est dommage pour Windows, c'est donc une version Windows sans le consentement de l'original. Anaconda a des explications à divers endroits, veuillez donc vous y référer. Avec anaconda3, continuez en supposant python3.7.

Guide de démarrage rapide de ChainerRL

Ce cahier est un guide de démarrage rapide pour les utilisateurs qui souhaitent essayer ChainerRL pour la première fois. Exécutez la commande suivante pour installer ChainerRL.

# Install Chainer, ChainerRL and CuPy!
!conda install cupy chainer
!pip -q install chainerrl
!pip -q install gym
!pip -q install pyglet
!pip -q install pyopengl
!pip -q install pyvirtualdisplay
!pip -q install JSAnimation
!pip -q install matplotlib
!pip -q install jupyter
!conda install -c conda-forge ffmpeg

Tout d'abord, vous devez importer les modules requis. Le nom du module pour ChainerRL est chainerrl. Importons également gym et numpy pour une utilisation ultérieure.

import chainer
import chainer.functions as F
import chainer.links as L
import chainerrl
import gym
import numpy as np

ChainerRL peut être utilisé pour n'importe quel problème si «l'environnement» est modélisé. OpenAI Gym fournit différents types d'environnements d'analyse comparative et définit une interface commune entre eux. ChainerRL utilise un sous-ensemble de cette interface. Plus précisément, l'environnement doit définir son espace d'observation et son espace d'action et disposer d'au moins deux méthodes, reset et step.

env.reset réinitialise l'environnement à son état initial et retourne l'état initial (observation). env.step exécute l'action donnée, passe à l'état suivant et renvoie quatre valeurs: --observation --scalar récompense --a Boolean indiquant si l'état actuel est l'état fini Valeur-Informations supplémentaires env.render rend l'état actuel. Essayons maintenant CartPole-v0, un problème de contrôle classique. Ci-dessous, vous pouvez voir que l'espace d'états est composé de quatre nombres réels et que son espace de travail est composé de deux actions discrètes.

env = gym.make('CartPole-v0')
print('observation space:', env.observation_space)
print('action space:', env.action_space)

obs = env.reset()
#env.render()
print('initial observation:', obs)

action = env.action_space.sample()
obs, r, done, info = env.step(action)
print('next observation:', obs)
print('reward:', r)
print('done:', done)
print('info:', info)
WARN: gym.spaces.Box autodetected dtype as <class 'numpy.float32'>. Please provide explicit dtype.
observation space: Box(4,)
action space: Discrete(2)
initial observation: [-0.04055678 -0.00197163  0.02364212  0.03487198]
next observation: [-0.04059621 -0.1974245   0.02433956  0.33491948]
reward: 1.0
done: False
info: {}

Vous avez maintenant défini votre environnement. Ensuite, nous devons définir un agent qui apprend par l'interaction avec l'environnement.

ChainerRL propose une variété d'agents, chacun mettant en œuvre un algorithme d'apprentissage par renforcement profond.

Pour utiliser DQN (Deep Q-Network), vous devez définir une fonction Q qui prend un état et renvoie le retour futur attendu que chaque action de l'agent peut prendre. Dans ChainerRL, la fonction Q peut être définie comme chainer.Link comme suit. Notez que la sortie est encapsulée par chainerrl.action_value.DiscreteActionValue, qui implémente chainerrl.action_value.ActionValue. ChainerRL peut gérer une telle fonction Q à action discrète et NAF (Normalized Advantage Functions) de la même manière en enveloppant la sortie de la fonction Q.

class QFunction(chainer.Chain):

    def __init__(self, obs_size, n_actions, n_hidden_channels=50):
        super().__init__()
        with self.init_scope():
            self.l0 = L.Linear(obs_size, n_hidden_channels)
            self.l1 = L.Linear(n_hidden_channels, n_hidden_channels)
            self.l2 = L.Linear(n_hidden_channels, n_actions)

    def __call__(self, x, test=False):
        """
        Args:
            x (ndarray or chainer.Variable): An observation
            test (bool): a flag indicating whether it is in test mode
        """
        h = F.tanh(self.l0(x))
        h = F.tanh(self.l1(h))
        return chainerrl.action_value.DiscreteActionValue(self.l2(h))

obs_size = env.observation_space.shape[0]
n_actions = env.action_space.n
q_func = QFunction(obs_size, n_actions)

Si vous souhaitez utiliser CUDA pour des calculs comme Chainer, appelez to_gpu.

Si vous souhaitez utiliser Colaboratory, vous devez changer le type d'exécution en GPU. ..

q_func.to_gpu(0)
<__main__.QFunction at 0x7f0bc217beb8>

Vous pouvez également utiliser les fonctions Q prédéfinies de ChainerRL.

_q_func = chainerrl.q_functions.FCStateQFunctionWithDiscreteAction(
    obs_size, n_actions,
    n_hidden_layers=2, n_hidden_channels=50)

Comme Chainer, chainer.Optimizer est utilisé pour mettre à jour le modèle.

# Use Adam to optimize q_func. eps=1e-2 is for stability.
optimizer = chainer.optimizers.Adam(eps=1e-2)
optimizer.setup(q_func)

La fonction Q et sa fonction d'optimisation sont utilisées par les agents de DQN. Vous devez spécifier plus de paramètres et de paramètres pour créer un agent pour DQN.

# Set the discount factor that discounts future rewards.
gamma = 0.95

# Use epsilon-greedy for exploration
explorer = chainerrl.explorers.ConstantEpsilonGreedy(
    epsilon=0.3, random_action_func=env.action_space.sample)

# DQN uses Experience Replay.
# Specify a replay buffer and its capacity.
replay_buffer = chainerrl.replay_buffer.ReplayBuffer(capacity=10 ** 6)

# Since observations from CartPole-v0 is numpy.float64 while
# Chainer only accepts numpy.float32 by default, specify
# a converter as a feature extractor function phi.
phi = lambda x: x.astype(np.float32, copy=False)

# Now create an agent that will interact with the environment.
agent = chainerrl.agents.DoubleDQN(
    q_func, optimizer, replay_buffer, gamma, explorer,
    replay_start_size=500, update_interval=1,
    target_update_interval=100, phi=phi)

Maintenant, l'agent et l'environnement sont prêts. Commençons par renforcer l'apprentissage!

Lors de l'apprentissage, utilisez agent.act_and_train pour sélectionner des actions exploratoires. Vous devez appeler agent.stop_episode_and_train une fois l'épisode terminé. Vous pouvez utiliser agent.get_statistics pour obtenir des statistiques d'entraînement pour les agents.

n_episodes = 200
max_episode_len = 200
for i in range(1, n_episodes + 1):
    obs = env.reset()
    reward = 0
    done = False
    R = 0  # return (sum of rewards)
    t = 0  # time step
    while not done and t < max_episode_len:
        # Uncomment to watch the behaviour
        # env.render()
        action = agent.act_and_train(obs, reward)
        obs, reward, done, _ = env.step(action)
        R += reward
        t += 1
    if i % 10 == 0:
        print('episode:', i,
              'R:', R,
              'statistics:', agent.get_statistics())
    agent.stop_episode_and_train(obs, reward, done)
print('Finished.')
episode: 10 R: 37.0 statistics: [('average_q', 1.2150215711003933), ('average_loss', 0.05015367301912823)]
episode: 20 R: 44.0 statistics: [('average_q', 3.7857904640201947), ('average_loss', 0.09890545599011519)]
episode: 30 R: 97.0 statistics: [('average_q', 7.7720408907953145), ('average_loss', 0.12504807923600555)]
episode: 40 R: 56.0 statistics: [('average_q', 10.963194695758215), ('average_loss', 0.15639676991049656)]
episode: 50 R: 177.0 statistics: [('average_q', 14.237965547239822), ('average_loss', 0.23526638038745168)]
episode: 60 R: 145.0 statistics: [('average_q', 17.240442032833762), ('average_loss', 0.16206694621384216)]
episode: 70 R: 175.0 statistics: [('average_q', 18.511116289009692), ('average_loss', 0.18787805607905012)]
episode: 80 R: 57.0 statistics: [('average_q', 18.951395985384725), ('average_loss', 0.149411012387425)]
episode: 90 R: 200.0 statistics: [('average_q', 19.599694542558165), ('average_loss', 0.16107124308010012)]
episode: 100 R: 200.0 statistics: [('average_q', 19.927458098228968), ('average_loss', 0.1474102671167888)]
episode: 110 R: 200.0 statistics: [('average_q', 19.943080568511867), ('average_loss', 0.12303519377444547)]
episode: 120 R: 152.0 statistics: [('average_q', 19.81996694327306), ('average_loss', 0.12570420169091834)]
episode: 130 R: 196.0 statistics: [('average_q', 19.961466224568177), ('average_loss', 0.17747677703107395)]
episode: 140 R: 194.0 statistics: [('average_q', 20.05166109574271), ('average_loss', 0.1334155925948816)]
episode: 150 R: 200.0 statistics: [('average_q', 19.982061292121358), ('average_loss', 0.12589899261907)]
episode: 160 R: 175.0 statistics: [('average_q', 20.060457421033803), ('average_loss', 0.13909796300744334)]
episode: 170 R: 200.0 statistics: [('average_q', 20.03359962493644), ('average_loss', 0.12457978502375021)]
episode: 180 R: 200.0 statistics: [('average_q', 20.023962037264738), ('average_loss', 0.10855797175237188)]
episode: 190 R: 200.0 statistics: [('average_q', 20.023348743333067), ('average_loss', 0.11714457311489457)]
episode: 200 R: 200.0 statistics: [('average_q', 19.924879051722634), ('average_loss', 0.08032495725586702)]
Finished.

Ceci termine la formation des agents. Dans quelle mesure cet agent apprend-il? Il peut être testé en utilisant agent.act et agent.stop_episode. Les explorations telles que epsilon-greedy ne sont pas utilisées ici.

Afin de vérifier le résultat de l'exécution sur Notebook, il est affiché à l'aide de la fonction d'animation de matplotlib.

from JSAnimation.IPython_display import display_animation
from matplotlib import animation
import matplotlib.pyplot as plt
%matplotlib inline
frames = []
for i in range(3):
    obs = env.reset()
    done = False
    R = 0
    t = 0
    while not done and t < 200:
        frames.append(env.render(mode = 'rgb_array'))
        action = agent.act(obs)
        obs, r, done, _ = env.step(action)
        R += r
        t += 1
    print('test episode:', i, 'R:', R)
    agent.stop_episode()
env.render()

from IPython.display import HTML
plt.figure(figsize=(frames[0].shape[1]/72.0, frames[0].shape[0]/72.0),dpi=72)
patch = plt.imshow(frames[0])
plt.axis('off') 
def animate(i):
    patch.set_data(frames[i])
anim = animation.FuncAnimation(plt.gcf(), animate, frames=len(frames),interval=50)
anim.save('movie_cartpole.mp4')
HTML(anim.to_jshtml())
test episode: 0 R: 200.0
test episode: 1 R: 200.0
test episode: 2 R: 200.0

Si les scores et résultats des tests ci-dessus sont suffisants, le reste du travail consiste à enregistrer l'agent pour une réutilisation. Tout ce que vous avez à faire est d'appeler agent.save pour enregistrer l'agent, puis d'appeler agent.load pour charger l'agent enregistré.

# Save an agent to the 'agent' directory
agent.save('agent')

# Uncomment to load an agent from the 'agent' directory
# agent.load('agent')

Avec ce qui précède, le renforcement de l'apprentissage a été appris et testé.

Cependant, écrire un code comme celui-ci chaque fois que vous implémentez un apprentissage amélioré peut être fastidieux. Par conséquent, ChainerRL a des fonctions utilitaires qui font ces choses.

# Set up the logger to print info messages for understandability.
import logging
import sys
gym.undo_logger_setup()  # Turn off gym's default logger settings
logging.basicConfig(level=logging.INFO, stream=sys.stdout, format='')

chainerrl.experiments.train_agent_with_evaluation(
    agent, env,
    steps=20000,           # Train the agent for 2000 steps
    eval_n_steps=None,       # 10 episodes are sampled for each evaluation
    eval_n_episodes=10,       # 10 episodes are sampled for each evaluation
    eval_max_episode_len=200,  # Maximum length of each episodes
    eval_interval=1000,   # Evaluate the agent after every 1000 steps
    outdir='result')      # Save everything to 'result' directory

C'est tout pour le guide de démarrage rapide de ChainerRL. Pour en savoir plus sur ChainerRL, jetez un œil au répertoire des exemples et lisez et exécutez les exemples. Merci beaucoup!

Le fichier chainerrl à remodeler est userfolder.conda\envs\chainer\Lib\site-packages\chainerrl\experiments\train_agent.py était. chainerui a bien fonctionné.

Je l'ai mentionné ici. (Presque une copie complète.) https://book.mynavi.jp/manatee/detail/id=88961

J'espère que les utilisateurs de Windows pourront également utiliser chainerRL.

Recommended Posts

Renforcer l'apprentissage 12 Guide de démarrage rapide de ChainerRL Version Windows
Renforcer l'apprentissage 28 collaboratif + OpenAI + chainerRL
Renforcer l'apprentissage 19 Colaboratory + Mountain_car + ChainerRL
Renforcement de l'apprentissage 2 Installation de chainerrl
Renforcer l'apprentissage 20 Colaboratoire + Pendule + ChainerRL
Apprentissage par renforcement 9 Remodelage magique ChainerRL
Renforcer l'apprentissage 21 Colaboratoire + Pendule + ChainerRL + A2C
Renforcer l'apprentissage 13 Essayez Mountain_car avec ChainerRL.
Renforcer l'apprentissage 22 Colaboratory + CartPole + ChainerRL + A3C
Renforcer l'apprentissage 24 Colaboratory + CartPole + ChainerRL + ACER
Renforcer l'apprentissage 14 Pendulum a été réalisé à ChainerRL.
Renforcer l'apprentissage 11 Essayez OpenAI acrobot avec ChainerRL.
Apprentissage par renforcement 27 chainerRL (+ chokozainerRL)
Commencer l'apprentissage en profondeur
Démarrage rapide de Python
Apprentissage par renforcement futur_2
Apprentissage par renforcement futur_1
Apprentissage par renforcement 37 Démarrez automatiquement avec l'enrubanneuse Atari