【发布时间】:2021-03-18 14:48:24
【问题描述】:
首先我必须说我知道,Dropout 在强化学习 (RL) 中并不常见。您可以在此处阅读有关该主题的更多信息以及为什么它可能有意义:
https://towardsdatascience.com/generalization-in-deep-reinforcement-learning-a14a240b155b
我不确定如何在 Keras DQN 中实现 Dropout。通常(在监督学习中)Keras 负责打开/关闭 Dropout 层的任务,具体取决于您是在训练还是在测试。就我而言(与 RL 进行交易),我确实训练了 TRAIN 数据并测试了坚持数据,但它们并不相等。该模型确实过度拟合了 TRAIN 数据并且不能很好地概括。只需查看训练结果,我就可以看到它过度拟合 - 它记忆并完美地交易训练过的数据。这就是我想使用 Dropout 的原因。
编辑:由于“krenerd”提供了一种不同的方式来实现该功能,我将在这里总结所有 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(由“krenerd”建议):
“使用模型(x,training = True)调用模型”在这里我得到一个值错误:使用不是符号张量的输入调用了层 INPUT。收到的类型:
如果您查看以下 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() 两次,一次用于“状态”,一次用于“next_state”(创建我们的目标/标签),我们调用 predict () 在 act() 中。我们是否为 replay() 中的两个 predict() 调用启用 Dropout?我们是否为 act() 中的 predict() 调用启用 Dropout?
ON TEST DATA: 无探索,Epsilon = 0。仅使用 act() 来评估未见数据的性能。来自 TEST 的数据不保存在重放缓冲区中。我想我们这里不使用 Dropout?
2 个问题:
您将如何/在何处插入 Dropout 层?在第一个 Dense 层之前或之后和/或在 Activation 层之前/之后?
哪些 predict() 调用必须在 training = True / learning_phase = 1 的情况下进行,哪些不需要?
提前致谢!
【问题讨论】:
-
几个问题:你的状态空间和动作空间的维度?您在代码中的哪个位置更新目标估计器,如果是,多久更新一次?你的缓冲区有多大?此外,评估 DQN 代理的方法是提取策略并根据您认为更好的另一个策略评估该策略。
-
亲爱的 siddhant,感谢您的评论。抱歉,回答这个问题不需要“状态/动作空间和缓冲区大小的维度”吗?我不明白你为什么需要这些信息?没有“目标估计器”,我展示的示例是一个简单的 DQN。而且它不是“我的代码”,它是一个简单的示例来解释实现 DROPOUT 的问题。 “评估 DQN 代理的方法是提取策略并根据另一策略评估该策略”-> 我不明白,因为代理用于查找策略-因为我没有更好的策略?
-
嗨 Anna,实际上在 DQN 任务中使用 dropout 是没有意义的。 Dropout 本质上是为了避免过度拟合,在监督学习场景中也是如此。 DQN 的整个想法是让 Q-Learning 看起来更像监督学习。在 DQN 中,这是通过使用目标估计器和我问你的其他 DQN 参数来完成的。在 RL 的世界中,没有这样的训练和测试数据。您可以参考this answer 了解更多信息。
-
我对策略的意思是,您必须有另一个策略来比较您的 DQN 策略。让我们称之为您的“基准”政策。对于每个状态,您所采取的行动都可以根据基准策略评估您的 DQN 策略,并查看哪个策略可以为您提供更好的奖励。基本上它针对基准策略对 DQN 的策略评估。您的基准可以是 SARSA,甚至是离散状态和动作空间上的 Q-learning。
-
我们能否结束关于“辍学在这里是否有意义”的理论讨论?有一些迹象表明这种技术可能会成功,我只是想知道如何正确实施它。我很清楚,这个应用领域超出了正常规范。我知道解决这些问题更像是一门艺术而不是科学。我的目的是找出如何在技术上实现这一点,而不是讨论它在理论上是否有意义。它可能不起作用,但我想自己测试一下。然而,为了能够对其进行测试,它必须正确实施。
标签: python keras reinforcement-learning