Гиперполосный поиск Keras с использованием итератора каталогов

Я использую flow_from_directory Tensorflow для сбора большого набора данных изображений, а затем тренируюсь на нем. Я хочу использовать Keras Tuner, но когда я запускаю

tuner.search(test_data_gen, epochs=50, 
              validation_split=0.2, callbacks=[stop_early]) 

Выдает следующую ошибку,

ValueError: `validation_split` is only supported for Tensors or NumPy arrays, found following types in the input: [<class 'tensorflow.python.keras.preprocessing.image.DirectoryIterator'>] 

Я мало знаю о преобразовании между типами данных в AI, поэтому любая помощь действительно приветствуется.

Вот остальная часть моего кода:

import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import IPython.display as display
from PIL import Image, ImageSequence
import os
import pathlib
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import cv2
import datetime
import kerastuner as kt

tf.compat.v1.enable_eager_execution()

epochs = 50
steps_per_epoch = 10
batch_size = 20
IMG_HEIGHT = 200
IMG_WIDTH = 200

train_dir = "Data/Train"
test_dir = "Data/Val"

train_image_generator = ImageDataGenerator(rescale=1. / 255)

test_image_generator = ImageDataGenerator(rescale=1. / 255)

train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=train_dir,
                                                           shuffle=True,
                                                           target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                           class_mode='sparse')

test_data_gen = test_image_generator.flow_from_directory(batch_size=batch_size,
                                                         directory=test_dir,
                                                         shuffle=True,
                                                         target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                         class_mode='sparse')


    def model_builder(hp):
        model = keras.Sequential()
        model.add(Conv2D(265, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)))
        model.add(MaxPooling2D())
        model.add(Conv2D(64, 3, padding='same', activation='relu'))
        model.add(MaxPooling2D())
        model.add(Conv2D(32, 3, padding='same', activation='relu'))
        model.add(MaxPooling2D())
        model.add(Flatten())
        model.add(keras.layers.Dense(256, activation="relu"))
        hp_units = hp.Int('units', min_value=32, max_value=512, step=32)
        model.add(keras.layers.Dense(hp_units, activation="relu"))
        model.add(keras.layers.Dense(80, activation="softmax"))
    
        hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])
    
        model.compile(optimizer=keras.optimizers.Adam(learning_rate=hp_learning_rate),
                      loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                      metrics=['top_k_categorical_accuracy'])
    
        return model
    
    tuner = kt.Hyperband(model_builder,
                         objective='val_accuracy',
                         max_epochs=30,
                         factor=3,
                         directory='Hypertuner_Dir',
                         project_name='AIOS')
    
    stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)

и начните поиск с tuner

tuner.search(train_data_gen, epochs=50, validation_split=0.2, callbacks=[stop_early])

# Get the optimal hyperparameters
best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]

print(f"""
The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is {best_hps.get('units')} and the optimal learning rate for the optimizer
is {best_hps.get('learning_rate')}.
""")

model = tuner.hypermodel.build(best_hps)

model.summary()
tf.keras.utils.plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True, rankdir='TB')
checkpoint_path = "training/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)

os.system("rm -r logs")

log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

#history = model.fit(train_data_gen,steps_per_epoch=steps_per_epoch,epochs=epochs,validation_data=test_data_gen,validation_steps=10,callbacks=[cp_callback, tensorboard_callback])
history = model.fit(train_data_gen,steps_per_epoch=steps_per_epoch,epochs=epochs,validation_split=0.2,validation_steps=10,callbacks=[cp_callback, tensorboard_callback])
model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))
model.save('model.h5', include_optimizer=True)

test_loss, test_acc = model.evaluate(test_data_gen)
print("Tested Acc: ", test_acc)
print("Tested Acc: ", test_acc*100, "%")

val_acc_per_epoch = history.history['val_accuracy']
best_epoch = val_acc_per_epoch.index(max(val_acc_per_epoch)) + 1
print('Best epoch: %d' % (best_epoch,))

===================================ИЗМЕНИТЬ======= ============================ введите здесь описание изображения


person DragonflyRobotics    schedule 30.03.2021    source источник


Ответы (2)


Согласно документу о validation_split:

validation_split: число с плавающей запятой от 0 до 1. Доля данных обучения, которые будут использоваться в качестве данных проверки. Модель будет выделять эту часть обучающих данных, не будет обучаться на ней и будет оценивать потери и любые метрики модели на этих данных в конце каждой эпохи. Данные проверки выбираются из последних выборок в предоставленных данных x и y перед перетасовкой. Этот аргумент не поддерживается, если x является набором данных, генератором или экземпляром keras.utils.Sequence.

Теперь, когда у вас есть генератор, попробуйте следующее: ссылка< /а>

tuner.search(train_data_gen, 
             epochs=50, 
             validation_data=test_data_gen, 
             callbacks=[stop_early])

Кроме того, убедитесь, что каждый из ваших генераторов правильно генерирует допустимые пакеты.

person M.Innat    schedule 22.04.2021
comment
Подождите, так я использую image_dataset_from_directory или flow_from_directory? - person DragonflyRobotics; 22.04.2021
comment
Я думаю, flow_from_dir..., тот, который вы уже упомянули в приведенном выше коде. - person M.Innat; 22.04.2021
comment
P.S. пожалуйста, очистите свой код выше, его трудно читать. Просто вставьте наиболее важную часть. - person M.Innat; 22.04.2021
comment
О, я вижу, что вы, ребята, говорите! Я не могу выполнить разделение проверки для tuner.search, потому что у меня есть итератор. Вместо этого мне нужно заранее разделить проверку, а затем прыщаво пройти ее! - person DragonflyRobotics; 22.04.2021
comment
Вы можете проверить: tuner.search(train_data_gen) и tuner.search(test_data_gen) и посмотреть, нормально ли они работают? - person M.Innat; 22.04.2021
comment
Теперь он говорит, что заполняется буфер случайного воспроизведения, и мой компьютер завис. Есть ли способ избежать этого? - person DragonflyRobotics; 22.04.2021
comment
для обоих? или конкретный? - person M.Innat; 22.04.2021
comment
Прикрепляю скриншот к вопросу. - person DragonflyRobotics; 22.04.2021
comment
для какой команды? tuner.search(train_data_gen) или tuner.search(test_data_gen)? - person M.Innat; 22.04.2021
comment
Я не уверена. Я попытаюсь выяснить, смогу ли я выяснить, какая команда его замораживает. - person DragonflyRobotics; 22.04.2021
comment
Я имел в виду проверить. Сначала запустите этот tuner.search(train_data_gen) и посмотрите, что произойдет? Если он работает нормально, попробуйте затем с test_data_gen. Но если какая-либо ошибка показывает, то сообщите здесь. - person M.Innat; 22.04.2021
comment
Морозно в tuner.search(train_ds, epochs=50, validation_data=test_ds, callbacks=[stop_early]) - person DragonflyRobotics; 22.04.2021
comment
Я починил это! Мне просто нужно было отключить перетасовку на моем пакетном генераторе, потому что мой компьютер не может с этим справиться. Большое спасибо за помощь. Я действительно ценю это! - person DragonflyRobotics; 22.04.2021
comment
Но обратите внимание, что вы должны установить shuffle=True для train_data_gen и установить False для test_data_gen`. - person M.Innat; 22.04.2021
comment
Я попробую это и посмотрю, выживет ли мой компьютер, чтобы рассказать историю! - person DragonflyRobotics; 22.04.2021

К сожалению, выполнение validation_split=0.2 в этом случае не работает, потому что этот аргумент предполагает, что данные представляют собой массив Tensor или NumPy. Поскольку у вас есть данные, хранящиеся в виде генератора (что является хорошей идеей), вы не можете просто разделить их.

Вам нужно будет создать генератор проверки, как вы сделали с test_data_gen, и изменить validation_split=0.2 на validation_data=val_data_gen.

person Peter Van Katwyk    schedule 14.04.2021
comment
Кажется, я пробовал это, но это все еще не сработало. Я сделал 2 отдельных генератора с совершенно разными каталогами данных, но это все равно не сработало. - person DragonflyRobotics; 15.04.2021
comment
с генератором данных проверки, какую ошибку он выдал? - person M.Innat; 22.04.2021
comment
Та же самая ошибка. - person DragonflyRobotics; 22.04.2021