【问题标题】:Keras.fit_generator takes more time for epochKeras.fit_generator 需要更多时间进行 epoch
【发布时间】:2020-04-19 11:26:36
【问题描述】:

我正在使用 Keras 进行图像分类,我在训练样本中有 8k 图像(输入),在测试样本中有 2k 图像(输入),将 epoch 定义为 25 。我注意到 epoch 非常慢(第一次迭代大约需要一个小时)。

任何人都可以建议我如何克服这个问题,以及花费大量时间的原因是什么?

下面的代码..

PART-1
initialise neural network
from keras.models import Sequential

#package to perfom first layer , which is convolution , using 2d as it is for image , for video it will be 3d
from keras.layers import Convolution2D

#to perform max pooling on convolved layer
from keras.layers import MaxPool2D

#to convert the pool feature map into large feature vector, will be input for ANN
from keras.layers import Flatten 

#to add layeres on ANN
from keras.layers import Dense

#STEP -1
#Initializing CNN
classifier = Sequential()

#add convolution layer
classifier.add(Convolution2D(filters=32,kernel_size=(3,3),strides=(1, 1),input_shape= (64,64,3),activation='relu'))

#filters - Number of feature detecters that we are going to apply in image

#kernel_size - dimension of feature detector

#strides moving thru one unit at a time

#input shape - shape of the input image on which we are going to apply filter thru convolution opeation,
#we will have to covert the image into that shape in image preprocessing before feeding it into convolution
#channell 3 for rgb and 1 for bw , and  dimension of pixels

#activation - function we use to avoid non linearity in image

#STEP -2 

#add pooling
#this step will significantly reduce the size of feature map , and makes it easier for computation

classifier.add(MaxPool2D(pool_size=(2,2)))

#pool_size - factor by which to downscale


#STEP -3
#flattern the feature map

classifier.add(Flatten())

#STEP -4 
#hidden layer
classifier.add(Dense(units=128,activation='relu',kernel_initializer='uniform'))

#output layer
classifier.add(Dense(units=1,activation='sigmoid'))


#Compiling the CNN using stochastic gradient descend

classifier.compile(optimizer='adam',loss = 'binary_crossentropy',
                  metrics=['accuracy'])

#loss function should be categorical_crossentrophy if output is more than 2 class

#PART2 - Fitting CNN to image

#copied from keras documentation 

from keras.preprocessing.image import ImageDataGenerator

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(
        '/Users/arunramji/Downloads/Sourcefiles/CNN_Imageclassification/Convolutional_Neural_Networks/dataset/training_set',
        target_size=(64, 64),
        batch_size=32,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
    '/Users/arunramji/Downloads/Sourcefiles/CNN_Imageclassification/Convolutional_Neural_Networks/dataset/test_set',
        target_size=(64, 64),
        batch_size=32,
        class_mode='binary')

classifier.fit_generator(
        training_set,
        steps_per_epoch=8000,   #number of input (image)
        epochs=25,
        validation_data=test_set,
        validation_steps=2000)          # number of training sample

 classifier.fit(
                 training_set,
        steps_per_epoch=8000,   #number of input (image)
        epochs=25,
        validation_data=test_set,
        validation_steps=2000)

【问题讨论】:

  • flow_from_directory 很慢(至少我的经验),因为它首先从磁盘读取然后进行扩充然后开始训练,如果可以的话,您应该首先将它们加载到 RAM 中(将它们附加到数组中)然后使用它。如果您使用的是 CPU 而不是 GPU,那么迭代一个小时可能是可以的。
  • 请在下面更新我的答案

标签: python-3.x tensorflow machine-learning keras deep-learning


【解决方案1】:

您将steps_per_epoch 设置为错误的值(这就是它花费的时间比必要时间更长的原因):它没有设置为数据点的数量。 steps_per_epoch 应设置为数据集大小除以批量大小,训练集应为 8000/32 = 250,验证集应为 63。

【讨论】:

  • 我刚刚进行了编辑以便能够投票。谢谢。
【解决方案2】:

更新:

正如 Matias 在他的回答中指出的那样,您在 fit 方法中的 steps_per_epoch 参数设置导致每个时期的速度大幅下降。 来自fit_generator documentation

steps_per_epoch:
整数。步骤总数(样本批次) 在宣布一个纪元完成之前从生成器中产生,并且 开始下一个纪元。它通常应该等于 ceil(num_samples / batch_size) 序列可选:如果未指定, 将使用 len(generator) 作为多个步骤。

validation_steps:
仅当 validation_data 是生成器时才相关。 要从中产生的步骤总数(样本批次) 在每个 epoch 结束时停止之前的 validation_data 生成器。 它通常应该等于您的样本数 验证数据集除以批量大小。序列可选: 如果未指定,将使用 len(validation_data) 作为 步骤。

实际上 Keras 在处理这两个参数时存在不一致,因为如果您使用简单的 dataset 而不是 datagenerator 并设置像batch_size=batch_size, steps_per_epoch=num_samples这样的参数:

ValueError: Number of samples 60000 is less than samples required for specified batch_size 200 and steps 60000

但是当数据来自 datagenerator 时,它不会处理同样的问题,让您遇到当前问题。

我做了一个小示例代码来检查这些。

fit 方法与steps_per_epoch=num_samples

Number of samples: 60000
Number of samples per batch: 200
Train for 60000 steps, validate for 50 steps
Epoch 1/5
263/60000 [..............................] - ETA: 4:07:09 - loss: 0.2882 - accuracy: 0.9116

ETA(预计时间):4:07:09,

因为这是 60000 步,每批 200 个样本。


fitsteps_per_epoch=num_samples // batch_size 相同:

Number of samples: 60000
Number of samples per batch: 200
Train for 300 steps, validate for 50 steps
Epoch 1/5
28/300 [=>............................] - ETA: 1:15 - loss: 1.0946 - accuracy: 0.6446

预计到达时间1:15


解决方案:

steps_per_epoch=(training_set.shape[0] // batch_size)
validation_steps=(validation_set.shape[0] // batch_size)


其他可能的性能问题:

正如@SajanGohil 在他的评论train_datagen.flow_from_director 中所写,在实际训练过程之前执行一些任务,如文件操作预处理,有时需要更多时间作为训练 本身。

因此,为了避免这些额外时间,您可以在整个训练过程之前单独执行一次预处理任务。然后你可以在训练时使用这些预处理数据。

无论如何,具有大量图像的 CNN 是相当耗费时间和资源的任务,因此假设使用 GPU。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 2020-08-28
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多