DQN Learning Cartpole GrapePython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 DQN Learning Cartpole Grape

Сообщение Anonymous »

Я попытался сделать модель DQN для простой игры Cartpole, но после обучения ее для почти 3000 эпизодов она создает действительно странный график вознаграждения, и я не уверен, что это даже правильно тренироваться. Я посмотрел и пытался решить все эти проблемы, и это то, что я получил.:

Код: Выделить всё

import torch
from torch import nn
import torch.nn.functional as F

class DQN(nn.Module):
def __init__(self, state_dim, action_dim, hidden_dim=256):
super(DQN, self).__init__()

self.fc1 = nn.Linear(state_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, action_dim)

def forward(self, x: torch.Tensor) -> torch.Tensor:
x = F.relu(self.fc1(x))
return self.fc2(x)
< /code>
agent.py
:

Код: Выделить всё

import torch
import flappy_bird_gymnasium
import gymnasium
from dqn import DQN
from experience_replay import ReplayMemory
import itertools
import yaml
import random
from pathlib import Path
from torch import nn
import matplotlib.pyplot as plt
import argparse
import numpy as np

device = "gpu" if torch.cuda.is_available() else "cpu"

class Agent():

def __init__(self, hyperparameter_set):
with open(str(Path().resolve()) + "\\hyperparameters.yml", "r") as file:
all_hyperparameters_set = yaml.safe_load(file)
hyperparameters = all_hyperparameters_set[hyperparameter_set]

self.env_name = hyperparameters["env_id"]
self.replay_memory_size = hyperparameters['replay_memory_size']
self.mini_batch_size = hyperparameters['mini_batch_size']
self.epsilon_init = hyperparameters['epsilon_init']
self.decay_rate = hyperparameters['epsilon_decay']
self.epsilon_min = hyperparameters['epsilon_min']
self.network_sync_rate = hyperparameters["network_sync_rate"]
self.lr = hyperparameters["lr"]
self.discount_factor_g = hyperparameters["discount_factor_g"]
self.hidden_layers = hyperparameters["hidden_layers"]
self.stop_on_reward = hyperparameters["stop_on_reward"]

self.loss_fn = nn.MSELoss()
self.optimizer = None

self.LOG_FILE = str(Path().resolve()) + "\\logs.txt"
self.MODEL_FILE = str(Path().resolve()) + "\\models.pt"
self.GRAPH_FILE = str(Path().resolve()) + "\\graphs.png"

def run(self, is_training=False, render=False):
env = gymnasium.make(self.env_name, render_mode="human")

obs, _ = env.reset()

reward_per_episode = []

num_actions = env.action_space.n
num_states = env.observation_space.shape[0]

policy_dqn = DQN(num_states, num_actions, self.hidden_layers)

if is_training:
policy_dqn.train()
memory = ReplayMemory(self.replay_memory_size)

epsilon_history = []
epsilon = self.epsilon_init

self.optimizer = torch.optim.Adam(policy_dqn.parameters(), lr=self.lr)

target_dqn = DQN(num_states, num_actions, self.hidden_layers).to(device)
target_dqn.load_state_dict(policy_dqn.state_dict())

step_count = 0

best_reward = float('-inf')
else:
policy_dqn.eval()
policy_dqn.load_state_dict(torch.load(self.MODEL_FILE))

for episode in itertools.count():
state, _ = env.reset()
state = torch.tensor(state, dtype=torch.float, device=device)
episode_reward = 0.0
terminated = False

while (not terminated) and episode_reward < self.stop_on_reward:

if is_training and random.random() <  epsilon:
action = env.action_space.sample()
action = torch.tensor(action, dtype=torch.int64, device=device)
else:
with torch.no_grad():
action = torch.argmax(torch.squeeze(policy_dqn(torch.unsqueeze(state, 0)), 0))

new_state, reward, terminated, _, info = env.step(action.item())
new_state = torch.tensor(new_state, dtype=torch.float, device=device)

episode_reward += reward

reward = torch.tensor(reward, dtype=torch.float, device=device)

if is_training:
memory.append((state, action, new_state, reward, terminated))

step_count += 1

state = new_state

if is_training:
if episode_reward > best_reward:
log_message = f"New best reward {episode_reward: 0.1f}, {(episode_reward - best_reward):0.1f} increase from previous best"
with open(self.LOG_FILE, 'a') as file:
file.write(log_message + '\n')
torch.save(policy_dqn.state_dict(), Path(self.MODEL_FILE))
best_reward = episode_reward

if len(memory) > self.mini_batch_size:
mini_batch = memory.sample(self.mini_batch_size)

self.optimize(mini_batch, policy_dqn, target_dqn)

if step_count > self.network_sync_rate:
target_dqn.load_state_dict(policy_dqn.state_dict())
step_count = 0

epsilon = max(epsilon * self.decay_rate, self.epsilon_min)
epsilon_history.append(epsilon)
print(epsilon)
reward_per_episode.append(episode_reward)

def optimize(self, mini_batch, policy_dqn, target_dqn):
states, actions, new_states, rewards, terminations = zip(*mini_batch)

states = torch.stack(states)
actions = torch.stack(actions)
new_states = torch.stack(new_states)
rewards = torch.stack(rewards)
terminations = torch.tensor(terminations).float().to(device)

with torch.no_grad():
target_q = rewards + (1 - terminations) * self.discount_factor_g * target_dqn(new_states).max(dim=1)[0]

current_q = torch.squeeze(torch.gather(policy_dqn(states), 1, torch.unsqueeze(actions, 1)), 1)

loss = self.loss_fn(current_q, target_q)

self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()

if __name__ == "__main__":
parser = argparse.ArgumentParser(description=" Train or test model.")
parser.add_argument("hyperparameters", help='')
parser.add_argument("--train", help="Training mode", action="store_true")
args = parser.parse_args()

dql = Agent(hyperparameter_set=args.hyperparameters)

if args.train:
dql.run(is_training=True)
else:
dql.run(is_training=False, render=True)
< /code>
hyperparameters.yml
:
cartpole1:
env_id: CartPole-v1
replay_memory_size: 100000
mini_batch_size: 32
epsilon_init: 1
epsilon_decay: 0.9995
epsilon_min: 0.05
network_sync_rate: 10
lr: 0.001
discount_factor_g: 0.99
stop_on_reward: 100000
hidden_layers: 10
enable_double_dqn: True
< /code>
I've tried playing around with the hyperparameters (even copying the parameters from stable-baselines3), but it still does the same thing.
If it is normal, this training does seem excessively slow, so what would I need to do for quicker training? Increasing network_sync rate, decreasing the epsilon decay or something else. I'm really unsure.
After experimenting some more with the hyperparameters, I was able to get something much more sensible:
Изображение
.
I slowed down the epsilon decay, increased the learning rate and increased the number of hidden layers.

Подробнее здесь: https://stackoverflow.com/questions/790 ... ward-graph
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • График вознаграждений Cartpole для обучения DQN
    Anonymous » » в форуме Python
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Точка появления спортзала Cartpole
    Anonymous » » в форуме Python
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Точка появления спортзала Cartpole
    Anonymous » » в форуме Python
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Реализация PyTorch PPO для Cartpole-v0 застревает в локальной оптиме
    Anonymous » » в форуме Python
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Cartpole с Q-обучением ничего не изучать
    Anonymous » » в форуме Python
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»