【问题标题】:Tensorflow/Keras stops using gpu after recompiling model重新编译模型后,Tensorflow/Keras 停止使用 gpu
【发布时间】:2020-06-12 13:42:18
【问题描述】:

我正在尝试使用 Keras/TensorFlow 2.0 分两个阶段训练我的顺序模型 (RNN->GRU->Dense),两个阶段的损失权重不同。要更改损失权重,我需要在两个阶段之间重新编译模型。我的问题是重新编译后训练变得慢得多,除了不再使用 GPU 之外,我看不到其他解释。以下是相关代码:

# Build model
input_ = tf.keras.layers.Input(shape=(None, num_features))
masking = tf.keras.layers.Masking(mask_value=0.)(input_)
rnn = tf.keras.layers.SimpleRNN(24, return_sequences=True, name="rnn")(masking)
gru = tf.keras.layers.GRU(16, return_sequences=True, name="gru")(rnn)
dense1 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name="dense1")(gru)
dense2 = tf.keras.layers.Dense(1, activation=tf.math.sigmoid, name="dense2")(gru)
model = tf.keras.Model(inputs=[input_], outputs=[dense1, dense2])

# Learn reate scheduler: Reduce learn reate by factor 0.5 when no progress after 7 epochs
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='loss', factor=0.5, patience=7, min_lr=0.0001)

# Compile and fit, phase 1
optimizer = tf.keras.optimizers.Adam(lr=0.01, clipvalue=0.1)
model.compile(optimizer=optimizer, loss=['categorical_crossentropy', 'binary_crossentropy'], sample_weight_mode="temporal", loss_weights=[0.7, 0.3], metrics=['accuracy'])
model.fit_generator(train_generator(), steps_per_epoch=BATCHES_PER_EPOCH, epochs=375, callbacks=[reduce_lr])

# Recompile and fit, phase 2
optimizer.lr = 0.001
model.compile(optimizer=optimizer, loss=['categorical_crossentropy', 'binary_crossentropy'], sample_weight_mode="temporal", loss_weights=[0.99, 0.01], metrics=['accuracy'])
model.fit_generator(train_generator(), steps_per_epoch=BATCHES_PER_EPOCH, epochs=125, callbacks=[reduce_lr])

第 1 阶段结束和第 2 阶段开始时的输出显示了训练如何变得慢了大约 5 倍:

Epoch 374/375
4/4 [==============================] - 5s 1s/step - loss: 0.1177 - dense1_loss: 0.1479 - dense2_loss: 0.0473 - dense1_accuracy: 0.9249 - dense2_accuracy: 0.9784
Epoch 375/375
4/4 [==============================] - 5s 1s/step - loss: 0.1177 - dense1_loss: 0.1479 - dense2_loss: 0.0473 - dense1_accuracy: 0.9249 - dense2_accuracy: 0.9784
Epoch 1/125
4/4 [==============================] - 27s 7s/step - loss: 0.1494 - dense1_loss: 0.1504 - dense2_loss: 0.0478 - dense1_accuracy: 0.9225 - dense2_accuracy: 0.9779
Epoch 2/125
4/4 [==============================] - 24s 6s/step - loss: 0.1603 - dense1_loss: 0.1614 - dense2_loss: 0.0545 - dense1_accuracy: 0.9201 - dense2_accuracy: 0.9750

可能的解释是什么?模型在重新编译时是否以某种方式重新组织,因此 TensorFlow 无法再将操作映射到 GPU?

(我尝试使用 model.loss_weights = [0.99, 0.01] 更改损失权重,但这不起作用 - 需要重新编译。)

【问题讨论】:

    标签: tensorflow tensorflow2.0 tf.keras


    【解决方案1】:

    试试这个:

    构建两个具有相同层(权重)的独立模型:

    input_ = tf.keras.layers.Input(shape=(None, num_features))
    masking = tf.keras.layers.Masking(mask_value=0.)(input_)
    rnn = tf.keras.layers.SimpleRNN(24, return_sequences=True, name="rnn")(masking)
    gru = tf.keras.layers.GRU(16, return_sequences=True, name="gru")(rnn)
    dense1 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name="dense1")(gru)
    dense2 = tf.keras.layers.Dense(1, activation=tf.math.sigmoid, name="dense2")(gru)
    
    model1 = tf.keras.Model(inputs=[input_], outputs=[dense1, dense2])
    model2 = tf.keras.Model(inputs=[input_], outputs=[dense1, dense2])
    

    使用不同的优化器实例分别编译和拟合每一个:

    optimizer1 = tf.keras.optimizers.Adam(lr=0.01, clipvalue=0.1)
    optimizer2 = tf.keras.optimizers.Adam(lr=0.001, clipvalue=0.1)
    
    model1.compile(optimizer=optimizer1, loss=['categorical_crossentropy', 'binary_crossentropy'], sample_weight_mode="temporal", loss_weights=[0.7, 0.3], metrics=['accuracy'])
    model2.compile(optimizer=optimizer2, loss=['categorical_crossentropy', 'binary_crossentropy'], sample_weight_mode="temporal", loss_weights=[0.99, 0.01], metrics=['accuracy'])
    
    model1.fit_generator(train_generator(), steps_per_epoch=BATCHES_PER_EPOCH, epochs=375, callbacks=[reduce_lr])
    model2.fit_generator(train_generator(), steps_per_epoch=BATCHES_PER_EPOCH, epochs=125, callbacks=[reduce_lr])
    

    【讨论】:

    • 谢谢,但这不是我想要的。我真的想要一个模型首先使用一组损失权重进行训练,然后从该点继续使用相同的模型并使用另一组损失权重。您可能想知道为什么——说来话长,但简而言之,这是一个实验,我想看看在第一阶段强制训练识别次要输出是否会导致它走向更好的最终解决方案,尽管最终解决方案实际上只需要识别主要输出。情况似乎如此,但由于未知原因,第二阶段的训练非常缓慢。
    • 在代码中,模型之间的权重指的是相同的变量。这些模型的相同之处在于它们基本上引用了相同的内存位置。
    • 您也可以验证这一点。训练 model1,然后使用 model1.evaluate() 和 model2.evaluate()。他们会在相同的数据上给出相同的结果。
    • 哦,我明白了,感谢您的澄清!好的,我试过了,但不幸的是它没有帮助 - 拟合模型 2 仍然比模型 1 慢得多。即使为两者重复使用相同的优化器也无济于事。
    猜你喜欢
    • 2021-07-07
    • 2020-06-13
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 2020-07-31
    • 2018-08-16
    • 2018-02-15
    • 2021-11-28
    相关资源
    最近更新 更多