如何在新图像上使用.predict_generator()-Keras

时间:2018-09-11 06:47:42

标签: python pandas image-processing keras

我已经使用ImageDataGeneratorflow_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')

ImageGenerator代码:

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')
  

找到了1852个属于4类的图像

     

找到了115个属于4类的图像

这是我的模型训练代码:

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对新图像进行预测。我在Google上搜索了很多,还在Kaggle Kernels上搜索过,但是还没有找到解决方法。

5 个答案:

答案 0 :(得分:8)

因此,首先,应将测试图像放置在测试文件夹内的单独文件夹中。因此,就我而言,我在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]

其中,由班级编号将替换为班级名称。最后一步,如果要将其保存到csv文件中,请将其布置在数据帧中,图像名称后附有预测的类。

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

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

答案 1 :(得分:0)

很可能您在使用flow_from_directory时犯了一个错误。阅读文档:

  

flow_from_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

答案 2 :(得分:0)

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

表示您是否以这种方式具有测试文件夹:

/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/"

这种方法对我有用。

答案 3 :(得分:0)

我在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]})

答案 4 :(得分:0)

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

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

相关问题