#python #image #tensorflow #machine-learning #classification
#python #изображение #tensorflow #машинное обучение #классификация
Вопрос:
У меня есть уже обученная модель, и я хочу делать прогнозы двоичной классификации для изображений в каталоге. У меня более 100 000 изображений, поэтому для повышения эффективности я хочу делать пакетные прогнозы. Как я могу выполнять пакетные прогнозы для своих изображений, получать результаты прогнозирования и сохранять изображения в двух отдельных папках после того, как они были предсказаны на основе класса?
Вот как пока выглядит мой код…
model_filepath = r"C:Usersmodel_200.h5"
model = tf.keras.models.load_model(model_filepath)
test_dir = r"C:Usersimage_testing_folder"
batch_size = 64
IMG_HEIGHT = 200
IMG_WIDTH = 200
test_image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
test_image_gen = test_image_generator.flow_from_directory(directory=str(test_dir),
batch_size=batch_size,
shuffle=False,
target_size=(IMG_HEIGHT, IMG_WIDTH),
)
predictions = (model.predict(test_image_gen) > 0.5).astype("int32")
predictions
Одним из решений было бы связать прогноз с путем к файлу изображения, а затем использовать shutil.move() для перемещения исходного изображения в папку назначения. Как бы я это сделал? Есть ли лучший способ для пакетного прогнозирования, чем использование ImageDataGenerator и .flow_from_directory ?
Ответ №1:
Вы можете создать пользовательский набор данных, чтобы также легко получить имя файла:
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras import Sequential
from glob2 import glob
from shutil import copy
import numpy as np
files = glob('group1\*\*.jpg')
imsize = 64
def load(file_path):
img = tf.io.read_file(file_path)
img = tf.image.decode_png(img, channels=3)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, size=(imsize, imsize))
return img, file_path
ds = tf.data.Dataset.from_tensor_slices(files).
take(100).
shuffle(100).
map(load).batch(4)
model = Sequential()
model.add(Conv2D(8, (3, 3), input_shape=(imsize, imsize, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(units=32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(units=2, activation='sigmoid'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.build(input_shape=(imsize, imsize, 3))
categories = np.array(['cats', 'dogs'])
target_dir = 'newpics'
for cat in categories:
os.makedirs(os.path.join(target_dir, cat), exist_ok=True)
for images, filenames in ds:
preds = model(images)
targets = categories[np.argmax(preds, axis=1)]
for file, destination in zip(filenames, targets):
copy(file.numpy().decode(), os.path.join(target_dir, destination,
os.path.basename(file.numpy().decode())
))
print(file.numpy().decode(), '-->', os.path.join(target_dir, destination,
os.path.basename(file.numpy().decode())
))
group1catscat.4051.jpg --> newpicscatscat.4051.jpg
group1catscat.4091.jpg --> newpicsdogscat.4091.jpg
group1catscat.4055.jpg --> newpicscatscat.4055.jpg
group1catscat.4041.jpg --> newpicscatscat.4041.jpg
group1catscat.4090.jpg --> newpicscatscat.4090.jpg
group1catscat.4071.jpg --> newpicsdogscat.4071.jpg
group1catscat.4082.jpg --> newpicscatscat.4082.jpg
group1catscat.4037.jpg --> newpicscatscat.4037.jpg
group1catscat.4005.jpg --> newpicscatscat.4005.jpg
Все, что вам нужно изменить, это шаблон глобуса и папки.
Комментарии:
1. Спасибо за быстрый ответ!
2. Однако есть один вопрос; Хотя вы создали пользовательский набор данных со 100 изображениями на «пакет», вы используете цикл for для итерации по каждому изображению. Является ли ваше решение истинным «пакетным предсказанием» в смысле генерации прогнозов для набора изображений «все сразу»? Как это сравнивается с точки зрения скорости прогнозирования с таким решением, как model.predict_classes(np.vstack(test_images_2)) или с использованием TF ImageDataGenerator? Возможно, цикл for необходим для возврата путей к файлам. Спасибо!
3. Для первого вам нужно будет загрузить все изображения в память, что, скорее всего, приведет к перегрузке памяти. Для второго это то же самое, потому что ImageDataGenerator использует мою реализацию под капотом. Как вы можете видеть выше, он использует размер пакета 4, поэтому одновременно прогнозируется более одной выборки. Так что это действительно быстрее. Вы даже можете увеличить это число. Вы можете использовать размер пакета 256, если он умещается в памяти.