J'ai changé un peu l'échantillon de QuickStart et déplacé CNN. La cible de l'apprentissage est le "Pong-v0" d'Atari. ChainerRL Quickstart Guide
Je fais référence à cet article. Essayez d'utiliser chainerRL
Je ne peux pas dire si j'apprends correctement en raison d'un manque de connaissances sur Linux, Python et l'apprentissage amélioré, mais j'ai confirmé que cela fonctionne. Veuillez nous donner des erreurs ou des conseils.
OS: ubuntu 16.04 python: 3.6.0 chainer: 1.21.0
Il y a deux changements principaux ci-dessous. Je l'ai utilisé pour les niveaux de gris et redimensionner l'écran de jeu.
train.py
import chainer
import chainer.functions as F
import chainer.links as L
import chainerrl
import gym
import numpy as np
import datetime
from skimage.color import rgb2gray
from skimage.transform import resize
Je n'ai pas changé ce domaine.
train.py
env = gym.make('Pong-v0')
obs = env.reset()
env.render()
Je ne sais pas comment le définir, alors j'utilise le modèle précédent de CNN tel quel.
train.py
class QFunction(chainer.Chain):
def __init__(self, n_history=1, n_action=6):
super().__init__(
l1=L.Convolution2D(n_history, 32, ksize=8, stride=4, nobias=False, wscale=np.sqrt(2)),
l2=L.Convolution2D(32, 64, ksize=3, stride=2, nobias=False, wscale=np.sqrt(2)),
l3=L.Convolution2D(64, 64, ksize=3, stride=1, nobias=False, wscale=np.sqrt(2)),
l4=L.Linear(3136, 512, wscale=np.sqrt(2)),
out=L.Linear(512, n_action, initialW=np.zeros((n_action, 512), dtype=np.float32))
)
def __call__(self, x, test=False):
s = chainer.Variable(x)
h1 = F.relu(self.l1(s))
h2 = F.relu(self.l2(h1))
h3 = F.relu(self.l3(h2))
h4 = F.relu(self.l4(h3))
h5 = self.out(h4)
return chainerrl.action_value.DiscreteActionValue(h5)
La même chose s'applique à cela. Je n'étudie pas assez. n_history est utilisé pour désigner un canal. Cette fois, je l'ai fait en échelle de gris, donc le canal est 1.
train.py
n_action = env.action_space.n
n_history=1
q_func = QFunction(n_history, n_action)
Capacité modifiée de 10 ** 6.
optimizer = chainer.optimizers.Adam(eps=1e-2)
optimizer.setup(q_func)
gamma = 0.95
explorer = chainerrl.explorers.ConstantEpsilonGreedy(
epsilon=0.3, random_action_func=env.action_space.sample)
replay_buffer = chainerrl.replay_buffer.ReplayBuffer(capacity=10 ** 4)
phi = lambda x: x.astype(np.float32, copy=False)
train.py
agent = chainerrl.agents.DoubleDQN(
q_func, optimizer, replay_buffer, gamma, explorer,
minibatch_size=4, replay_start_size=500, update_frequency=1,
target_update_frequency=100, phi=phi)
last_time = datetime.datetime.now()
n_episodes = 1000
for i in range(1, n_episodes + 1):
obs = resize(rgb2gray(env.reset()),(80,80))
obs = obs[np.newaxis, :, :]
reward = 0
done = False
R = 0
while not done:
action = agent.act_and_train(obs, reward)
obs, reward, done, _ = env.step(action)
obs = resize(rgb2gray(obs), (80, 80))
obs = obs[np.newaxis, :, :]
if reward != 0:
R += reward
elapsed_time = datetime.datetime.now() - last_time
print('episode:', i, '/', n_episodes,
'reward:', R,
'minutes:', elapsed_time.seconds/60)
last_time = datetime.datetime.now()
if i % 100 == 0:
filename = 'agent_Breakout' + str(i)
agent.save(filename)
agent.stop_episode_and_train(obs, reward, done)
print('Finished.')
Les principaux changements sont ces deux lignes. La première ligne est l'échelle de gris et le redimensionnement. Dans la deuxième ligne, j'ai changé la forme pour la mettre dans Convolution2D.
obs = resize(rgb2gray(env.reset()),(80,80))
obs = obs[np.newaxis, :, :]
J'ai utilisé un ordinateur portable avec 8 Go de mémoire, mais si je règle la capacité à 10 ** 6 et non en niveaux de gris, il sera tué environ 300 épisodes. Je ne sais pas lequel fonctionne, mais ces deux changements l'ont résolu.
Si vous étudiez environ 200 épisodes, vous obtiendrez 21 points d'affilée. J'ai obtenu environ 5 points en 1000 épisodes. L'apprentissage de 1000 épisodes prend une journée entière.
Je le posterai car je pense que cela peut être utile pour les débutants. Si vous avez des erreurs ou des points à améliorer, n'hésitez pas à nous donner quelques conseils.