与pytorch(Adam优化器)配合使用但与keras/Tensorflow(Adam优化器)不配合使用的Deep Sarsa算法出现问题

mwkjh3gx  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(342)

我有一个深Sarsa算法,它在月球登陆器V2的Pytorch上工作得很好,我会和Keras/Tensorflow一起使用。它使用64大小的小批量,在每集使用128次来训练。
这是我得到的结果。正如你所看到的,它在Pytorch中工作得很好,但在Keras / Tensorflow中就不行了...所以我认为我没有正确地实现Keras/Tensorflow的训练函数(代码如下)。
在Keras中,损失似乎是振荡的,因为ε值从早到慢,但在Pytorch中,它的作用非常大...
你看到的东西,可以解释为什么它不工作在Keras/Tensorflow请?非常感谢您的帮助和任何想法,可以帮助我...

网络信息:

它使用Adam优化器,并有两层网络:256和128,每个上具有RELU:

class Q_Network(nn.Module):
def __init__(self, state_dim , action_dim):
    super(Q_Network, self).__init__()
    self.x_layer = nn.Linear(state_dim, 256)
    self.h_layer = nn.Linear(256, 128)
    self.y_layer = nn.Linear(128, action_dim)
    print(self.x_layer)

def forward(self, state):
    xh = F.relu(self.x_layer(state))
    hh = F.relu(self.h_layer(xh))
    state_action_values = self.y_layer(hh)
    return state_action_values

对于角动量/tensorflow ,我使用以下方法:

def CreationModele(dimension): 
  entree_etat = keras.layers.Input(shape=(dimension))

  sortie = keras.layers.Dense(units=256, activation='relu')(entree_etat)
  sortie = keras.layers.Dense(units=128, activation='relu')(sortie)
  sortie = keras.layers.Dense(units=4)(sortie)

  modele = keras.Model(inputs=entree_etat,outputs=sortie)
  return modele

培训代码

在Pytorch中,培训由以下人员完成:

def update_Sarsa_Network(self, state, next_state, action, next_action, reward, ends):

    actions_values = torch.gather(self.qnet(state), dim=1, index=action.long())

    next_actions_values = torch.gather(self.qnet(next_state), dim=1, index=next_action.long())

    next_actions_values = reward + (1.0 - ends) * (self.discount_factor * next_actions_values)

    q_network_loss = self.MSELoss_function(actions_values, next_actions_values.detach())
    self.qnet_optim.zero_grad()
    q_network_loss.backward()
    self.qnet_optim.step()
    return q_network_loss

在Keras/Tensorflow中,作者为:

mse = keras.losses.MeanSquaredError(
    reduction=keras.losses.Reduction.SUM)

@tf.function
def train(model, batch_next_states_tensor, batch_next_actions_tensor, batch_reward_tensor, batch_end_tensor, batch_states_tensor, batch_actions_tensor, optimizer, gamma):
  with tf.GradientTape() as tape:
    # EStimation des valeurs des actions courantes
    actions_values = model(batch_states_tensor)                                                          # (mini_batch_size,4)
    actions_values = tf.linalg.diag_part(tf.gather(actions_values,batch_actions_tensor,axis=1))         # (mini_batch_size,)
    actions_values = tf.expand_dims(actions_values,-1)                                                  # (mini_batch_size,1)

    # EStimation des valeurs des actions suivantes
    next_actions_values = model(batch_next_states_tensor)                                                          # (mini_batch_size,4)
    next_actions_values = tf.linalg.diag_part(tf.gather(next_actions_values,batch_next_actions_tensor,axis=1))   # (mini_batch_size,)
    cibles = batch_reward_tensor + (1.0 - batch_end_tensor)*gamma*tf.expand_dims(next_actions_values,-1)         # (mini_batch_size,1)

    error = mse(cibles, actions_values)

  grads = tape.gradient(error, model.trainable_variables)
  optimizer.apply_gradients(zip(grads, model.trainable_variables))

  return error

错误函数和优化程序代码

在Pytorch和Tensorflow中,优化器是Adam,lr=0.001。在Pytorch中:

def __init__(self, state_dim, action_dim):
    self.qnet = Q_Network(state_dim, action_dim)
    self.qnet_optim = torch.optim.Adam(self.qnet.parameters(), lr=0.001)
    self.discount_factor = 0.99
    self.MSELoss_function = nn.MSELoss(reduction='sum')
    self.replay_buffer = ReplayBuffer()
    pass

在Keras /tensorflow 中:

alpha = 1e-3

# Initialise le modèle

modele_Keras = CreationModele(8)

optimiseur_Keras = keras.optimizers.Adam(learning_rate=alpha)
nhjlsmyf

nhjlsmyf1#

最后,我找到了一个解决方案,通过使用两个模型将目标值和操作值去相关,其中一个模型定期更新,用于目标值计算。
我使用一个模型来估计ε-贪婪行为并计算Q(s,a)值,以及使用一个固定模型(但周期性地随先前模型的权重更新)来计算目标r+gamma*Q(s ′,a ′)。
以下是我的结果:

相关问题