我正在阅读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_model
和model
中改变权重。我很惊讶,因为即使两个模型都引用了相同的输出张量对象(trainable_model.y_pred = model.output
),trainable_model = Model(...)
的实例化也应该实例化一组新的权重,不是吗?
感谢您的帮助!
答案 0 :(得分:0)
这是一个小示例,显示了当您使用另一个模型的输入和输出张量实例化新的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())
绝对要记住一些事情。对我来说不直观。