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

Python 如何在新图像上使用.predict_generator()-Keras,python,pandas,image-processing,keras,Python,Pandas,Image Processing,Keras,我使用了来自目录的ImageDataGenerator和flow\u进行培训和验证 这些是我的目录: 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') 图像生成

我使用了来自目录的
ImageDataGenerator
flow\u进行培训和验证

这些是我的目录:

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')
找到了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\u生成器时,我得到:

找到属于0类的0个图像

因此,我尝试了以下解决方案:

1) 这不起作用,因为它仅在验证集上进行尝试

2) 未找到模块图像

3) 这也没有成功

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

因此,在我的测试文件夹中,我有大约300个图像,我想在这些图像上预测并生成一个数据帧,如下所示:

image_name    class
gghh.jpg       1
rrtq.png       2
1113.jpg       1
44rf.jpg       4
tyug.png       1
ssgh.jpg       3
/root/test_parent/test/img1.png
/root/test_parent/test/img2.png
/root/test_parent/test/img3.png
/root/test_parent/test/img4.png
我还使用了以下代码:

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)
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
)
但是我得到了这个错误:
[Errno 13]权限被拒绝:“D:\\dataset\\Trell\\images\\new\u images\\testing”


但我无法在测试图像上预测\u生成器。那么,我如何使用Keras预测我的新图像呢。我在谷歌上搜索了很多,也搜索了Kaggle内核,但没有找到解决方案。

最有可能的是,您使用目录中的
flow\u时出错了。阅读文档:

来自目录(目录,…)的流

其中:

目录:目标目录的路径。它应该包含一个 每个类的子目录。里面有任何PNG、JPG、BMP、PPM或TIF图像 目录树中的每个子目录都将包含在 发电机

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

编辑

好的,如果您要执行预测,我相信您希望使用
预测
功能,如下所示:(注意,您必须以与学习过程中相同的格式向网络提供数据)


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

表示如果您以这种方式拥有测试文件夹:

/root/test/img1.png
/root/test/img2.png
/root/test/img3.png
/root/test/img4.png
这是一种错误的使用预测_生成器的方法。按如下方式更新您的测试文件夹:

image_name    class
gghh.jpg       1
rrtq.png       2
1113.jpg       1
44rf.jpg       4
tyug.png       1
ssgh.jpg       3
/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/"

这种方法对我来说是可行的

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

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)
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
)
上面的代码为我提供了一个输出:

找到306张属于1类的图像

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

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)
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
)
test\u generator.reset()

否则会有奇怪的输出。 然后使用
.predict\u generator()
函数:

pred=cnn.predict\u生成器(test\u生成器,verbose=1,steps=306/批量大小)

运行上面的代码将给出概率输出,所以首先我需要将它们转换为类编号。在我的例子中,它是4个类,所以类号是0、1、2和3

编写的代码:

predicted\u class\u index=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})

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

我在使用
predict\u generator()
时遇到一些问题。这里的一些帖子帮助很大。我也在这里发布我的解决方案,希望它能帮助其他人。我所做的:

  • 使用
    predict\u generator()
  • 获取每个预测的文件名
  • 将结果存储在数据帧中
我做了“猫和狗”的二元预测。然而,这种逻辑可以推广到多类情况。在这种情况下,预测的结果每类有一列

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

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)
# Predict from generator (returns probabilities)
pred=model.predict_generator(test_generator, steps=len(test_generator), verbose=1)
注意:必须指定
shuffle=False
以保持文件名和预测的顺序

图像存储在
C:/kerasimages/pred/Images/
中。数据生成器将仅在
C:/kerasimages/pred/
的子文件夹中查找图像(如
test\u generator
中所述)。尊重数据生成器的逻辑非常重要,因此需要子文件夹
/images/
。生成器将
C:/kerasimages/pred/
中的每个子文件夹解释为一个类。在这里,生成器将报告属于1个类的
找到的x个图像(因为只有一个子文件夹)。如果我们进行预测,则类(由生成器检测到)是不相关的

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

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)
# Predict from generator (returns probabilities)
pred=model.predict_generator(test_generator, steps=len(test_generator), verbose=1)
在这种情况下,不需要重置发电机,但如果以前已设置过发电机,则可能需要使用
test\u 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]})

根据下文引用的Keras文件,predict_发生器已弃用。Model.predict现在支持生成器,因此不再需要使用predict_生成器endpoi