我有一组相当复杂的模型需要训练,我正在寻找一种方法来保存和加载模型优化器的状态。这些“训练模型”由几个其他“权重模型”的不同组合组成,其中一些模型共享权重,有些模型的权重根据训练器而被冻结等。这个例子过于复杂,无法分享,但简而言之,我无法在停止和开始训练时使用model.save('model_file.h5')
和keras.models.load_model('model_file.h5')
。
使用model.load_weights('weight_file.h5')
在训练完成后测试模型是可行的,但如果我试图使用这种方法继续训练模型,损失值远未能回到上次的位置。我读到这是因为这种方法没有保存优化器状态,这是有道理的。然而,我需要一种方法来保存和加载我的训练模型的优化器状态。看起来Keras曾经有一个model.optimizer.get_sate()
和model.optimizer.set_sate()
可以实现我想要的功能,但似乎现在不再适用(至少对Adam优化器来说是这样)。在当前的Keras中还有其他解决方案吗?
回答:
你可以从load_model
和save_model
函数中提取重要的代码行。
对于保存优化器状态,在save_model
中:
# 保存优化器权重.symbolic_weights = getattr(model.optimizer, 'weights')if symbolic_weights: optimizer_weights_group = f.create_group('optimizer_weights') weight_values = K.batch_get_value(symbolic_weights)
对于加载优化器状态,在load_model
中:
# 设置优化器权重.if 'optimizer_weights' in f: # 构建训练函数(以获取权重更新)。 if isinstance(model, Sequential): model.model._make_train_function() else: model._make_train_function() # ... try: model.optimizer.set_weights(optimizer_weight_values)
结合上述代码行,这里有一个示例:
- 首先训练模型5个周期。
X, y = np.random.rand(100, 50), np.random.randint(2, size=100)x = Input((50,))out = Dense(1, activation='sigmoid')(x)model = Model(x, out)model.compile(optimizer='adam', loss='binary_crossentropy')model.fit(X, y, epochs=5)Epoch 1/5100/100 [==============================] - 0s 4ms/step - loss: 0.7716Epoch 2/5100/100 [==============================] - 0s 64us/step - loss: 0.7678Epoch 3/5100/100 [==============================] - 0s 82us/step - loss: 0.7665Epoch 4/5100/100 [==============================] - 0s 56us/step - loss: 0.7647Epoch 5/5100/100 [==============================] - 0s 76us/step - loss: 0.7638
- 现在保存权重和优化器状态。
model.save_weights('weights.h5')symbolic_weights = getattr(model.optimizer, 'weights')weight_values = K.batch_get_value(symbolic_weights)with open('optimizer.pkl', 'wb') as f: pickle.dump(weight_values, f)
- 在另一个Python会话中重建模型,并加载权重。
x = Input((50,))out = Dense(1, activation='sigmoid')(x)model = Model(x, out)model.compile(optimizer='adam', loss='binary_crossentropy')model.load_weights('weights.h5')model._make_train_function()with open('optimizer.pkl', 'rb') as f: weight_values = pickle.load(f)model.optimizer.set_weights(weight_values)
- 继续模型训练。
model.fit(X, y, epochs=5)Epoch 1/5100/100 [==============================] - 0s 674us/step - loss: 0.7629Epoch 2/5100/100 [==============================] - 0s 49us/step - loss: 0.7617Epoch 3/5100/100 [==============================] - 0s 49us/step - loss: 0.7611Epoch 4/5100/100 [==============================] - 0s 55us/step - loss: 0.7601Epoch 5/5100/100 [==============================] - 0s 49us/step - loss: 0.7594