1

我正在阅读keras-rl /rl/agents/dqn.py中的 DQN 实现,并看到在该compile()步骤中基本上实例化了 3 个 keras 模型:

  • self.model:提供q值预测
  • self.trainable_model:与我们想要训练的损失函数相同self.model但具有我们想要训练的损失函数
  • self.target_model: 提供 q 个目标的目标模型,每k一步都使用来自的权重进行更新self.model

然而,唯一train_on_batch()被调用的模型是trainable_model- 这是我不明白的 - 这也更新了 的权重model

trainable_model在输出张量之一的定义中,y_pred引用来自 的输出model

        y_pred = self.model.output
        y_true = Input(name='y_true', shape=(self.nb_actions,))
        mask = Input(name='mask', shape=(self.nb_actions,))
        loss_out = Lambda(clipped_masked_error, output_shape=(1,), name='loss')([y_true, y_pred, mask])
        ins = [self.model.input] if type(self.model.input) is not list else self.model.input
        trainable_model = Model(inputs=ins + [y_true, mask], outputs=[loss_out, y_pred])

trainable_model.train_on_batch()被调用时,重都trainable_modelmodel变化。我很惊讶,因为即使两个模型引用了相同的输出张量对象(trainable_model.y_pred = model.output),实例化也trainable_model = Model(...) 应该实例化一组新的权重,不是吗?

谢谢您的帮助!

4

1 回答 1

1

这是一个小示例,表明当您keras.models.Model()使用来自另一个模型的输入和输出张量实例化一个新张量时,这两个模型的权重是共享的。他们不会重新初始化。

# keras version: 2.2.4
import numpy as np

from keras.models import Sequential, Model
from keras.layers import Dense, Input
from keras.optimizers import SGD

np.random.seed(123)

model1 = Sequential()
model1.add(Dense(1, input_dim=1, activation="linear", name="model1_dense1", weights=[np.array([[10]]),np.array([10])]))
model1.compile(optimizer=SGD(), loss="mse")

model2 = Model(inputs=model1.input, outputs=model1.output)
model2.compile(optimizer=SGD(), loss="mse")

x = np.random.normal(size=2000)
y = 2 * x + np.random.normal(size=2000)

print("model 1 weights", model1.get_weights())
print("model 2 weights", model2.get_weights())
model2.fit(x,y, epochs=3, batch_size=32)
print("model 1 weights", model1.get_weights())
print("model 2 weights", model2.get_weights())

绝对要记住的事情。对我来说不直观。

于 2019-05-17T08:32:06.637 回答