#neural-network #gradient #pytorch #reinforcement-learning #backpropagation
#нейронная сеть #градиент #pytorch #подкрепление-обучение #обратное распространение
Вопрос:
Мне нужно суммировать градиенты на каждой итерации, а затем передавать эти градиенты другому процессу для воспроизведения изученной сети.
Ключевой код выглядит следующим образом ниже. Способ 1:
class Net(nn.Module):
def __init__(self, state_dim, action_dim, max_action):
super(Actor, self).__init__()
self.l1 = nn.Linear(state_dim, 40)
self.l2 = nn.Linear(40, 30)
self.l3 = nn.Linear(30, action_dim)
self.max_action = max_action
def forward(self, x):
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = self.max_action * torch.tanh(self.l3(x))
return x
def train(batches,state_dim, action_dim, max_action):
actor = Net(state_dim, action_dim, max_action)
critic = Net(state_dim, action_dim, max_action)
for i in range(1000):
...
#Compute critic loss
critic_loss = F.mse_loss(current_Q, target_Q)
# Optimize the critic
critic_optimizer.zero_grad()
critic_loss.backward()
critic_optimizer.step()
# Compute actor loss
actor_loss = -critic(state,actor(state)).mean()
# Optimize the actor
actor_optimizer.zero_grad()
actor_loss.backward()
actor_optimizer.step()
return net
...
net = train(batches,state_dim, action_dim, max_action)
Способ 2:
...
def train(batches,state_dim, action_dim, max_action):
net = Net(state_dim, action_dim, max_action)
for i in range(1000):
...
# Optimize the critic
critic_optimizer.zero_grad()
critic_loss.backward()
sum_grads(critic) # sum the gradient in critic
for g,p in zip(sum_grads,net.parameters()):
p.grad = torch.from_numpy(g)
net_optimizer.step()
return net
...
net = train(batches,state_dim, action_dim, max_action)
Я надеюсь, что метод 1 и метод два могут изучать одни и те же параметры сети, но этого не произошло. Итак, мой вопрос в том, почему? И как заставить это работать? Заранее благодарю вас.
Комментарии:
1. Пожалуйста, опубликуйте код или алгоритм, что-нибудь, что поможет нам помогать вам.
2. Привет, я опубликовал некоторый код. Спасибо.
Ответ №1:
Нет необходимости явно суммировать градации, вам просто нужно обнулить градацию один раз, применить вперед и назад, но без шага в цикле и вызвать step один раз
model.zero_grad() # Reset gradients tensors
for i, (inputs, labels) in enumerate(training_set):
predictions = model(inputs) # Forward pass
loss = loss_function(predictions, labels) # Compute loss function
loss = loss / accumulation_steps # Normalize our loss (if averaged)
loss.backward() # Backward pass
if (i 1) % accumulation_steps == 0: # Wait for several backward steps
optimizer.step() # Now we can do an optimizer step
model.zero_grad() # Reset gradients tensors
Комментарии:
1. Спасибо. Однако на каждой итерации я должен обновлять сетевой параметр (архитектура актер-критик, используйте обновленный критик, чтобы помочь обновить параметр актер). Итак, как справиться с этой ситуацией?
2. Я не понимаю. Если вы хотите накопить свои оценки для нескольких минибатчей и применить их вместе (потому что у вас возникают проблемы с памятью при больших размерах пакетов), вы можете использовать мой код. Это именно то, что вы пытаетесь сделать в своем втором методе. В противном случае ваш первый метод верен и он работает.
3. Спасибо. Я отредактировал пример кода. В процессе обучения сначала обновите сеть критиков, а затем используйте эту сеть для обучения сети-исполнителя. Итак, кажется, необходимо обновлять параметры на каждой итерации.