【问题标题】:Training a binary CNN (Keras) - Slow training time训练二进制 CNN (Keras) - 训练时间慢
【发布时间】:2019-02-18 06:28:04
【问题描述】:

我正在 keras 中训练一个二元 CNN,用于对情绪(表达)的极性进行分类,例如Smiling/Not_smiling。这是我的代码。我在多 GPU 机器上训练这个,但对这个训练需要多长时间感到惊讶。每个类二进制模型需要 5-6 个小时。这是正常/预期的吗?

我之前训练了一个结合所有类的multi-class 模型,总共花了大约 4 个小时。

注意:每个 pos/neg 类包含约 5000-10000 张图像。

我这样做对吗?是否需要此培训时间?

class_names = ["smiling","frowning","surprised","sad"]
## set vars!
for cname in class_names:
    print("[+] training: ",model_name,cname)

    dp_path_train = './emotion_data/{0}/train/{1}'.format(model_name,cname)
    dp_path_val = './emotion_data/{0}/val/{1}'.format(model_name,cname)
    dir_checkpoint = './models'
    G = 2 # no. of gpus to use

    batch_size = 32 * G
    step_size = 1000//G
    print("[*] batch size & step size: ", batch_size,step_size)

    model = Sequential()
    model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(BatchNormalization())
    model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(BatchNormalization())
    model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(BatchNormalization())
    model.add(Conv2D(96, kernel_size=(3,3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(BatchNormalization())
    model.add(Conv2D(32, kernel_size=(3,3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(BatchNormalization())
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.3))
    model.add(Dense(1, activation = 'sigmoid'))
    model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

    train_datagen = ImageDataGenerator(rescale = 1./255,
        shear_range = 0.2,
        zoom_range = 0.2,
        horizontal_flip = True)
    test_datagen = ImageDataGenerator(rescale = 1./255)

    training_set = train_datagen.flow_from_directory(dp_path_train,
        target_size = (224, 224),
        batch_size = batch_size,
        class_mode = 'binary')

    test_set = test_datagen.flow_from_directory(dp_path_val,
        target_size = (224, 224),
        batch_size = batch_size,
        class_mode = 'binary')

    model.fit_generator(training_set,
        steps_per_epoch = step_size,
        epochs = 50,
        validation_data = test_set,
        validation_steps = 2000)

    print("[+] saving model: ",model_name,cname)
    model.save("./models2/{0}_{1}.hdf5".format(model_name,cname))

【问题讨论】:

  • 您是否验证过它在 GPU 上运行?另外,我猜BatchNormalization 层正在减慢速度。您可以尝试将它们全部评论出来,然后看看速度如何?
  • 谢谢,我使用了 nvidia-smi,它显示了正在使用的 gpus。我会尝试删除BatchNormaliztion 看看效果如何
  • BatchNormalization 减慢速度是个好主意。你在使用多个 GPU 吗?而且您似乎有 2000 个验证步骤。对于超过 50 个 epoch 的相同批量大小,这似乎相当多。您可以尝试减少它以查看是否可以进一步加快速度吗?
  • 好的,我减少了批量标准化步骤,虽然训练时间有点不足,但它确实加快了速度。希望这会有所帮助。 @IanQuah 你介意张贴作为答案让我接受吗?
  • 谢谢!如果您提出一个新问题并描述您的网络,我相信 SO 的人们会愿意参与讨论如何加快速度

标签: python tensorflow keras


【解决方案1】:

删除所有BatchNormalization 层应该有助于加快速度,或者您可以在网络架构层之间减少使用它的频率

【讨论】: