#python #numpy #tensorflow #machine-learning #keras
Вопрос:
Я очень новичок в машинном обучении и python в целом. Я работаю над проектом, требующим создания модели классификации изображений. Я прочитал данные с моего локального диска, используя tf.keras.preprocessing.image_dataset_from_directory
, и теперь я пытаюсь извлечь x_val
и y_val
сгенерировать файл skilearn.metrics.classification_report
.
Проблема в том, что всякий раз, когда я звоню:
y_val = np.concatenate([y_val, np.argmax(y.numpy(), axis=-1)])`
Я получаю следующую ошибку, и я понятия не имею, почему и как ее исправить
y_val = np.объединение([y_val, np.argmax(y.numpy(), ось=-1)]) Файл «<внутренние функции array_function>», строка 5, в ошибке объединения значений: все входные массивы должны иметь одинаковое количество измерений, но массив с индексом 0 имеет 1 измерение(ы), а массив с индексом 1 имеет 0 измерений (ов)`
Вот мой код
#data is split into train and validation folders with 6 folders in each representing a class, like this:
#data/train/hamburger/<haburger train images in here>
#data/train/pizza/<pizza train images in here>
#data/validation/hamburger/<haburger test images in here>
#data/validation/pizza/<pizza test images in here>
#training_dir = ......
validation_dir = pathlib.Path('path to data dir on local disk')
#hyperparams
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
training_dir,
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
validation_dir,
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)
print(val_ds.class_names)
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)
resize_and_rescale = tf.keras.Sequential([
layers.experimental.preprocessing.Resizing(img_height, img_width),
layers.experimental.preprocessing.Rescaling(1./255)
])
#normalization, augmentation, model layers
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['accuracy'])
model.summary()
start_time = time.monotonic()
epochs = 1
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
#plot
#testing random image
test_path = pathlib.Path('C:/Users/adi/Desktop/New folder/downloads/hamburger/images(91).jpg')
img = keras.preprocessing.image.load_img(
test_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print(
"This image most likely belongs to {} with a {:.2f} percent confidence."
.format(class_names[np.argmax(score)], 100 * np.max(score))
)
x_val = np.array([])
y_val = np.array([])
for x, y in val_ds:
x_val = np.concatenate([x_val, np.argmax(model.predict(x), axis=-1)])
y_val = np.concatenate([y_val, np.argmax(y.numpy(), axis=-1)]) #<----- crashes here
print(classification_report(y_val, x_val, target_names = ['doughnuts (Class 0)','french_fries (Class 1)', 'hamburger (Class 2)','hot_dog (Class 3)', 'ice_cream (Class 4)','pizza (Class 5)']))
Любые идеи, почему я получаю эту ошибку и как я могу ее исправить. Или, в качестве альтернативы, как я могу получить то, что мне нужно, чтобы classification_report работал. Спасибо.
Комментарии:
1. можете ли вы показать нам пару элементов из val_ds?
2. @sk877 хорошо. как мне это сделать? или вы имеете в виду изображения?
3. просто попробуйте напечатать(val_ds[0:3]) или что-то в этом роде и уменьшите 3, если массивы слишком длинные.
4. кроме того, не связанные, но хорошо приспосабливающиеся на ранней стадии… странно оценивать модель (с отчетом о классификации) между «x_val» и «y_val». вы оцениваете фактический y по сравнению с прогнозируемым y, поэтому, возможно, подумайте о переименовании ваших переменных в y_pred и y_act или что-то в этом роде, иначе люди будут плакать
5. @sk877ok. Я переименую. Спасибо. попытался распечатать. дай мне
TypeError: 'PrefetchDataset' object is not subscriptable
Ответ №1:
Вам не нужна argmax
операция при получении истинных классов.
Поскольку вы не указали class_mode
в каталоге tf.keras.preprocessing.image_dataset_from_directory, метки разрежены, что означает, что они не закодированы одним горячим способом.
Если бы у вас были векторные метки с одним горячим кодом, приведенный выше код был бы правильным.
Другое дело, что переименование ваших массивов должно быть лучше таким образом, и при прогнозировании одного изображения за раз вы можете использовать model(x)
то, что более эффективно. Правильный код должен быть:
predicted_classes = np.array([])
labels = np.array([])
for x, y in val_ds:
predicted_classes = np.concatenate([predicted_classes, np.argmax(model(x), axis=-1)])
labels = np.concatenate([labels, y.numpy()])
Комментарии:
1. Это работает. Большое вам спасибо, я потратил на это больше половины дня. Сейчас я ухожу, чтобы понять, что такое однократное кодирование.
2. Скажите, у вас есть ярлыки [0], [1], [2] —> 0 представлен в виде [1,0,0] // 1 —>> [0,1,0] … и так далее.