【问题标题】:Training of keras model get's slower after each repetition每次重复后,keras 模型的训练都会变慢
【发布时间】:2018-01-29 11:21:00
【问题描述】:

我正在编写一些代码来优化神经网络架构,因此有一个 python 函数create_nn(parms) 可以创建和初始化一个 keras 模型。 但是,我遇到的问题是,在较少的迭代之后,模型的训练时间比平时要长得多(最初一个时期需要 10 秒,然后在大约第 14 个模型之后(每个模型训练 20 个时期)需要 60 秒/时代)。 我知道这不是因为不断发展的架构,因为如果我重新启动脚本并开始它是否结束,它就会恢复正常速度。

我正在跑步

from keras import backend as K

然后是一个

K.clear_session()

在训练任何给定的新模型之后。

一些额外的细节:

  • 对于前 12 个模型,每个 epoch 的训练时间大致保持在 10 秒/epoch。然后在第 13 个模型每个 epoch 的训练时间稳步攀升至 60 秒。然后每个 epoch 的训练时间徘徊在 60 秒/epoch 左右。

  • 我正在以 Tensorflow 作为后端运行 keras

  • 我正在使用 Amazon EC2 t2.xlarge 实例

  • 有大量可用 RAM(7GB 可用,数据集大小为 5GB)

我已经删除了一堆层和参数,但基本上create_nn 看起来像:

def create_nn(features, timesteps, number_of_filters):
    inputs = Input(shape = (timesteps, features))
    x = GaussianNoise(stddev=0.005)(inputs)
    #Layer 1.1
    x = Convolution1D(number_of_filters, 3, padding='valid')(x)
    x = Activation('relu')(x)
    x = Flatten()(x)
    x = Dense(10)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Dropout(0.5)(x)
    # Output layer
    outputs = Dense(1, activation='sigmoid')(x)
    model = Model(inputs=inputs, outputs=outputs)

    # Compile and Return
    model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    print('CNN model built succesfully.')
    return model

请注意,虽然 Sequential 模型可以在这个虚拟示例中工作,但实际用例需要功能 API。

我该如何解决这个问题?

【问题讨论】:

  • 需要更多信息来回答这个问题,如果您使用自定义函数来构建模型,那么您应该检查您的代码并确保您没有创建模型副本或无意中每次构建新层时添加一堆层。
  • @Dimesio 感谢您的评论。我已经用有关create_nn 函数的更多详细信息更新了这个问题。调用K.clear_session() 时不会清除图层等,还是我弄错了K.clear_session() 的作用?
  • @E.O.我不太确定 K.clear_session() 做了什么,但由于您使用的是 TensorFlow,也许您还需要使用 tf.reset_default_graph() 重置底层图形?
  • 我有一个类似的问题 - 你找到解决办法了吗?
  • 如果您编写了自己的数据加载器,问题可能就在那里。我曾经在自定义数据加载器中遇到过一个错误,它不断返回越来越大的批次,因此运行时间越来越长。

标签: python tensorflow keras


【解决方案1】:

为什么每次跑步后我的训练时间都会增加?

简短回答:您需要在创建每个新模型之前使用tf.keras.backend.clear_session()

这个问题似乎只发生在急切执行关闭时。

好的,让我们在有和没有 clear_session 的情况下运行一个实验。 make_model 的代码在此响应的末尾。

首先,我们来看看使用 clear session 时的训练时间。我们将运行这个实验 10 次并打印结果

使用 tf.keras.backend.clear_session()

non_seq_time = [ make_model(clear_session=True) for _ in range(10)]

使用 clear_session=True

non sequential
Elapse =  1.06039
Elapse =  1.20795
Elapse =  1.04357
Elapse =  1.03374
Elapse =  1.02445
Elapse =  1.00673
Elapse =  1.01712
Elapse =    1.021
Elapse =  1.17026
Elapse =  1.04961

如您所见,训练时间基本保持不变

现在让我们在不使用 clear session 的情况下重新运行实验并查看训练时间

不要使用 tf.keras.backend.clear_session()

non_seq_time = [ make_model(clear_session=False) for _ in range(10)]

使用 clear_session=False

non sequential
Elapse =  1.10954
Elapse =  1.13042
Elapse =  1.12863
Elapse =   1.1772
Elapse =   1.2013
Elapse =  1.31054
Elapse =  1.27734
Elapse =  1.32465
Elapse =  1.32387
Elapse =  1.33252

如您所见,训练时间在没有 clear_session 的情况下会增加

完整代码示例

# Training time increases - and how to fix it

# Setup and imports

# %tensorflow_version 2.x

import tensorflow as tf
import tensorflow.keras.layers as layers
import tensorflow.keras.models as models
from time import time

# if you comment this out, the problem doesn't happen
# it only happens when eager execution is disabled !!
tf.compat.v1.disable_eager_execution()


(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()


# Let's build that network
def make_model(activation="relu", hidden=2, units=100, clear_session=False):
    # -----------------------------------
    # .     HERE WE CAN TOGGLE CLEAR SESSION
    # -----------------------------------
    if clear_session:
        tf.keras.backend.clear_session()

    start = time()
    inputs = layers.Input(shape=[784])
    x = inputs

    for num in range(hidden) :
        x = layers.Dense(units=units, activation=activation)(x)

    outputs = layers.Dense(units=10, activation="softmax")(x)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

    results = model.fit(x_train, y_train, validation_data=(x_test, y_test), batch_size=200, verbose=0)
    elapse = time()-start
    print(f"Elapse = {elapse:8.6}")
    return elapse

# Let's try it out and time it

# prime it first
make_model()

print("Use clear session")
non_seq_time = [ make_model(clear_session=True) for _ in range(10)]

print("Don't use clear session")
non_seq_time = [ make_model(clear_session=False) for _ in range(10)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 2019-11-25
    • 1970-01-01
    • 2019-08-27
    • 2017-09-28
    • 2018-04-15
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多