如何在 Keras 中保存整个数据的预测值

数据挖掘 机器学习 喀拉斯 机器学习模型 vgg16
2022-02-27 02:41:05

我正在使用预训练的 VGG16 模型对文件夹中的图像进行分类。目前,我只能对一张图像进行分类。

  1. 如何修改代码以对文件夹中的所有图像进行分类
  2. 如何保存每张图像的预测值?

下面是我的代码:

from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.imagenet_utils import decode_predictions
import matplotlib.pyplot as plt

filename = 'cat.jpg'
# load an image in PIL format
original = load_img(filename, target_size=(224, 224))
print('PIL image size',original.size)
plt.imshow(original)
plt.show()

# convert the PIL image to a numpy array
# IN PIL - image is in (width, height, channel)
# In Numpy - image is in (height, width, channel)
numpy_image = img_to_array(original)
plt.imshow(np.uint8(numpy_image))
plt.show()
print('numpy array size',numpy_image.shape)

# Convert the image / images into batch format
# expand_dims will add an extra dimension to the data at a particular axis
# We want the input matrix to the network to be of the form (batchsize, height, width, channels)
# Thus we add the extra dimension to the axis 0.
image_batch = np.expand_dims(numpy_image, axis=0)
print('image batch size', image_batch.shape)
plt.imshow(np.uint8(image_batch[0]))



# prepare the image for the VGG model
processed_image = vgg16.preprocess_input(image_batch.copy())

# get the predicted probabilities for each class
predictions = vgg_model.predict(processed_image)
print (predictions)

# convert the probabilities to class labels
# We will get top 5 predictions which is the default
#label = decode_predictions(predictions)

谢谢

1个回答

首先,你总是可以用一个循环来包装你的代码。

files = [file1, file2, ...]
predictions = []
for file in files:
    original = load_img(file, target_size=(224, 224))
    numpy_image = img_to_array(original)
    image_batch = np.expand_dims(numpy_image, axis=0)
    processed_image = vgg16.preprocess_input(image_batch)  # you dont need to copy :)      predictions_cur = vgg_model.predict(processed_image)
    print(predictions_cur)
    predictions.append(predictions_cur)
    #label = decode_predictions(predictions_cur)

其次,您可以使用 tf.data api 提高此代码的效率。例如:

from tensorflow.data import Dataset

batch_size = 32
num_threads = 4
target_size=(224, 224)

def preprocess_image(file):
    # file is not a tensor, so we have to use functions that work on tensors
    img_string = tf.read_file(file)
    img = tf.image.decode_png(img_string)
    img = tf.image.resize_images(target_size)
    img = vgg16.preprocess_input(img)  # this function can handle tensors as well.
    return img

files = [file1, file2, ...]
dataset = Dataset.from_tensor_slices(tf.constant(files))
dataset = dataset.map(preprocess_image, num_threads)
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(1)  
predictions = vgg_model.predict(dataset, steps=len(files) // batch_size)
# You could decode the predictions from here :)

解释

让我详细说明每个步骤:)

dataset.from_tensor_slices(files)将只构建一个数据集对象,它将使用的样本是您的文件。

dataset.map(preprocess_image, num_threads)
这表明在我们使用每个样本之前对其进行预处理。
这也将在num_threads并行调用中进行,如果我们将样本批处理在一起进行预测,这将加快进程。

dataset = dataset.batch(batch_size)
这会将样本批处理在一起以进行预测。这对于并行进行预测和加快进程很有用。

dataset.prefetch(1)
这将在预测前一个批次的同时预分配下一批。因此,这也将使过程更快,因为您可以通过这种方式节省时间。

最后,predictions = vgg_model.predict(dataset, steps=len(files) // batch_size)
这将预测我们提供给上述数据集的所有文件。
请注意,我们指出步数是len(files) // batch_size,因此如果len(files)不是batch_size的乘积,则无法预测某些图像。如果要预测所有图像,可以使用除以len(files)的batch_size,或者只使用 batch_size = 1。