Вопрос или проблема
Мне было интересно, написал ли кто-нибудь код, с помощью которого я могу считать из каталога изображений (без вложенной папки, представляющей “класс”) и затем запустить model.predict() на нем. Я не хочу настраивать вложенную папку, потому что обычно она называется как класс, так как эта папка будет невидимой и неназванной. Вот мой код попытки, который не работает:
model = tf.keras.models.load_model('Classification_model')
data_augmentation = keras.Sequential(
[
layers.experimental.preprocessing.Rescaling(1./255)
]
)
dataset = tf.data.Dataset.list_files("test/*.JPG", shuffle = False) # чтение группы jpeg.
def decode_img(img):
img = tf.image.decode_jpeg(img, channels=3) # цветные изображения
img = tf.image.convert_image_dtype(img, tf.float32)
# конвертировать тензор unit8 в флоаты в диапазоне [0,1]
return img
def decode_jpeg_and_label(filename):
bits = tf.io.read_file(filename)
image = decode_img(bits)
label = 1 # фейковая метка
return image, label
dataset = dataset.map(decode_jpeg_and_label)
augmented_test_ds = dataset.map(
lambda x, y: (data_augmentation(x, training=False), y))
probs = model.predict(augmented_test_ds, verbose = 1)
Однако ошибка, которую я получаю, такова:
ValueError: Вход 0 слоя stem_conv несовместим с слоем:
: ожидается min_ndim=4, найдено ndim=3. Полная форма получена: [None, None,
None]
что, я полагаю, означает, что я неправильно форматирую свой набор данных для прогнозирования. Что мне делать? Спасибо!
Tensorflow/Keras ожидать, что тренировочные и тестовые наборы данных будут в формате пакета с формой (32, 224, 224, 3), где 32 представляет количество изображений, так что в случае предсказания одного изображения форма вашего пакета должна выглядеть как (1, 224, 224, 3).
def decode_jpeg_and_label(filename):
bits = tf.io.read_file(filename)
image = decode_img(bits)
image = image.reshape((1, 224, 224, 3)) # Добавлено это, чтобы изменить форму одного изображения
label = 1 # фейковая метка
return image, label
Как только вы добавите этот блок кода, ошибка ndim=3 исчезнет
Ответ или решение
Чтобы использовать модель Keras для предсказания на наборе данных, который не имеет подкаталогов для представления "классов", необходимо выполнить несколько шагов для правильной подготовки и предсказания данных с использованием TensorFlow/Keras. Давайте подробно разберем, как можно это сделать с теоретическим обоснованием, практическим примером и применением на практике.
Теория
В машинном обучении и особенно в задачах компьютерного зрения, подготовка данных и их предобработка играют ключевую роль для успешного выполнения предсказаний моделей. Когда вы работаете с предсказанием изображений, модель ожидает входные данные в определенном формате и размерности. Для сверточной нейронной сети (CNS) это, как правило, 4-мерный тензор с формой (batch_size, height, width, channels)
. Здесь batch_size
— это количество изображений в одной партии, который всегда должен быть задан. Если вы работаете с одиночными изображениями, то batch_size
будет равен 1.
Ошибка, с которой вы столкнулись — "Input 0 of layer stem_conv is incompatible with the layer: expected min_ndim=4, found ndim=3" — говорит о том, что ваша модель ожидает 4-мерный тензор на вход, а вы передаете только 3-мерный (форма изображения без размерной партии). Для исправления этой ошибки необходимо убедиться, что каждое изображение находится в правильном формате и размерности.
Пример
Ниже представлен пример кода, который исправляет вашу текущую имплементацию, чтобы сделать ее совместимой с ожиданиями модели. Мы добавим этапы для изменения размера изображения и добавления размерной партии.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# Загрузка модели
model = tf.keras.models.load_model('Classification_model')
# Определяем этап аугментации данных
data_augmentation = keras.Sequential([
layers.experimental.preprocessing.Rescaling(1./255)
])
# Список файлов изображений
dataset = tf.data.Dataset.list_files("test/*.JPG", shuffle=False)
# Декодирование и предобработка изображений
def decode_img(img):
img = tf.image.decode_jpeg(img, channels=3) # Декодирование изображения
img = tf.image.convert_image_dtype(img, tf.float32) # Преобразование к типу float32
img = tf.image.resize(img, [224, 224]) # Изменение размера изображения
return img
def decode_jpeg_and_label(filename):
bits = tf.io.read_file(filename)
image = decode_img(bits)
image = tf.expand_dims(image, axis=0) # Добавляем размерную партию
label = 1 # Временная метка
return image, label
dataset = dataset.map(decode_jpeg_and_label)
# Аугментация данных
augmented_test_ds = dataset.map(
lambda x, y: (data_augmentation(x, training=False), y))
# Извлечение изображений из данных
augmented_images = [image[0] for image, _ in augmented_test_ds]
# Предсказание модели
probs = model.predict(tf.stack(augmented_images), verbose=1)
Применение
Объяснение кода:
-
Загрузка модели: Мы используем метод
load_model
из Keras для загрузки заранее подготовленной моделиClassification_model
. -
Предобработка данных:
list_files
: Генерирует список файлов изображений в указанной директории.decode_img
: Функция для декодирования и изменения формата изображения. Здесь мы используем функциюtf.image.resize
чтобы изменить размер изображений до(224, 224)
, что является стандартом для большинства моделей изображений.tf.expand_dims
: Добавляет размерной партии, необходимой для модели, так как модель ожидает 4-мерные тензоры.
-
Аугментация: Используем
data_augmentation
, чтобы нормализовать данные. -
Предсказание: Используем
model.predict
для выполнения предсказания на подготовленных данных.
Это решение создает совместимый с моделью набор данных и позволяет корректно предсказывать метрики для изображений из заданной директории, обеспечивая процесс на уровне производственного стандарта. Убедитесь, что изображения передаются в форму, совместимую с ожиданиями модели, чтобы избежать ошибок и получить надежные результаты.