【问题标题】:How to use .predict_generator() on new Images - Keras如何在新图像上使用 .predict_generator() - Keras
【发布时间】:2019-02-15 14:51:51
【问题描述】:

我使用ImageDataGenerator 和flow_from_directory 进行训练和验证。

这些是我的目录:

train_dir = Path('D:/Datasets/Trell/images/new_images/training')
test_dir = Path('D:/Datasets/Trell/images/new_images/validation')
pred_dir = Path('D:/Datasets/Trell/images/new_images/testing')

图像生成器代码:

img_width, img_height = 28, 28
batch_size=32
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(
    train_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

找到属于 4 个类别的 1852 张图片

找到属于 4 个类别的 115 张图片

这是我的模型训练代码:

history = cnn.fit_generator(
        train_generator,
        steps_per_epoch=1852 // batch_size,
        epochs=20,
        validation_data=validation_generator,
        validation_steps=115 // batch_size)

现在我在测试文件夹中有一些新图像(所有图像都在同一个文件夹中),我想对其进行预测。但是当我使用.predict_generator 时,我得到:

找到属于 0 类的 0 张图片

所以我尝试了这些解决方案:

1) Keras: How to use predict_generator with ImageDataGenerator? 这没有成功,因为它只尝试验证集。

2)How to predict the new image by using model.predict?module image not found

3) How to get predictions with predict_generator on streaming test data in Keras? 这也没有成功。

我的火车数据基本上存储在 4 个单独的文件夹中,即 4 个特定的类,验证也以相同的方式存储并且效果很好。

所以在我的测试文件夹中,我有大约 300 张图像,我想在这些图像上预测并制作一个数据框,如下所示:

image_name    class
gghh.jpg       1
rrtq.png       2
1113.jpg       1
44rf.jpg       4
tyug.png       1
ssgh.jpg       3

我也使用了以下代码:

img = image.load_img(pred_dir, target_size=(28, 28))
img_tensor = image.img_to_array(img)
img_tensor = np.expand_dims(img_tensor, axis=0)
img_tensor /= 255.

cnn.predict(img_tensor)

但我收到此错误:[Errno 13] Permission denied: 'D:\\Datasets\\Trell\\images\\new_images\\testing'

但我无法在我的测试图像上predict_generator。那么如何使用 Keras 预测我的新图像。我在谷歌上搜索了很多,也在 Kaggle Kernels 上进行了搜索,但还没有找到解决方案。

【问题讨论】:

    标签: python pandas image-processing keras


    【解决方案1】:

    根据下面引用的 Keras 文档,不推荐使用 predict_generator。 Model.predict 现在支持生成器,因此不再需要使用 predict_generator 端点。

    Keras 文档,参考:https://www.tensorflow.org/api_docs/python/tf/keras/Model#predict_generator

    【讨论】:

      【解决方案2】:

      predict_generator() 我遇到了一些麻烦。这里的一些帖子很有帮助。我也在这里发布我的解决方案,希望它对其他人有所帮助。我的工作:

      • 使用predict_generator() 对新图像进行预测
      • 获取每个预测的文件名
      • 将结果存储在数据框中

      我根据here 的文档进行二元预测,例如“猫和狗”。但是,该逻辑可以推广到多类情况。在这种情况下,每个类的预测结果有一列。

      首先,我加载我存储的模型并设置数据生成器:

      import numpy as np
      import pandas as pd
      from keras.preprocessing.image import ImageDataGenerator
      from keras.models import load_model
      
      # Load model
      model = load_model('my_model_01.hdf5')
      
      test_datagen = ImageDataGenerator(rescale=1./255)
      test_generator = test_datagen.flow_from_directory(
              "C:/kerasimages/pred/",
              target_size=(150, 150),
              batch_size=20,
              class_mode='binary',
              shuffle=False)
      

      注意:指定shuffle=False 以保持文件名和预测的顺序很重要。

      图像存储在C:/kerasimages/pred/images/。数据生成器将仅在C:/kerasimages/pred/(如test_generator 中指定)的子文件夹 中查找图像。尊重数据生成器的逻辑很重要,因此需要子文件夹/images/。 C:/kerasimages/pred/ 中的每个子文件夹都被生成器解释为一个类。在这里,生成器将报告Found x images belonging to 1 classes(因为只有一个子文件夹)。如果我们进行预测,则类(由生成器检测到)是不相关的。

      现在,我可以使用生成器进行预测:

      # Predict from generator (returns probabilities)
      pred=model.predict_generator(test_generator, steps=len(test_generator), verbose=1)
      

      在这种情况下不需要重置生成器,但如果之前已设置生成器,则可能需要使用test_generator.reset() 将其重置。

      接下来我对概率进行四舍五入以获取类并检索文件名:

      # Get classes by np.round
      cl = np.round(pred)
      # Get filenames (set shuffle=false in generator is important)
      filenames=test_generator.filenames
      

      最后,结果可以存储在数据框中:

      # Data frame
      results=pd.DataFrame({"file":filenames,"pr":pred[:,0], "class":cl[:,0]})
      

      【讨论】:

      • 我尝试了很多不同的解决方案,但“shuffle=False”提示正是我所缺少的。
      • 我花了一些时间才弄明白
      【解决方案3】:

      因此,首先应将测试图像放在测试文件夹内的单独文件夹中。所以就我而言,我在test 文件夹中创建了另一个文件夹并将其命名为all_classes。 然后运行以下代码:

      test_generator = test_datagen.flow_from_directory(
          directory=pred_dir,
          target_size=(28, 28),
          color_mode="rgb",
          batch_size=32,
          class_mode=None,
          shuffle=False
      )
      

      上面的代码给了我一个输出:

      找到属于 1 类的 306 张图片

      最重要的是,您必须编写以下代码:

      test_generator.reset()

      否则会出现奇怪的输出。 然后使用.predict_generator()函数:

      pred=cnn.predict_generator(test_generator,verbose=1,steps=306/batch_size)

      运行上面的代码会给出概率输出,所以首先我需要将它们转换为类号。就我而言,它是 4 个班级,所以班级编号是 0、1、2 和 3。

      代码编写:

      predicted_class_indices=np.argmax(pred,axis=1)

      下一步是我想要类的名称:

      labels = (train_generator.class_indices)
      labels = dict((v,k) for k,v in labels.items())
      predictions = [labels[k] for k in predicted_class_indices]
      

      where by class numbers 将替换为类名。最后一步,如果要将其保存到 csv 文件,请将其排列在数据框中,并在图像名称后附加预测的类。

      filenames=test_generator.filenames
      results=pd.DataFrame({"Filename":filenames,
                            "Predictions":predictions})
      

      显示您的数据框。现在一切都完成了。您将获得图像的所有预测类别。

      【讨论】:

      • 回归问题时我们该怎么办?在这种情况下,我们没有任何课程。
      【解决方案4】:

      您最有可能在使用flow_from_directory 时出错。阅读文档:

      flow_from_directory(目录,...)

      地点:

      directory:目标目录的路径。它应该包含一个 每个类的子目录。内含任何 PNG、JPG、BMP、PPM 或 TIF 图像 每个子目录目录树都将包含在 生成器。

      这意味着在您传递给此函数的目录中,您必须创建子目录并将图像放置在此子目录中。否则,当图像在您传递的目录(不是子目录)中时,确实有 0 个图像和 0 个类。

      编辑

      好的,如果您要执行预测,我相信您想使用predict 函数,如下所示:(请注意,您必须以与学习期间相同的格式向网络提供数据过程)

      image = img_to_array(load_img(f"{directory}/{foldername}/{filename}"))
      # here you prepare the input data, for example here we take the gray image
      # gray scale is the 1st channel in the Lab color space
      color_me = rgb2lab((1.0 / 255) * color_me)[:, :, 0]
      color_me = color_me.reshape(color_me.shape + (1,))
      # here data is in the format which is accepted by, in this case, my model
      # for your model you have to do the preparation just the same as in the case of learning process
      output = model.predict(np.array([color_me]))
      # and here you have your predicted output
      

      【讨论】:

      • 是的,但是如果我已经将它们放在子目录中,那为什么还要使用.predict_generator呢?
      • 问题是,您应该使用与您想要实现的目标相关的功能。我的意思是,如果你想生成预测,predict_generator 是可以的,但是当你需要训练模型时,fit_generator 应该是你的选择。
      • 我只使用过mode.fit_generator。等我更新问题
      • 如果可以,请在此处粘贴您传递给flow_from_directory 的路径以及图片的路径。
      【解决方案5】:

      我强烈建议您在测试文件夹中创建一个父文件夹。然后将测试文件夹移动到父文件夹。

      表示如果你有这种方式的测试文件夹:

      /root/test/img1.png
      /root/test/img2.png
      /root/test/img3.png
      /root/test/img4.png
      

      这种使用 predict_generator 的错误方式。像这样更新您的测试文件夹:

      /root/test_parent/test/img1.png
      /root/test_parent/test/img2.png
      /root/test_parent/test/img3.png
      /root/test_parent/test/img4.png
      

      使用此命令更新:

      mv /root/test/ ./root/test_parent/test 
      

      而且,也不要忘记像这样给模型提供路径

      "/root/test_parent/"
      

      这种方法对我有用。

      【讨论】:

      • 但随后它的显示发现了属于 1 类的 300 张图像,当我预测它给出一个真假数组时
      • 据我所知,“predict_generator”只给出类概率。
      • 嗨,我做到了,我想我应该发布它
      • 不得不做更多的事情,检查我的答案。我从 Medium 获得了参考
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2019-09-16
      相关资源
      最近更新 更多