Я изменил его так, чтобы агент должен был достичь нескольких целей , чтобы закончить эпизод. Из руководства вы можете видеть, что состояние окружающей среды - это словарь, содержащий координаты агента и цели; Я изменил тип пространства с Box на последовательность , что позволяет мне указать неопределенное количество наблюдений:
Код: Выделить всё
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>
Я взял код агента отсюда и адаптировал его к своей среде. Самое главное, я заменил метод Replay ()
Код: Выделить всё
FrozenLake
Код: Выделить всё
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
, показанное ниже, здесь - это код, используемый в функции Optimize () < /code> внутри агента, которая отвечает за обновление нейронных сетей.
Я добавил несколько комментариев, которые помогут вам (и мне) выяснить, что делают различные разделы.
Кроме того, вот некоторые разъяснения об остальной части кода в программе:
- 2 нейронные сети синхронизированы один раз на эпизод < /strong> < /li>
В моей среде, в отличие от Frozenlake, < Strong> нет никакого способа, которым агент может потерять: завершение означает победу, и усечение происходит во время обучения после достижения MAX_STEPS ; В этот момент он разрушает цикл и сбрасывает окружающую среду < /li>
Состояние моей среды представлено местоположением агента и местоположениями целей
< li> Тенсор, который передается в нейронную сеть, является комбинацией всех координат, например, С 2 целями: [0, 0, 2, 3, 1, 6] (первые 2 - координаты [x, y] агента, следующие 2 - первые цели, ...)
Когда цель собирается, его координаты в тензоре заменяются на -1 , поскольку я не могу изменить количество входных нейронов
Код: Выделить всё
def optimize(self, ever_won):
# checks if it has enough experience and has won at least once
if(self.batch_size>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)
Подробнее здесь: https://stackoverflow.com/questions/794 ... m-to-learn