2017-08-25 3 views
0

J'essaie de mettre en œuvre q-learning avec une fonction d'approximation de valeur d'action. J'utilise openai-gym et l'environnement "MountainCar-v0" pour tester mon algorithme. Mon problème est, il ne converge pas ou ne trouve pas l'objectif du tout.Approximateur de fonction et q-learning

Fondamentalement l'approximateur fonctionne comme suit, vous alimentez dans les 2 caractéristiques: position et vitesse et l'une des 3 actions dans un codage à chaud: 0 -> [1,0,0], 1 -> [ 0,1,0] et 2 -> [0,0,1]. La sortie est l'approximation de la valeur d'action Q_approx (s, a), pour une action spécifique.

Je sais que généralement, l'entrée est l'état (2 caractéristiques) et la couche de sortie contient 1 sortie pour chaque action. La grande différence que je vois est que j'ai couru la passe d'avance 3 fois (un pour chaque action) et prenons le maximum, tandis que dans l'implémentation standard vous l'exécutez une fois et prenez le maximum sur la sortie.

Peut-être que ma mise en œuvre est complètement fausse et je me trompe. Je vais coller le code ici, c'est un bordel mais j'expérimente juste un peu:

import gym 
import numpy as np 
from keras.models import Sequential 
from keras.layers import Dense, Activation 

env = gym.make('MountainCar-v0') 

# The mean reward over 20 episodes 
mean_rewards = np.zeros(20) 
# Feature numpy holder 
features = np.zeros(5) 
# Q_a value holder 
qa_vals = np.zeros(3) 

one_hot = { 
    0 : np.asarray([1,0,0]), 
    1 : np.asarray([0,1,0]), 
    2 : np.asarray([0,0,1]) 
} 

model = Sequential() 
model.add(Dense(20, activation="relu",input_dim=(5))) 
model.add(Dense(10,activation="relu")) 
model.add(Dense(1)) 
model.compile(optimizer='rmsprop', 
       loss='mse', 
       metrics=['accuracy']) 

epsilon_greedy = 0.1 
discount = 0.9 
batch_size = 16 

# Experience replay containing features and target 
experience = np.ones((10*300,5+1)) 

# Ring buffer 
def add_exp(features,target,index): 
    if index % experience.shape[0] == 0: 
     index = 0 
     global filled_once 
     filled_once = True 
    experience[index,0:5] = features 
    experience[index,5] = target 
    index += 1 
    return index 

for e in range(0,100000): 
    obs = env.reset() 
    old_obs = None 
    new_obs = obs 
    rewards = 0 
    loss = 0 
    for i in range(0,300): 

     if old_obs is not None: 
      # Find q_a max for s_(t+1) 
      features[0:2] = new_obs 
      for i,pa in enumerate([0,1,2]): 
       features[2:5] = one_hot[pa] 
       qa_vals[i] = model.predict(features.reshape(-1,5)) 

      rewards += reward 
      target = reward + discount*np.max(qa_vals) 

      features[0:2] = old_obs 
      features[2:5] = one_hot[a] 

      fill_index = add_exp(features,target,fill_index) 

      # Find new action 
      if np.random.random() < epsilon_greedy: 
       a = env.action_space.sample() 
      else: 
       a = np.argmax(qa_vals) 
     else: 
      a = env.action_space.sample() 

     obs, reward, done, info = env.step(a) 

     old_obs = new_obs 
     new_obs = obs 

     if done: 
      break 

     if filled_once: 
      samples_ids = np.random.choice(experience.shape[0],batch_size) 
      loss += model.train_on_batch(experience[samples_ids,0:5],experience[samples_ids,5].reshape(-1))[0] 
    mean_rewards[e%20] = rewards 
    print("e = {} and loss = {}".format(e,loss)) 
    if e % 50 == 0: 
     print("e = {} and mean = {}".format(e,mean_rewards.mean())) 

Merci d'avance!

+0

J'ai entendu parler d'utiliser les actions comme des fonctionnalités avant, mais je n'ai pas entendu parler de cela fonctionne bien. Je pense que vous êtes mieux d'aller avec la tradition à ce sujet et d'utiliser des actions comme sorties. Mathématiquement, ces deux réseaux seront très différents. – Andnp

Répondre

1

Il ne devrait pas y avoir beaucoup de différence entre les actions en tant qu'entrées sur votre réseau ou en tant que sorties différentes de votre réseau. Cela fait une énorme différence si vos états sont des images par exemple. parce que les réseaux Conv fonctionnent très bien avec les images et il n'y aurait pas de moyen évident d'intégrer les actions à l'entrée.

Avez-vous essayé l'environnement d'équilibrage du cartpole? Il est préférable de tester si votre modèle fonctionne correctement.

La montée en montagne est assez difficile. Il n'a pas de récompense avant d'atteindre le sommet, ce qui n'arrive souvent pas du tout. Le modèle commencera seulement à apprendre quelque chose d'utile une fois arrivé au sommet. Si vous n'arrivez jamais au sommet, vous devriez probablement augmenter votre temps d'exploration. en d'autres termes, prendre des actions plus aléatoires, beaucoup plus ...