Генератор соответствий Keras - ValueError: Не удалось найти адаптер данных, который может обрабатывать ввод - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь приспособить мою модель глубокого обучения с помощью специального генератора.

Когда я подгоняю модель, она показывает мне эту ошибку: enter image description here

Я пытался найти похожие вопросы, но все ответы были о преобразовании списков в массив numpy. Я думаю, что это не вопрос в этой ошибке. Все мои списки в формате numpy. Этот пользовательский генератор основан на пользовательском генераторе из здесь

Это часть кода, где я подгоняю модель:

        train_generator = RepresentationGenerator(representation_path=representations_path, target_path=target_path,
                                              filenames=training_filenames, batch_size=batch_size)
    val_generator = RepresentationGenerator(representation_path=representations_path, target_path=target_path,
                                            filenames=validation_filenames, batch_size=batch_size)
    self.model_semantic.fit_generator(train_generator,
                            epochs=10,
                            verbose=1,
                            validation_data=val_generator,
                            )
    return 0

, где переменные:

  • представитель_путь - это строка с каталогом к пути, в котором я храню обучающие файлы, тот файл, который является входом для модели
  • target_path - это строка с каталогом по пути, в котором я храню целевые файлы, тот, который является целевым объектом модели (вывод)
  • training_filenames - это список с имена обучающих и целевых файлов (оба имеют одинаковые имена, но находятся в разных папках)
  • batch_size - целое число с размером пакета. Он имеет значение 7.

Мой класс генератора ниже:

import np
from tensorflow_core.python.keras.utils.data_utils import Sequence
class RepresentationGenerator(Sequence):

    def __init__(self, representation_path, target_path, filenames, batch_size):
        self.filenames = np.array(filenames)
        self.batch_size = batch_size
        self.representation_path = representation_path
        self.target_path = target_path

    def __len__(self):
        return (np.ceil(len(self.filenames) / float(self.batch_size))).astype(np.int)

    def __getitem__(self, idx):
        files_to_batch = self.filenames[idx * self.batch_size: (idx + 1) * self.batch_size]
        batch_x, batch_y = [], []
        for file in files_to_batch:
            batch_x.append(np.load(self.representation_path + file + ".npy", allow_pickle=True))
            batch_y.append(np.load(self.target_path + file + ".npy", allow_pickle=True))

        return np.array(batch_x), np.array(batch_y)

Это значения, когда вызывается метод fit: enter image description here

Как я могу исправить эту ошибку?

Спасибо, товарищи!


Когда я вызываю метод fit_generator, он вызывает метод подходит. enter image description here

Метод fit, вызывает метод fun c .fit и передает переменную Y, которая установлена ​​как None

g

Ошибка в этой строке: enter image description here

1 Ответ

1 голос
/ 17 февраля 2020

Окончательное решение:

Импорт из правильного места:

from tensorflow.keras.utils import Sequence

Старые ответы:

Если __getitem__ никогда не вызывал, проблема может быть в __len__. Вы не возвращаете int, вы возвращаете np.int.

Я предлагаю вам попробовать:

def __len__(self):
    length = len(self.filenames) // self.batch_size
    if len(self.filenames) % self.batch_size > 0:
        length += 1

    return length

Но если вызывается __getitem__ и ваши данные вернувшись, вы должны проверить свои массивы.

Получить элемент из генератора самостоятельно и проверить содержимое:

x, y = train_generator[0]
  • Являются ли они отдельными массивами? Или это массивы массивов? (Должен быть один)
  • Каковы их формы? У них есть ожидаемые формы?
  • Какие у них типы? Обычно они должны быть float, иногда int (для входных данных для встраивания слоев), очень редко string (для входных данных в пользовательские слои, которые знают, как обрабатывать строки).
    • Выходные данные всегда должны быть float, максимум int (для разреженных потерь)

Другие предположения, которые вы используете fit с batch_size при использовании генератора .... это странно, и предложения "если" внутри метода могут быть не очень хорошо подготовлены, возможно, вы попадаете в другой обучающий случай.

Go прямо к обычным опциям:

self.model_semantic.fit_generator(train_generator, 
                                 epochs=10,
                                 verbose=1,
                                 validation_data=val_generator)

Ваш генератор Sequence, он уже имеет __len__, вам не нужно указывать steps_per_epoch или validation_steps.
Каждый генератор имеет автоматические c размеры партии, каждый шаг - партия, и все. Вам не нужно указывать batch_size в fit_generator.

Если вы собираетесь использовать fit, go следующим образом:

...fit(train_generator, steps_per_epoch = len(train_generator), 
       epochs = 10, verbose = 1,
       validation_data = val_generator, validation_steps = len(val_generator))  

Наконец, вы должны охотиться за всем, что может быть None ( как подсказывает сообщение об ошибке) в вашем коде.

  • Проверьте, имеет ли каждая функция строку return.
  • Проверьте все входы вашего генератора в __init__.
  • Печать имен файлов внутри генератора.
  • Получите __len__ генератора.
  • Попробуйте получить предмет из генератора: x, y= train_generator[0]
...