PPO est l'un des algorithmes d'apprentissage par renforcement profond, parmi lesquels il est basé sur des politiques. Une base de politique est un algorithme qui optimise directement une fonction de politique qui génère une probabilité d'action dans un environnement. D'autres algorithmes basés sur des politiques incluent A3C et TRPO. Les algorithmes non basés sur des politiques incluent des algorithmes basés sur des valeurs tels que DQN.
Tout d'abord, je vais expliquer d'autres méthodes.
Il existe trois techniques typiques utilisées dans A3C: Actor-Critic, Advantage et Asynchronous.
Actor-Critic Actor-Critic est une caractéristique de la structure du réseau. En A3C comme fonction objective de la politique
L_{policy}=A(t)log\pi_{\theta}(a_{t}|s_{t})
Est utilisé. Parmi ceux-ci, A (t) est appelée la fonction avantage.
A(t)=(R(t)-V(s_{t}))
Il est représenté par. Puisque la fonction valeur V (s) est utilisée pour obtenir ce A (t), il s'agit d'une méthode de construction d'un modèle de sorte que la valeur d'état devienne la sortie du réseau en même temps que la politique (distribution de probabilité d'action). Cela vous permettra d'apprendre plus rapidement.
Advantage Utilisez l'erreur suivante pour mettre à jour la fonction de valeur d'état normal $ V (t) $
loss=r(s_{t})+\gamma V(s_{t+1})-V(s_{t})
Nous apprendrons $ V (s) $ à satisfaire. Cependant, avec cette méthode, si le nombre d'étapes dans un épisode est important, le nombre d'apprentissages nécessaires pour se propager aux étapes où l'influence de l'apprentissage est précoce augmente et l'apprentissage devient lent. Par conséquent, Advantage utilise l'erreur suivante.
loss=\sum_{k=1}^n \gamma^{k-1} r(s_{t+k})+\gamma^n V(s_{t+2})-V(s_{t})
En ajustant $ n $ dans cette équation, les effets de l'apprentissage ultérieur se propageront plus rapidement, mais s'il est trop grand, la vitesse d'apprentissage ralentira. Par exemple, CartPole n'est pas très efficace et dans certains cas, il peut être plus rapide de ne pas utiliser Advantage. Asynchronous Asynchrone est une méthode liée aux méthodes d'apprentissage. Normalement, lors d'une recherche avec un agent, la direction de l'apprentissage a tendance à être biaisée. En guise de contre-mesure, la recherche est effectuée à l'aide d'un réseau de neurones partagé et de plusieurs agents, et chacun comporte un nombre fixe d'étapes. Au fil du temps, ou à la fin d'un épisode, chaque agent met à jour les paramètres réseau partagés pour un gradient sur les paramètres de fonction objectif.
Chaque agent dispose également d'un réseau neuronal qui copie les paramètres du réseau partagé et effectue des recherches avant le début de l'épisode. Cela évitera les biais dans l'apprentissage, comme le tampon de relecture dans DQN.
La fonction objectif d'A3C utilise trois méthodes: politique, valeur d'état et entropie pour la régularisation.
\begin{align}
L_{policy} &= A(t)log\pi_{\theta}(a_{t}|s_{t})\\
L_{value} &= (R(t)-V(s_{t}))^2\\
L_{entropy} &= \pi_{\theta}(a_{t}|s_{t})log\pi_{\theta}(a_{t}|s_{t})
\end{align}
Il est exprimé comme, et finalement il devient la formule suivante sous forme de combinaison de ceux-ci.
L_{all} = -L_{policy}+C_{value}L_{value}-C_{entropy}L_{entropy}
$ C_ {valeur} $ et $ C_ {entropie} $ représentent des constantes. L'apprentissage se fait en minimisant cela.
Dans A3C, le gradient de politique est
\Delta L_{policy} = \Delta log\pi_{\theta}(a_{t}|s_{t})A(t)
Il est exprimé comme, et comme $ log $ est inclus dans l'expression, il devient très grand lors de la mise à jour. Par conséquent, dans PPO, en limitant la mise à jour, il est possible d'éviter une sur-mise à jour. De plus, la fonction objectif est très différente de A3C.
r_{t}(\theta)=\frac{\pi_{\theta_{new}}(a_{t}|s_{t})}{\pi_{\theta_{old}}(a_{t}|s_{t})}\\
L^{CPI}=\mathbb E \big[\,r_{t}(\theta)A(t)\, \big]
Utilisez-la comme fonction d'objectif de substitution et utilisez la fonction de clip lors de la mise à jour pour en faire la fonction objectif de la stratégie. fonction de clip
clip(x,a,b)=\left\{
\begin{array}{ll}
b & (x > b) \\
x & (a \leq x \leq b) \\
a & (x < a)
\end{array}
\right.
Exprimé de cette façon, peu importe comment $ x $ change, il se situera entre $ a $ et $ b $. La fonction objectif utilisant cette fonction
L_{policy}=min \big(\, r_{t}(\theta)A(t),clip(r_{t}(\theta),1-\epsilon,1+\epsilon)\, \big)
Est exprimé comme. En ce qui concerne la fonction de valeur d'état, c'est presque la même chose que PPO.
De plus, PPO apprend également à utiliser Advantage de la même manière que A3C.
J'ai fait référence au site suivant lors de la mise en œuvre [Renforcement de l'apprentissage] PPO pour apprendre tout en mettant en œuvre [Standing with Cart Pole: Complete with 1 file]
main (): créer un thread et effectuer le traitement
Worker(thread_type, thread_name, ppo_brain) -run_thread (): Traitement séparé par type de thread -env_run (): Laisse l'agent explorer dans l'environnement.
ppo_agent(ppo_brain) -action (état): reçoit l'état et émet l'action -greedy_action (state): action de sortie en utilisant la méthode $ \ epsilon-greedy $ -update (mémoire): Apprenez les données enregistrées lors de la recherche en tenant compte de l'avantage ppo_brain() -build_graph: Définissez ici la forme du graphique -update: mise à jour
main
def main(args):
#Processus pour créer un fil
with tf.device("/cpu:0"):
brain = ppo_brain()
thread=[]
for i in range(WORKER_NUM):
thread_name = "local_thread"+str(i)
thread.append(Worker(thread_type = "train",thread_name = thread_name,brain = brain))
COORD = tf.train.Coordinator()
SESS.run(tf.global_variables_initializer())
saver = tf.train.Saver()
#Chargez le processus de formation précédent, faites-le après avoir défini le modèle
if args.load:
ckpt = tf.train.get_checkpoint_state(MODEL_DIR)
if ckpt:
saver.restore(SESS,MODEL_SAVE_PATH)
runnning_thread=[]
for worker in thread:
job = lambda: worker.run_thread()
t = threading.Thread(target=job)
t.start()
runnning_thread.append(t)
COORD.join(runnning_thread)
#Faites un test lorsque l'apprentissage est terminé
test = Worker(thread_type = "test",thread_name = "test_thread",brain=brain)
test.run_thread()
if args.save:
saver.save(SESS,MODEL_SAVE_PATH)
print("saved")
Worker
class Worker:
def __init__(self,thread_type,thread_name,brain):
self.thread_type = thread_type
self.name = thread_name
self.agent = ppo_agent(brain)
self.env = gym.make(ENV_NAME)
#Enregistrez la vidéo au moment du test
if self.thread_type == "test" and args.video:
self.env = wrappers.Monitor(self.env, VIDEO_DIR, force = True)
self.leaning_memory = np.zeros(10)
self.memory = []
self.total_trial = 0
def run_thread(self):
while True:
if self.thread_type == "train" and not isLearned:
self.env_run()
elif self.thread_type == "train" and isLearned:
sleep(3)
break
elif self.thread_type == "test" and not isLearned:
sleep(3)
elif self.thread_type == "test" and isLearned:
self.env_run()
break
def env_run(self):
global isLearned
global frame
self.total_trial += 1
step = 0
observation = self.env.reset()
while True:
step += 1
frame += 1
#Choix d'action
if self.thread_type == "train":
action=self.agent.greedy_action(observation)
elif self.thread_type == "test":
self.env.render()
sleep(0.01)
action=self.agent.action(observation)
next_observation,_,done,_ = self.env.step(action)
reward = 0
if done:
if step >= 199:
reward = 1 #Au moment du succès
else:
reward =- 1 #Au moment de l'échec
else:
#Quand ce n'est pas fini
reward+=0
#Enregistrer le résultat en mémoire
self.memory.append([observation,action,reward,done,next_observation])
observation = next_observation
if done:
break
#Calculez le score moyen de 10 fois
self.leaning_memory = np.hstack((self.leaning_memory[1:],step))
print("Thread:",self.name," Thread_trials:",self.total_trial," score:",step," mean_score:",self.leaning_memory.mean()," total_step:",frame)
#À la fin de l'apprentissage
if self.leaning_memory.mean() >= 199:
isLearned = True
sleep(3)
else:
#Mise à jour des paramètres
self.agent.update(self.memory)
self.memory = []
ppo_agent
class ppo_agent:
def __init__(self,brain):
self.brain=brain
self.memory=[]
#Agir sans éléments aléatoires
def action(self,state):
prob,v = self.brain.predict(state)
return np.random.choice(ACTION_LIST,p = prob)
#Agir au hasard avec une certaine probabilité
def greedy_action(self,state):
if frame >= EPS_STEPS:
eps = EPS_END
else:
eps = EPS_START + frame* (EPS_END - EPS_START) / EPS_STEPS
if np.random.random() <= eps:
return np.random.choice(ACTION_LIST)
else:
return self.action(state)
#Traiter le résultat de la recherche et le PPO_Envoyer au cours de cerveau
def update(self,memory):
R = sum([memory[j][2] * (GAMMA ** j) for j in range(ADVANTAGE + 1)])
self.memory.append([memory[0][0], memory[0][1], R,memory[0][3], memory[0][4], GAMMA ** ADVANTAGE])
#Considérez l'avantage
for i in range(1, len(memory) - ADVANTAGE):
R = ((R - memory[i-1][2]) / GAMMA) + memory[i + ADVANTAGE][2] * (GAMMA ** (ADVANTAGE - 1))
self.memory.append([memory[i][0], memory[i][1], R,memory[i + ADVANTAGE][3], memory[i][4],GAMMA ** ADVANTAGE])
for i in range(ADVANTAGE - 1):
R = ((R - memory[len(memory) - ADVANTAGE + i][2]) / GAMMA)
self.memory.append([memory[i][0], memory[i][1], R, True, memory[i][4], GAMMA ** (ADVANTAGE - i)])
#ppo_Envoyer des données à la classe de cerveau pour mettre à jour
self.brain.update(self.memory)
self.memory = []
ppo_brain
class ppo_brain:
def __init__(self):
self.build_model()
self.name="brain"
self.prob_old=1.0
def build_model(self):
self.input=tf.placeholder(dtype=tf.float32,shape=[None,STATE_NUM])
#Ici, l'ancien modèle de paramètre et le nouveau modèle de paramètre sont définis, et la probabilité d'action et la valeur d'état sont sorties pour la même entrée.
#Nouveau réseau
with tf.variable_scope("current_brain"):
hidden1=tf.layers.dense(self.input,HIDDEN_LAYERE,activation=tf.nn.leaky_relu)
self.prob=tf.layers.dense(hidden1,ACTION_NUM,activation=tf.nn.softmax)
self.v=tf.layers.dense(hidden1,1)
#Ancien réseau
with tf.variable_scope("old_brain"):
old_hiddend1=tf.layers.dense(self.input,HIDDEN_LAYERE,activation=tf.nn.leaky_relu)
self.old_prob=tf.layers.dense(hidden1,ACTION_NUM,activation=tf.nn.softmax)
self.old_v=tf.layers.dense(hidden1,1)
self.reward=tf.placeholder(dtype=tf.float32,shape=(None,1))
self.action=tf.placeholder(dtype=tf.float32,shape=(None,ACTION_NUM))
###########Voici la définition de la fonction de perte############
#Définition de la fonction d'avantage
advantage = self.reward-self.v
#Définition faisant partie de la fonction de perte du contrat
r_theta = tf.div(self.prob + 1e-10, tf.stop_gradient(self.old_prob) + 1e-10)
action_theta = tf.reduce_sum(tf.multiply(r_theta, self.action), axis = 1, keepdims = True)
#Calculer le clip de r
r_clip = tf.clip_by_value(action_theta, 1 - EPSIRON, 1 + EPSIRON)
#Lorsque vous utilisez la fonction avantage comme fonction objectif de la politique, le gradient n'est pas pris en compte, alors arrêtez_Utiliser le dégradé
advantage_cpi = tf.multiply(action_theta, tf.stop_gradient(advantage))
advantage_clip = tf.multiply(r_clip , tf.stop_gradient(advantage))
self.policy_loss = tf.minimum(advantage_clip , advantage_cpi)
#Fonction de perte de valeur d'état
self.value_loss = tf.square(advantage)
#Définition de l'entropie
self.entropy = tf.reduce_sum(self.prob*tf.log(self.prob+1e-10),axis = 1,keepdims = True)
#Définition de la fonction de perte finale
self.loss = tf.reduce_sum(-self.policy_loss + LOSS_V * self.value_loss - LOSS_ENTROPY * self.entropy)
##############Ce qui suit définit les actions requises pour la mise à jour##############
#Mise à jour des paramètres (minimisée à l'aide d'Adam)
self.opt = tf.train.AdamOptimizer(learning_rate = LEARNING_RATE)
self.minimize = self.opt.minimize(self.loss)
#Obtenez de nouveaux et anciens paramètres de leurs réseaux respectifs
self.weight_param = tf.get_collection(key = tf.GraphKeys.TRAINABLE_VARIABLES, scope = "current_brain")
self.old_weight_param = tf.get_collection(key = tf.GraphKeys.TRAINABLE_VARIABLES, scope = "old_brain")
#Remplacer de nouveaux paramètres réseau par d'anciens paramètres réseau
self.insert = [g_p.assign(l_p) for l_p,g_p in zip(self.weight_param,self.old_weight_param)]
#Probabilité d'action de sortie et valeur d'état à partir de l'état
def predict(self,state):
state=np.array(state).reshape(-1,STATE_NUM)
feed_dict={self.input:state}
p,v=SESS.run([self.prob,self.v],feed_dict)
return p.reshape(-1),v.reshape(-1)
#Créer un lot par prétraitement avant de saisir des données
#Mise à jour
def update(self,memory):
length=len(memory)
s_=np.array([memory[j][0] for j in range(length)]).reshape(-1,STATE_NUM)
a_=np.eye(ACTION_NUM)[[memory[j][1] for j in range(length)]].reshape(-1,ACTION_NUM)
R_=np.array([memory[j][2] for j in range(length)]).reshape(-1,1)
d_=np.array([memory[j][3] for j in range(length)]).reshape(-1,1)
s_mask=np.array([memory[j][5] for j in range(length)]).reshape(-1,1)
_s=np.array([memory[j][4] for j in range(length)]).reshape(-1,STATE_NUM)
#Inférer la dernière valeur d'état
_, v=self.predict(_s)
#Calculez la récompense en tenant compte de l'avantage
R=(np.where(d_,0,1)*v.reshape(-1,1))*s_mask+R_
#Mise à jour des paramètres
feed_dict={self.input:s_, self.action:a_, self.reward:R}
SESS.run(self.minimize,feed_dict)
#Mise à jour du réseau
SESS.run(self.insert)
Le code entier ressemble à ceci:
import argparse
import tensorflow as tf
import numpy as np
import random
import threading
import gym
from time import sleep
from gym import wrappers
from os import path
parser=argparse.ArgumentParser(description="Reiforcement training with PPO",add_help=True)
parser.add_argument("--model",type=str,required=True,help="model base name. required")
parser.add_argument("--env_name",default="CartPole-v0",help="environment name. default is CartPole-v0")
parser.add_argument("--save",action="store_true",default=False,help="save command")
parser.add_argument("--load",action="store_true",default=False,help="load command")
parser.add_argument("--thread_num",type=int,default=5)
parser.add_argument("--video",action="store_true",default=False, help="write this if you want to save as video")
args=parser.parse_args()
ENV_NAME=args.env_name
WORKER_NUM=args.thread_num
#define constants
VIDEO_DIR="./train_info/video"
MODEL_DIR="./train_info/models"
MODEL_SAVE_PATH=path.join(MODEL_DIR,args.model)
ADVANTAGE=2
STATE_NUM=4
ACTION_LIST=[0,1]
ACTION_NUM=2
#epsiron parameter
EPS_START = 0.5
EPS_END = 0.1
EPS_STEPS = 200 * WORKER_NUM**2
#learning parameter
GAMMA=0.99
LEARNING_RATE=0.002
#loss constants
LOSS_V=0.5
LOSS_ENTROPY=0.02
HIDDEN_LAYERE=30
EPSIRON = 0.2
class ppo_brain:
def __init__(self):
self.build_model()
self.name="brain"
self.prob_old=1.0
def build_model(self):
self.input=tf.placeholder(dtype=tf.float32,shape=[None,STATE_NUM])
#Ici, l'ancien modèle de paramètre et le nouveau modèle de paramètre sont définis, et la probabilité d'action et la valeur d'état sont sorties pour la même entrée.
with tf.variable_scope("current_brain"):
hidden1=tf.layers.dense(self.input,HIDDEN_LAYERE,activation=tf.nn.leaky_relu)
self.prob=tf.layers.dense(hidden1,ACTION_NUM,activation=tf.nn.softmax)
self.v=tf.layers.dense(hidden1,1)
with tf.variable_scope("old_brain"):
old_hiddend1=tf.layers.dense(self.input,HIDDEN_LAYERE,activation=tf.nn.leaky_relu)
self.old_prob=tf.layers.dense(hidden1,ACTION_NUM,activation=tf.nn.softmax)
self.old_v=tf.layers.dense(hidden1,1)
self.reward=tf.placeholder(dtype=tf.float32,shape=(None,1))
self.action=tf.placeholder(dtype=tf.float32,shape=(None,ACTION_NUM))
###########Voici la définition de la fonction de perte############
#Définition de la fonction d'avantage
advantage = self.reward-self.v
#Définition faisant partie de la fonction de perte du contrat
r_theta = tf.div(self.prob + 1e-10, tf.stop_gradient(self.old_prob) + 1e-10)
action_theta = tf.reduce_sum(tf.multiply(r_theta, self.action), axis = 1, keepdims = True)
r_clip = tf.clip_by_value(action_theta, 1 - EPSIRON, 1 + EPSIRON)
advantage_cpi = tf.multiply(action_theta, tf.stop_gradient(advantage))
advantage_clip = tf.multiply(r_clip , tf.stop_gradient(advantage))
self.policy_loss = tf.minimum(advantage_clip , advantage_cpi)
#Fonction de perte de valeur d'état
self.value_loss = tf.square(advantage)
#Définition de l'entropie
self.entropy = tf.reduce_sum(self.prob*tf.log(self.prob+1e-10),axis = 1,keepdims = True)
#Définition de la fonction de perte finale
self.loss = tf.reduce_sum(-self.policy_loss + LOSS_V * self.value_loss - LOSS_ENTROPY * self.entropy)
##############Ce qui suit définit les actions requises pour la mise à jour##############
#Mise à jour des paramètres (minimisée à l'aide d'Adam)
self.opt = tf.train.AdamOptimizer(learning_rate = LEARNING_RATE)
self.minimize = self.opt.minimize(self.loss)
#Obtenez de nouveaux et anciens paramètres de leurs réseaux respectifs
self.weight_param = tf.get_collection(key = tf.GraphKeys.TRAINABLE_VARIABLES, scope = "current_brain")
self.old_weight_param = tf.get_collection(key = tf.GraphKeys.TRAINABLE_VARIABLES, scope = "old_brain")
#Remplacer de nouveaux paramètres réseau par d'anciens paramètres réseau
self.insert = [g_p.assign(l_p) for l_p,g_p in zip(self.weight_param,self.old_weight_param)]
#Probabilité d'action de sortie et valeur d'état à partir de l'état
def predict(self,state):
state=np.array(state).reshape(-1,STATE_NUM)
feed_dict={self.input:state}
p,v=SESS.run([self.prob,self.v],feed_dict)
return p.reshape(-1),v.reshape(-1)
#Créer un lot par prétraitement avant de saisir des données
#Mise à jour
def update(self,memory):
length=len(memory)
s_=np.array([memory[j][0] for j in range(length)]).reshape(-1,STATE_NUM)
a_=np.eye(ACTION_NUM)[[memory[j][1] for j in range(length)]].reshape(-1,ACTION_NUM)
R_=np.array([memory[j][2] for j in range(length)]).reshape(-1,1)
d_=np.array([memory[j][3] for j in range(length)]).reshape(-1,1)
s_mask=np.array([memory[j][5] for j in range(length)]).reshape(-1,1)
_s=np.array([memory[j][4] for j in range(length)]).reshape(-1,STATE_NUM)
#Inférer la dernière valeur d'état
_, v=self.predict(_s)
#Calculez la récompense en tenant compte de l'avantage
R=(np.where(d_,0,1)*v.reshape(-1,1))*s_mask+R_
#Mise à jour des paramètres
feed_dict={self.input:s_, self.action:a_, self.reward:R}
SESS.run(self.minimize,feed_dict)
#Mise à jour du réseau
SESS.run(self.insert)
class ppo_agent:
def __init__(self,brain):
self.brain=brain
self.memory=[]
#Agir sans éléments aléatoires
def action(self,state):
prob,v = self.brain.predict(state)
return np.random.choice(ACTION_LIST,p = prob)
#Agir au hasard avec une certaine probabilité
def greedy_action(self,state):
if frame >= EPS_STEPS:
eps = EPS_END
else:
eps = EPS_START + frame* (EPS_END - EPS_START) / EPS_STEPS
if np.random.random() <= eps:
return np.random.choice(ACTION_LIST)
else:
return self.action(state)
#Traiter le résultat de la recherche et le PPO_Envoyer au cours de cerveau
def update(self,memory):
R = sum([memory[j][2] * (GAMMA ** j) for j in range(ADVANTAGE + 1)])
self.memory.append([memory[0][0], memory[0][1], R,memory[0][3], memory[0][4], GAMMA ** ADVANTAGE])
#Considérez l'avantage
for i in range(1, len(memory) - ADVANTAGE):
R = ((R - memory[i-1][2]) / GAMMA) + memory[i + ADVANTAGE][2] * (GAMMA ** (ADVANTAGE - 1))
self.memory.append([memory[i][0], memory[i][1], R,memory[i + ADVANTAGE][3], memory[i][4],GAMMA ** ADVANTAGE])
for i in range(ADVANTAGE - 1):
R = ((R - memory[len(memory) - ADVANTAGE + i][2]) / GAMMA)
self.memory.append([memory[i][0], memory[i][1], R, True, memory[i][4], GAMMA ** (ADVANTAGE - i)])
#ppo_Envoyer des données à la classe de cerveau pour mettre à jour
self.brain.update(self.memory)
self.memory = []
class Worker:
def __init__(self,thread_type,thread_name,brain):
self.thread_type = thread_type
self.name = thread_name
self.agent = ppo_agent(brain)
self.env = gym.make(ENV_NAME)
#Enregistrez la vidéo au moment du test
if self.thread_type == "test" and args.video:
self.env = wrappers.Monitor(self.env, VIDEO_DIR, force = True)
self.leaning_memory = np.zeros(10)
self.memory = []
self.total_trial = 0
def run_thread(self):
while True:
if self.thread_type == "train" and not isLearned:
self.env_run()
elif self.thread_type == "train" and isLearned:
sleep(3)
break
elif self.thread_type == "test" and not isLearned:
sleep(3)
elif self.thread_type == "test" and isLearned:
self.env_run()
break
def env_run(self):
global isLearned
global frame
self.total_trial += 1
step = 0
observation = self.env.reset()
while True:
step += 1
frame += 1
if self.thread_type == "train":
action=self.agent.greedy_action(observation)
elif self.thread_type == "test":
self.env.render()
sleep(0.01)
action=self.agent.action(observation)
next_observation,_,done,_ = self.env.step(action)
reward = 0
if done:
if step >= 199:
reward = 1 #Au moment du succès
else:
reward =- 1 #Au moment de l'échec
else:
#Quand ce n'est pas fini
reward+=0
#Enregistrer le résultat en mémoire
self.memory.append([observation,action,reward,done,next_observation])
observation = next_observation
if done:
break
#Calculez le score moyen de 10 fois
self.leaning_memory = np.hstack((self.leaning_memory[1:],step))
print("Thread:",self.name," Thread_trials:",self.total_trial," score:",step," mean_score:",self.leaning_memory.mean()," total_step:",frame)
#À la fin de l'apprentissage
if self.leaning_memory.mean() >= 199:
isLearned = True
sleep(3)
else:
#Mise à jour des paramètres
self.agent.update(self.memory)
self.memory = []
def main(args):
#Processus pour créer un fil
with tf.device("/cpu:0"):
brain = ppo_brain()
thread=[]
for i in range(WORKER_NUM):
thread_name = "local_thread"+str(i)
thread.append(Worker(thread_type = "train",thread_name = thread_name,brain = brain))
COORD = tf.train.Coordinator()
SESS.run(tf.global_variables_initializer())
saver = tf.train.Saver()
#Chargez le processus de formation précédent, faites-le après avoir défini le modèle
if args.load:
ckpt = tf.train.get_checkpoint_state(MODEL_DIR)
if ckpt:
saver.restore(SESS,MODEL_SAVE_PATH)
runnning_thread=[]
for worker in thread:
job = lambda: worker.run_thread()
t = threading.Thread(target=job)
t.start()
runnning_thread.append(t)
COORD.join(runnning_thread)
#Faites un test lorsque l'apprentissage est terminé
test = Worker(thread_type = "test",thread_name = "test_thread",brain=brain)
test.run_thread()
if args.save:
saver.save(SESS,MODEL_SAVE_PATH)
print("saved")
if __name__=="__main__":
SESS=tf.Session()
frame=0
isLearned=False
main(args)
print("end")
C'est pourquoi j'ai implémenté PPO cette fois. Il semble qu'une caractéristique majeure de PPO est qu'il produit des résultats élevés malgré son mécanisme simple. J'ai fait un peu de recherche sur TRPO, mais le mécanisme semblait assez difficile, donc j'omettrai une explication détaillée cette fois. Ensuite, je voudrais résumer la mise en œuvre de PPO dans l'espace d'action continue ou d'autres méthodes.
Recommended Posts