Dernière fois suite ... Dans ce domaine, moi, un étranger, je n'ai pas du tout étudié «la théorie de l'apprentissage automatique». Je vais faire l'IA d'Othello. Cliquez ici pour le site référencé
J'ai fait l'IA d'Othello sans étudier du tout "la théorie de l'apprentissage automatique". Je résumerai les connaissances minimales requises pour la mettre en œuvre.
La structure et le rôle du fichier sont comme ça. --train.py --- Formation AI --Reversi.py --- Gestion du jeu Othello --dqn_agent.py --- Gestion de la formation en IA --FightWithAI.py --- Bataille avec les utilisateurs
L'algorithme DQN implémenté cette fois ressemble à ceci.
Si vous gardez ce flux à l'esprit, vous comprendrez de quoi vous parlez et ce que vous allez expliquer.
Le plateau utilisé pour les jeux Othello et l'entraînement à l'IA Cela se fait en utilisant un tableau à deux dimensions avec Non dans la figure ci-dessous.
Reversi.py
self.screen[0~7][0~7]
L'opération que AI peut sélectionner est de sélectionner le nombre de 0 à 63 dans la figure ci-dessus.
Reversi.py
self.enable_actions[0~63]
Dans l'entraînement à l'IA, les joueurs [0] et les joueurs [1] ont joué des batailles d'Othello n_epochs = 1000 fois. Enfin, sauvegardez l'IA du deuxième joueur [1].
--Si vous gagnez le jeu, définissez la récompense = 1 --Autre que cela, récompense = 0
Je jouerai avec deux IA, mais je dois agir même au tour de l'adversaire Parce que l'histoire jusqu'à la fin n'est pas connectée (la valeur Q n'est pas transmise)
Les deux agissent à chaque tour Cette fois, j'ai décidé de "sauvegarder la transition en D" pour tous les nombres qui peuvent être réglés séparément de la progression du jeu.
train.py
#cibles contient tous les nombres que vous pouvez mettre ce tour
for tr in targets:
#Dupliquer le statu quo
tmp = copy.deepcopy(env)
#action
tmp.update(tr, playerID[i])
#Fin du jugement
win = tmp.winner()
end = tmp.isEnd()
#Conseil après avoir agi
state_X = tmp.screen
#Un numéro que vous pouvez laisser après avoir agi
target_X = tmp.get_enables(playerID[i+1])
#Les deux actions
for j in range(0, len(players)):
reword = 0
if end == True:
if win == playerID[j]:
#Obtenez 1 récompense si vous gagnez
reword = 1
#Les deux "Enregistrer la transition en D"
players[j].store_experience(state, targets, tr, reword, state_X, target_X, end)
players[j].experience_replay()
La partie suivante de l'algorithme DQN est réalisée par dqn_agent.py.
--Save transition to D (, ai, ri, si + 1, terminal)
Je ne sais pas pourquoi c'est tout un pakuri du site auquel je fais référence
dqn_agent.py
def store_experience(self, state, targets, action, reward, state_1, targets_1, terminal):
self.D.append((state, targets, action, reward, state_1, targets_1, terminal))
>>
def experience_replay(self):
state_minibatch = []
y_minibatch = []
>>
# sample random minibatch
minibatch_size = min(len(self.D), self.minibatch_size)
minibatch_indexes = np.random.randint(0, len(self.D), minibatch_size)
>>
for j in minibatch_indexes:
state_j, targets_j, action_j, reward_j, state_j_1, targets_j_1, terminal = self.D[j]
action_j_index = self.enable_actions.index(action_j)
>>
y_j = self.Q_values(state_j)
>>
if terminal:
y_j[action_j_index] = reward_j
else:
# reward_j + gamma * max_action' Q(state', action')
qvalue, action = self.select_enable_action(state_j_1, targets_j_1)
y_j[action_j_index] = reward_j + self.discount_factor * qvalue
>>
state_minibatch.append(state_j)
y_minibatch.append(y_j)
>>
# training
self.sess.run(self.training, feed_dict={self.x: state_minibatch, self.y_: y_minibatch})
>>
# for log
self.current_loss = self.sess.run(self.loss, feed_dict={self.x: state_minibatch, self.y_: y_minibatch})
>>
Nom de variable | Contenu |
---|---|
state | Surface de la planche( = Reversi.screen[0~7][0~7] ) |
targets | Numéro que vous pouvez laisser |
action | Action sélectionnée |
reward | Récompense pour l'action 0-1 |
state_1 | Conseil après avoir agi |
targets_1 | Un numéro que vous pouvez laisser après avoir agi |
terminal | Fin du jeu = Vrai |
Dans l'entraînement à l'IA, les joueurs [0] et les joueurs [1] ont joué des batailles d'Othello n_epochs = 1000 fois. Enfin, sauvegardez l'IA du deuxième joueur [1].
train.py
# parameters
n_epochs = 1000
# environment, agent
env = Reversi()
# playerID
playerID = [env.Black, env.White, env.Black]
# player agent
players = []
# player[0]= env.Black
players.append(DQNAgent(env.enable_actions, env.name, env.screen_n_rows, env.screen_n_cols))
# player[1]= env.White
players.append(DQNAgent(env.enable_actions, env.name, env.screen_n_rows, env.screen_n_cols))
Cette partie
DQNAgent (env.enable_actions, env.name, env.screen_n_rows, env.screen_n_cols)
est
- Initialiser la mémoire de relecture D --Q NetworkQ est initialisé avec un poids aléatoire θ --Initialiser le réseau cibleQ θ ^ = θ
, Dqn_agent.py le fait.
dqn_agent.py
class DQNAgent:
>>
def __init__(self, enable_actions, environment_name, rows, cols):
...réduction...
#Initialisation de la mémoire de relecture D
self.D = deque(maxlen=self.replay_memory_size)
...réduction...
>>
def init_model(self):
# input layer (rows x cols)
self.x = tf.placeholder(tf.float32, [None, self.rows, self.cols])
>>
# flatten (rows x cols)
size = self.rows * self.cols
x_flat = tf.reshape(self.x, [-1, size])
>>
#Initialiser Q NetworkQ avec un poids aléatoire θ
W_fc1 = tf.Variable(tf.truncated_normal([size, size], stddev=0.01))
b_fc1 = tf.Variable(tf.zeros([size]))
h_fc1 = tf.nn.relu(tf.matmul(x_flat, W_fc1) + b_fc1)
>>
#Initialiser le réseau cible Q θ^=θ
W_out = tf.Variable(tf.truncated_normal([size, self.n_actions], stddev=0.01))
b_out = tf.Variable(tf.zeros([self.n_actions]))
self.y = tf.matmul(h_fc1, W_out) + b_out
>>
# loss function
self.y_ = tf.placeholder(tf.float32, [None, self.n_actions])
self.loss = tf.reduce_mean(tf.square(self.y_ - self.y))
>>
# train operation
optimizer = tf.train.RMSPropOptimizer(self.learning_rate)
self.training = optimizer.minimize(self.loss)
>>
# saver
self.saver = tf.train.Saver()
>>
# session
self.sess = tf.Session()
self.sess.run(tf.initialize_all_variables())
python
for e in range(n_epochs):
# reset
env.reset()
terminal = False
- for episode =1, M do
python
while terminal == False: #Boucle jusqu'à la fin d'un épisode
for i in range(0, len(players)):
state = env.screen
targets = env.get_enables(playerID[i])
if len(targets) > 0:
#S'il y a un endroit pour le mettre quelque part
#← Ici, toutes les mains mentionnées ci-dessus sont "sauvegardées en D"
#Choisissez une action
action = players[i].select_action(state, targets, players[i].exploration)
#Passer à l'action
env.update(action, playerID[i])
- while not terminal --Sélection d'action
La sélection d'action ʻagent.select_action (state_t, cibles, agent.exploration) `est Ceci est fait par dqn_agent.py.
- Sélection des actions
dqn_agent.py
def Q_values(self, state):
# Q(state, action) of all actions
return self.sess.run(self.y, feed_dict={self.x: [state]})[0]
>>
def select_action(self, state, targets, epsilon):
>>
if np.random.rand() <= epsilon:
# random
return np.random.choice(targets)
else:
# max_action Q(state, action)
qvalue, action = self.select_enable_action(state, targets)
return action
>>
#Le tableau(state)alors,Endroit pour mettre(targets)Renvoie la valeur Q et le nombre qui maximise la valeur Q de
def select_enable_action(self, state, targets):
Qs = self.Q_values(state)
#descend = np.sort(Qs)
index = np.argsort(Qs)
for action in reversed(index):
if action in targets:
break
# max_action Q(state, action)
qvalue = Qs[action]
>>
return qvalue, action
-Exécuter l'action ai et observer la récompense ri, l'écran suivant xi + 1 et terminer le jugement tarminal --Pré-traiter et créer l'état suivant si + 1
Enfin, enregistrez cette dernière IA
#Le résultat de l'exécution de l'action
terminal = env.isEnd()
w = env.winner()
print("EPOCH: {:03d}/{:03d} | WIN: player{:1d}".format(
e, n_epochs, w))
#Enregistrer sauve le deuxième joueur player2.
players[1].save_model()
La source est ici.
$ git clone https://github.com/sasaco/tf-dqn-reversi.git
La prochaine fois vous parlera de l'édition de combat.
Recommended Posts