Lors de la session d'étude à laquelle j'assistais, il y avait une histoire sur le renforcement de la troisième ligne, alors j'ai écrit le code.
Puisque j'ai utilisé cette fois la méthode Monte Carlo (policy on type), je n'écrirai que autour de la méthode Monte Carlo. (Je ne suis pas sûr du contenu car je viens de lire un petit livre quand j'ai entendu l'histoire à la session d'étude.) Pour écrire sur la méthode de Monte Carlo en un mot, c'est une méthode (apparemment) d'évaluation et d'amélioration des politiques tout en répétant les politiques en apprenant le nombre de valeurs et les mesures optimales à partir de l'expérience du format d'épisode d'échantillon. (Le code peut également être grossièrement divisé en blocs de répétition des politiques, d'évaluation des politiques et d'amélioration des politiques) Les avantages et inconvénients sont énumérés ci-dessous.
Cependant, en regardant le taux de victoire de la troisième ligne dans "Comment rendre un joueur de jeu robotique plus fort", la méthode de Monte Carlo était la plus élevée, donc j'écris le code pour la méthode de Monte Carlo.
Puisqu'il s'agit d'un arrangement à trois voies, il s'agit d'un code lors de l'apprentissage dans un espace discret et le pas de temps final T existe.
Le code ci-dessous est presque le même que celui décrit dans la rondelle (ry </ del>) "Comment créer un joueur de jeu robotique fort".
Ensuite, j'écrirai le code ci-dessous.
python
# coding: utf-8
import numpy as np
from math import floor
import matplotlib.pyplot as plt
class MonteCarloPolycyIteration:
n_states = 3**9 #Nombre d'états
n_actions = 9 #Nombre d'actions
T = 5 #Nombre maximum d'étapes
visites = None
states = None
actions = None
rewards = None
drewards = None
results = None
rate = []
#Il devient le même état lorsque la surface de la carte est tournée
#Effectuer la conversion et réduire le nombre d'états
convert = [[0,1,2,3,4,5,6,7,8], #L'état original
[2,1,0,5,4,3,8,7,6], #conversion(2)
[6,3,0,7,4,1,8,5,2], #conversion(3)
[0,3,8,1,4,7,2,5,8], #conversion(4)
[8,7,6,5,4,3,2,1,0], #conversion(5)
[6,7,8,3,4,5,0,1,2], #conversion(6)
[2,5,8,1,4,7,0,3,6], #conversion(7)
[8,5,2,7,4,1,6,3,0] #conversion(8)
]
#Vecteur de conversion de ternaire en décimal
power = np.array([ 3**i for i in xrange(8,-1,-1) ], dtype=np.float64)
def __init__(self,L,M,options):
self.L = L #Nombre d'itérations de politique
self.M = M #Nombre d'épisodes
self.options = options
self.Q = self.init_Q()
np.random.seed(555)
def init_Q(self):
"""Initialisation de la fonction Q(initialize look up table) """
return np.zeros((self.n_states,self.n_actions))
def train(self):
# policy iteration
for l in xrange(self.L):
self.visites = self.init_visites()
self.states = self.init_matrix()
self.actions = self.init_matrix()
self.rewards = self.init_matrix()
self.drewards = self.init_matrix()
self.results = self.init_results()
# episode
for m in xrange(self.M):
state3 = self.init_state3()
# step
for t in xrange(self.T):
state = self.encode(state3)
policy = self.generate_policy()
policy = self.policy_improvement(policy,state)
#Sélection et exécution des actions
action, reward, state3, fin = self.action_train(policy, t, state3)
self.update(m, t, state, action, reward)
if self.isfinished(fin):
#print 'fin_state',state3
self.results[m] = fin
#Calcul de la somme des récompenses de réduction
self.calculate_discounted_rewards(m, t)
break
self.Q = self.calculate_state_action_value_function()
self.output_results(l)
self.rate.append( float(len(self.results[self.results==2]))/self.M )
def init_visites(self):
return np.ones((self.n_states, self.n_actions))
def init_matrix(self):
return np.ones((self.M, self.T))
def init_results(self):
return np.zeros(self.M)
def init_state3(self):
return np.zeros(self.n_actions)
def generate_policy(self):
return np.zeros(self.n_actions)
def policy_improvement(self,policy,state):
if self.options['pmode']==0:
q = self.Q[state] #Indiquer la valeur dans la politique actuelle
v = max(q) #Valeur en comportement optimal dans l'état actuel
a = np.where(q==v)[0][0] #Comportement optimal
policy[a] = 1
elif self.options['pmode']==1:
q = self.Q[state] #Indiquer la valeur dans la politique actuelle
v = max(q) #Valeur en comportement optimal dans l'état actuel
a = np.where(q==v)[0][0] #Comportement optimal
policy = np.ones(self.n_actions)*self.options['epsilon']/self.n_actions
policy[a] = 1-self.options['epsilon']+self.options['epsilon']/self.n_actions
elif self.options['pmode']==2:
policy = np.exp(self.Q[state]/self.options['tau'])/ \
sum(np.exp(self.Q[state]/self.options['tau']))
return policy
def action_train(self, policy, t, state3):
npc_action = self.select_npc_action(t, state3, policy)
state3[npc_action] = 2
fin = self.check_game(state3)
reward = self.calculate_reward(fin)
if reward is not None:
return npc_action, reward, state3, fin
enemy_action = self.select_enemy_action(t, state3)
state3[enemy_action] = 1
fin = self.check_game(state3)
reward = self.calculate_reward(fin)
return npc_action, reward, state3, fin
def select_npc_action(self, step, state3, policy):
a = None
if step==0:
a = 0
else:
while 1:
random = np.random.rand()
cprob = 0
for a in xrange(self.n_actions):
cprob += policy[a]
if random<cprob: break
#Vérifiez si la masse est déjà remplie
if state3[a]==0:break
return a
def select_enemy_action(self, step, state3):
reach = 0
pos = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[1,5,8],[0,4,8],[2,4,6]]
a = None
for i in xrange(len(pos)):
state_i = state3[pos[i]]
val = sum(state_i)
num = len(state_i[state_i==0])
if val==2 and num==1:
idx = int( state_i[state_i==0][0] )
a = pos[i][idx]
reach = 1
break
if reach==0:
while 1:
a = floor(np.random.rand()*8)+1
if state3[a]==0: break
return a
def check_game(self, state3):
pos = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[1,5,8],[0,4,8],[2,4,6]]
for i in xrange(len(pos)):
state_i = state3[pos[i]]
val_npc = sum(state_i==1)
val_enemy = sum(state_i==2)
if val_npc==3:
return 1 #gagner
elif val_enemy==3:
return 2 #Perdre
if sum(state3==0)==0:
return 3 #dessiner
return 0 #Continuer le jeu
def calculate_reward(self, fin):
if fin==2:
return 10
elif fin==1:
return -10
elif fin==3:
return 0
elif fin==0:
return None
def update(self,m,t,state,action,reward):
"""Mettre à jour l'état, les actions, les récompenses, le nombre d'apparences"""
self.states[m,t] = state
self.actions[m,t] = action
self.rewards[m,t] = reward
self.visites[state, action] += 1
def isfinished(self,fin):
if fin>0: return True
else: return False
def calculate_discounted_rewards(self, m, t):
for pstep in xrange(t-1,-1,-1):
self.drewards[m,t] = self.rewards[m,t]
self.drewards[m,pstep] = \
self.options['gamma']*self.drewards[m,pstep+1]
def calculate_state_action_value_function(self):
Q = self.init_Q()
for m in xrange(self.M):
for t in xrange(self.T):
s = self.states[m,t]
if s==0: break #S'il est terminé au 9ème coup, le processus est terminé
a =self.actions[m,t]
Q[s,a] += self.drewards[m,t]
return Q/self.visites
def output_results(self,l):
print 'l=%d: Win=%d/%d, Draw=%d/%d, Lose=%d/%d\n' % (l, \
len(self.results[self.results==2]),self.M, \
len(self.results[self.results==3]),self.M, \
len(self.results[self.results==1]),self.M)
def encode(self, state3):
#établir(2)~(8)Après avoir ajouté 8 types de conversion, convertir en nombre décimal
cands = [ sum(state3[self.convert[i]]*self.power) #Échangez les index et convertissez en décimal
for i in xrange(len(self.convert))]
#Choisissez le plus petit des 8 candidats
return min(cands)+1
if __name__=='__main__':
options = {'pmode':1,'epsilon':0.05,'tau':2,'gamma':0.9}
mcpi= MonteCarloPolycyIteration(100,100,options)
mcpi.train()
plt.plot(range(len(mcpi.rate)), mcpi.rate)
plt.show()
J'ai expérimenté en utilisant la méthode ε-gourmande avec 100 étapes comme un ensemble. Ci-dessous, nous afficherons le taux de gain pour 100 sets pendant l'apprentissage.
L'apprentissage semble fonctionner, mais le calcul est lent. .. Il est imprudent d'implémenter la méthode Monte Carlo en python. .. À propos, le même résultat a été obtenu avec softmax.
Nous vous prions de nous excuser pour la gêne occasionnée, mais si vous faites une erreur, nous vous serions reconnaissants de bien vouloir la signaler.
Recommended Posts