在 Keras DQN(强化学习)中实现 Dropout

问题描述 投票:0回答:1

首先我必须说我知道,Dropout 在强化学习(RL)中并不常见。在这里您可以阅读有关该主题的更多信息以及为什么它可能有意义:

https://towardsdatascience.com/generalization-in-deep-reinforcement-learning-a14a240b155b

我不确定如何在 Keras DQN 中实现 Dropout。通常(在监督学习中)Keras 负责打开/关闭 Dropout 层的任务,具体取决于您是在训练还是测试。就我而言(使用 RL 进行交易),我在 TRAIN 数据上进行训练,并在保留数据上进行测试,但它们并不相等。该模型确实过度拟合 TRAIN 数据并且不能很好地概括。我可以看到它过度拟合,只需查看训练结果 - 它“记忆”并完美地交换训练数据。这就是为什么我想使用 Dropout。

编辑:由于“krenrd”给出了一种不同的方法来实现该功能,我将在这里总结所有 4 种(对我来说)已知的方法:

方式1:

将 K.set_learning_phase() 与 K.set_learning_phase(0) 或 K.set_learning_phase(1) 一起使用

方式2:

https://stackoverflow.com/a/57439143/11122466 使用K(后端)功能:

func = K.function(model.inputs + [K.learning_phase()], model.outputs)

在 dropout 层处于活动状态的情况下运行模型,即learning_phase=1

preds = func(list_of_input_arrays + [1])

在 dropout 层处于非活动状态的情况下运行模型,即learning_phase=0

preds = func(list_of_input_arrays + [0])

方式3:

https://stackoverflow.com/a/57439143/11122466) “另一种方法是定义一个具有相同架构但不设置training=True的新模型,然后将权重从训练好的模型转移到这个新模型。”这对我来说非常慢,每个副本大约需要 1.5 毫秒。因为它很慢,我不喜欢这个解决方案。

方式4(由“krenrd”建议):

“用 model(x,training=True) 调用模型”这里我得到一个值错误:使用不是符号张量的输入调用 Layer INPUT。收到的类型:。 我的输入是一个 numpy 数组,我必须将其转换为张量。 如果您查看以下 DQN 的简单示例,修改/摘自:


https://github.com/keon/deep-q-learning/blob/master/dqn.py

class DQNAgent: def __init__(self, state_size, action_size): self.state_size = state_size self.action_size = action_size self.memory = deque(maxlen=2000) self.gamma = 0.95 # discount rate self.epsilon = 1.0 # exploration rate self.epsilon_min = 0.01 self.epsilon_decay = 0.995 self.learning_rate = 0.001 self.model = self._build_model() def _build_model(self): model = Sequential() model.add(Dense(24, input_dim=self.state_size, activation='relu')) model.add(Dense(24, activation='linear')) model.add(Dropout(0.05)) model.add(ReLU()) model.add(Dense(self.action_size, activation='linear')) model.compile(loss='mse',optimizer=Adam(lr=self.learning_rate)) return model def act(self, state): if np.random.rand() <= self.epsilon: return random.randrange(self.action_size) act_values = self.model.predict(state) return np.argmax(act_values[0]) # returns action def replay(self, batch_size): minibatch = random.sample(self.memory, batch_size) for state, action, reward, next_state, done in minibatch: target = reward if not done: target = (reward + self.gamma * np.amax(self.model.predict(next_state)[0])) target_f = self.model.predict(state) target_f[0][action] = target self.model.fit(state, target_f, epochs=1, verbose=0) if self.epsilon > self.epsilon_min: self.epsilon *= self.epsilon_decay

关于火车数据:

我们在replay()函数中调用predict()两次,一次用于“state”,一次用于“next_state”(创建我们的目标/标签),并且我们在act()中调用predict()。我们是否为 replay() 中的两个 Predict() 调用启用 Dropout?我们是否为 act() 中的 Predict() 调用启用 Dropout?

测试数据:

无探索,Epsilon = 0。仅使用 act() 来评估未见数据的性能。来自 TEST 的数据不保存在重放缓冲区中。我想我们这里不使用Dropout?

2 个问题:

    如何/在哪里插入 Dropout 层?在第一个密集层之前或之后和/或在激活层之前/之后?
  • 哪些predict()调用必须在training=True/learning_phase=1的情况下进行,哪些则不需要?
python keras reinforcement-learning
1个回答
0
投票
model.predict(x)

自动忽略仅训练层,例如推理中的 Dropout 或 BatchNormalization。如果您希望应用 dropout 进行预测,则必须使用

model(x,training=True)
。使用 Training=fasle 编写代码,
model(x,training=False)
model.predict(x)
执行相同的操作。
因此,对于训练中使用的所有 

model.predict()

,您必须将其替换为

model(x,training=True)
    

© www.soinside.com 2019 - 2024. All rights reserved.