fit_generator训练的精度为0

时间:2018-12-06 15:25:39

标签: python tensorflow machine-learning keras classification

我正在尝试使用TensorFlow,Keras和ImageDataGenerator从头开始构建模型,但是并没有按预期进行。我仅使用生成器来加载图像,因此不使用数据扩充。有两个包含训练和测试数据的文件夹,每个文件夹有36个子文件夹,其中装有图像。我得到以下输出:

Using TensorFlow backend.
Found 13268 images belonging to 36 classes.
Found 3345 images belonging to 36 classes.
Epoch 1/2
1/3 [=========>....................] - ETA: 0s - loss: 15.2706 - acc: 0.0000e+00
3/3 [==============================] - 1s 180ms/step - loss: 14.7610 - acc: 0.0667 - val_loss: 15.6144 - val_acc: 0.0312
Epoch 2/2
1/3 [=========>....................] - ETA: 0s - loss: 14.5063 - acc: 0.1000
3/3 [==============================] - 0s 32ms/step - loss: 15.5808 - acc: 0.0333 - val_loss: 15.6144 - val_acc: 0.0312

即使看起来还可以,但显然根本无法训练。我尝试使用不同数量的纪元,步骤和较大的数据集-几乎没有变化。即使有超过60k的图像,训练每个纪元也需要大约半秒!奇怪的是,当我尝试将图像保存到相应的文件夹时,它只能保存其中的500-600个左右,并且很可能会停止。

from tensorflow.python.keras.applications import ResNet50
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, Flatten, GlobalAveragePooling2D, Conv2D, Dropout
from tensorflow.python.keras.applications.resnet50 import preprocess_input
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
import keras
import os

if __name__ == '__main__':
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

    image_size = 28
    img_rows = 28
    img_cols = 28
    num_classes = 36

    data_generator = ImageDataGenerator()

    train_generator = data_generator.flow_from_directory(
        directory="/final train 1 of 5/",
        save_to_dir="/image generator output/train/",
        target_size=(image_size, image_size),
        color_mode="grayscale",
        batch_size=10,
        class_mode='categorical')

    validation_generator = data_generator.flow_from_directory(
        directory="/final test 1 of 5/",
        save_to_dir="/image generator output/test/",
        target_size=(image_size, image_size),
        color_mode="grayscale",
        class_mode='categorical')

    model = Sequential()
    model.add(Conv2D(20, kernel_size=(3, 3),
                     activation='relu',
                     input_shape=(img_rows, img_cols, 1)))
    model.add(Conv2D(20, kernel_size=(3, 3), activation='relu'))
    model.add(Flatten())
    model.add(Dense(100, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer='adam',  # adam/sgd
                  metrics=['accuracy'])

    model.fit_generator(train_generator,
                        steps_per_epoch=3,
                        epochs=2,
                        validation_data=validation_generator,
                        validation_steps=1)

似乎有些事情默默地失败了并且削弱了培训过程。

2 个答案:

答案 0 :(得分:4)

问题是您误解了steps_per_epoch的{​​{1}}参数。让我们看一下文档:

  

steps_per_epoch :整数。在声明一个纪元完成并开始下一个纪元之前,要从生成器产生的步骤总数(样本批次)。它通常等于数据集的样本数量除以批次大小。序列的可选:如果未指定,将使用fit_generator作为许多步骤。

因此,基本上,它确定每个时期将生成多少批次。因为按照定义,纪元意味着要遍历整个训练数据,所以我们必须将此参数设置为样本总数除以批次大小。因此,在您的示例中,它将为len(generator)。当然,如文档中所述,您可以不指定它,它会自动推断出来。

此外,同样的情况也适用于steps_per_epoch = 13268 // 10参数。

答案 1 :(得分:0)

正如@today所建议,问题出在未归一化的图像中。

rescale=1/255传递给ImageDataGenerator可以解决此问题。