Ich habe es so geändert, dass der Agent mehrere Ziele erreichen muss, um die Episode zu beenden. Aus dem Leitfaden können Sie sehen, dass der Umweltzustand ein Wörterbuch ist, das die Koordinaten des Agenten und des Ziels enthält. Ich habe den Speicherplatztyp von Box in Sequenz geändert, sodass ich eine unbestimmte Anzahl von Beobachtungen angeben kann:
Code: Select all
self.observation_space = gym.spaces.Dict(
{
"agent": gym.spaces.Box(0, size-1, shape=(2,), dtype=int),
"targets": gym.spaces.Sequence(
gym.spaces.Box(0, size-1, shape=(2,), dtype=int) # element type
)
})
< /code>
Ich habe den Code des Agenten von hier aus übernommen und an meine Umgebung angepasst. Am wichtigsten ist, dass ich die Replay ()
Code: Select all
FrozenLake
Code: Select all
class DQN(nn.Module):
def __init__(self, n_input, n_output):
super(DQN, self).__init__()
self.layer1 = nn.Linear(n_input, 128)
self.layer2 = nn.Linear(128, 128)
self.layer3 = nn.Linear(128, n_output)
def forward(self, x):
x = torch.relu(self.layer1(x))
x = torch.relu(self.layer2(x))
res = self.layer3(x)
return res
[*] Die 2 neuronalen Netzwerke sind einmal pro Episode synchronisiert < /strong> < /li>
In meiner Umgebung, im Gegensatz zu Frozenlake, < Strong> Es gibt keine Möglichkeit, dass der Agent verlieren kann: Kündigung bedeutet Sieg, und die Kürzung findet während der Trainingsschleife statt, nachdem Max_Steps ; An diesem Punkt bricht es den Zyklus und setzt die Umgebung zurück < /li>
Der Zustand meiner Umgebung wird durch den Agentenstandort und die Standorte der Ziele
< Der Tensor, der an das neuronale Netzwerk übergeben wird, ist die Kombination aller Koordinaten, z. Mit 2 Zielen: [0, 0, 2, 3, 1, 6] (die ersten 2 sind [x, y] Koordnen des Agenten, die nächsten 2 sind die ersten Ziele, ...) len(self.memory)) or (not ever_won):
return
mini_batch = self.memory.sample(self.batch_size) # takes a sample from its memory
current_q_list = []
target_q_list = []
for state, reward, action, new_state, terminated in mini_batch: # cycles the experiences
# if the experience led to a victory
if terminated:
target = torch.FloatTensor([5]) # I assign a higher priority to the action that made it win
# otherwise, the q value is calulated
else:
with torch.no_grad():
target = torch.FloatTensor(
reward + self.gamma * self.target_dqn(self.state_to_tensor(new_state)).max()
)
# get the q values from policy_dqn (main network)
current_q = self.policy_dqn(self.state_to_tensor(state))
current_q_list.append(current_q)
# q values from target_dqn
target_q = self.target_dqn(self.state_to_tensor(state))
# adjust the q value of the action
target_q[action] = target
target_q_list.append(target_q)
# Compute loss for the whole minibatch
loss = self.loss_fn(torch.stack(current_q_list), torch.stack(target_q_list))
# saving loss for later plotting
self.losses.append(loss.item()) # self.losses = list()
# Optimize the model
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
# epsilon decay
self.epsilon = max(self.epsilon_min, self.epsilon*self.epsilon_decay)
[/code]
Bearbeiten 12. Februar 2025: Ich habe versucht, den Verlust mit Matplotlib zu planen. Verlust wird in einer Liste in optimize () für Loop gespeichert (siehe die Zeile, die ich am Ende des obigen Codes hinzugefügt habe) . Wie Sie sehen, gibt es viele Spikes ; Ich denke, das ist aus dem, als während des Trainings das Modell immer wieder max_steps . net/gscwhf2q.png "/>