Keras CNN模型训练时间

时间:2018-12-18 01:01:21

标签: machine-learning keras deep-learning

我创建了一个二进制图像分类器,当我运行代码时,我得到的训练时间为1到2个小时。我该如何减少呢? 这是我的代码:

from keras.layers import Conv2D, MaxPooling2D, Input
from keras.layers import Input, Dense, Flatten
from keras.models import Model

num_classes = 2 
# This returns a tensor
inputs = Input(shape=(150,150,3))

x = Conv2D(16,(1,1), padding = 'same', activation = 'relu',)(inputs)
x = Conv2D(16,(3,3), padding = 'same', activation = 'relu')(x)
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)

x = Conv2D(32,(1,1), padding = 'same', activation = 'relu',)(inputs)
x = Conv2D(32,(3,3), padding = 'same', activation = 'relu')(x)
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)

x = Conv2D(64,(1,1), padding = 'same', activation = 'relu',)(inputs)
x = Conv2D(64,(3,3), padding = 'same', activation = 'relu')(x)
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)

x = Conv2D(128,(1,1), padding = 'same', activation = 'relu',)(inputs)
x = Conv2D(128,(3,3), padding = 'same', activation = 'relu')(x)
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)


x = Flatten()(inputs)
predictions = Dense(num_classes, activation='sigmoid')(x)

# This creates a model that includes
# the Input layer and three Dense layers
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
          loss='sparse_categorical_crossentropy', #https://github.com/keras- 
team/keras/issues/5034
          #loss='binary_crossentropy',
          metrics=['accuracy'])

我使用ImageDataGenerator预处理图像:

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

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    "/content/drive/apagdata/train",
    target_size=(150,150),
    batch_size=32,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    "/content/drive/apagdata/test",
    target_size=(150,150),
    batch_size=32,
    class_mode='binary')

model.fit_generator(
    train_generator,
    steps_per_epoch=2000,
    epochs=50,
    validation_data=validation_generator,
    validation_steps=800)
model.save_weights('first_try.h5')

我的数据集总共只有169张图像。原因是我要在对所有数据实施模型之前尝试构建基本模型。

2 个答案:

答案 0 :(得分:0)

请参阅下面的更新

除了使用GPU以外,还有一些可能的速度改进:

  1. 如果图像是二进制图像,则您的输入可以是Input(shape=(150,150))而不是3通道

  2. 与其使用16 -- 32 -- 64 -- 128转换过滤器,不如尝试像8 -- 16 -- 16 -- 32那样,检查在什么时候停止获得更高的验证准确性

  3. 您实际上可以完全丢弃1 x 1卷积。 1 x 1卷积通常在3 x 35 x 5卷积之前使用,以降低维数。在您的情况下,可能不需要。即使您想使用它,1 x 1卷积也应输出较少的通道数,以便3 x 3卷积可以在较少的通道上操作并输出更多的通道,从而使整个过程更快。例如,150 x 150 x 256输入-> 3 x 3 x 256卷积比150 x 150 x 256输入-> 1 x 1 x 64卷积-> 3 x 3 x 256卷积慢。了解如何将256-D输出首先映射到64-D,然后再映射到256-D。您没有这样做

  4. 您可以通过在最大池操作中将步幅提高到(2,2)来进一步对输出进行二次采样,至少在最后三个最大池层中如此

  5. 与速度无关,但是如果您将categorical_crossentropy与一个热门标签一起使用,则可能要使用softmax而不是sigmoid(除非在多标签)

在GPU上,我认为这应该不会超过10分钟,因为您只有170张图像。

更新

实际上,我并没有对体系结构本身的正确性给予太多关注,但是您的评论使我产生了其他想法。

您的网络基本上是这样的:

inputs = Input(shape=(150,150,3))
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)
x = Flatten()(inputs)
predictions = Dense(num_classes, activation='sigmoid')(x)

这是因为没有将第二次卷积的输出作为最大池的输入,而是将其丢弃并再次对输入执行最大池。看到这个:

x = Conv2D(16,(1,1), padding = 'same', activation = 'relu',)(inputs)
x = Conv2D(16,(3,3), padding = 'same', activation = 'relu')(x)
x = MaxPooling2D((3,3), strides = (1,1), padding = 'same')(inputs)  # should be x here instead of inputs

除此之外,@ Alaroff的答案是主要原因。

答案 1 :(得分:0)

您正在将fit_generatorbatch_size=32配合使用并指定steps_per_epoch=2000,这意味着最终每个时期总共向网络馈送64000张图像。您通常会使用每个时间段使用一个唯一的图像,例如steps_per_epoch = no_train_samples // batch_size + 1(同样适用于validation_steps)。但是,假设您只有169个训练样本,则可能需要执行大量步骤,以最大程度地减少Keras在各个时期之间的训练阶段和验证阶段之间切换时的开销。 / p>

考虑在训练之前对训练图像进行降采样(无论如何,您的输入均为150x150像素),以节省解压缩开销(尤其是如果您要处理的PNG文件较大)。

此外,在Colab上,您并不总是被授予整个GPU的权限,而是可能与其他用户共享。这个事实也可能会影响整体性能。

最后,请注意从何处传输数据。是您安装的Google驱动器吗? I / O的低带宽/高延迟也可能是Colab的问题