Пользовательский DataGenerator - model.fit_generator: TypeError: только массивы размера 1 могут быть преобразованы в Python скаляры - PullRequest
0 голосов
/ 14 июля 2020

Я создал следующую модель:

def create_model(input_shape = (7, 7, 1280)):
    input_img = Input(shape=input_shape)
    backbone = Flatten(input_shape(7, 7, 1280)) (input_img)

    branches = []
    for i in range(8):
            branches.append(backbone)
            branches[i] = Dense(16000, activation = "relu", name="branch_"+str(i)+"_Dense_16000")(branches[i])
            branches[i] = Dense(128, activation = "relu", name="branch_"+str(i)+"_Dense_128")(branches[i])
            branches[i] = Dense(36, activation = "softmax", name="branch_"+str(i)+"_output")(branches[i])
        
    output = Concatenate(axis=1)(branches)
    output = Reshape((8, 36))(output)
    model = Model(input_img, output)

    return model

model = create_model()

Теперь я хотел бы применить эту модель к данным, которые генерируются Generator партиями. Поэтому я использовал предложенный DataGenerator от mujjiga с небольшой модификацией в def __getiteam__:

class DataGenerator(Sequence):
    def __init__(self, X, y, batch_size):
        self.X = X
        self.y = y
        self.batch_size = batch_size
        self.indexes = np.arange(len(self.X))

    def __len__(self):
        return int(np.floor(len(self.X) / self.batch_size))

    def __getitem__(self, index):
        idx = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
        idx = int(idx)    
        batch_X, batch_y = self.X[idx], self.y[idx]
        batch_X = np.array(batch_X)
        batch_y = np.array(batch_y)
        return batch_X, batch_y

После этого я применил DataGenerator к X_after_efn_train, y_train, X_after_efn_val и * 1013. *. X_after_efn_train и X_after_efn_val имеют форму (n, 7, 7, 1280) и значения X после запуска на них предварительно обученной модели Efficien tNet (https://keras.io/api/applications/efficientnet/#efficientnetb0 -функция ).

training_generator_after_efn = DataGenerator(X_after_efn_train, y_train, batch_size=32)
validation_generator_after_efn = DataGenerator(X_after_efn_val, y_val, batch_size=32)

Я скомпилировал модель с этим кодом:

model.compile(optimizer="rmsprop", loss="categorical_crossentropy", metrics=["accuracy"])

Теперь я попытался использовать model.fit_generator:

model.fit_generator(generator=training_generator_after_efn,
                    validation_data=validation_generator_after_efn,
                    steps_per_epoch = num_train_samples // 32,
                    validation_steps = num_val_samples // 32,
                    epochs = 10, workers=6, use_multiprocessing=True)

и получил эту ошибку:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-120-682a3512f3ac> in <module>()
      3                     steps_per_epoch = num_train_samples // 32,
      4                     validation_steps = num_val_samples // 32,
----> 5                     epochs = 10, workers=6, use_multiprocessing=True)

8 frames
<ipython-input-117-49b8453acf0a> in __getitem__(self, index)
     11     def __getitem__(self, index):
     12         idx = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
---> 13         idx = int(idx)
     14         batch_X, batch_y = self.X[idx], self.y[idx]
     15         batch_X = np.array(batch_X)

TypeError: only size-1 arrays can be converted to Python scalars

Большое спасибо!

1 Ответ

1 голос
/ 14 июля 2020

Модель (версия с уменьшенным масштабом)

def create_model(input_shape = (7, 7, 8)):
    input_img = keras.layers.Input(shape=input_shape)
    backbone = keras.layers.Flatten()(input_img)

    branches = []
    for i in range(8):
            branches.append(backbone)
            branches[i] = keras.layers.Dense(16, activation = "relu", name="branch_"+str(i)+"_Dense_16000")(branches[i])
            branches[i] = keras.layers.Dense(8, activation = "relu", name="branch_"+str(i)+"_Dense_128")(branches[i])
            branches[i] = keras.layers.Dense(4, activation = "softmax", name="branch_"+str(i)+"_output")(branches[i])
        
    output = keras.layers.Concatenate(axis=1)(branches)
    output = keras.layers.Reshape((8, 4))(output)
    model = keras.models.Model(input_img, output)

    return model

model = create_model()
model.compile(optimizer='sgd', loss='mse')

Фиктивные данные

X_train = np.random.randn(100,7,7,8)
X_val = np.random.randn(100,7,7,8)

y_train = np.random.randn(10,8,4)
y_val = np.random.randn(10,8,4)

Генератор данных

class DataGenerator(keras.utils.Sequence):
    def __init__(self, X, y, batch_size):
        self.X = X
        self.y = y
        self.batch_size = batch_size
        self.indexes = np.arange(len(self.X))

    def __len__(self):
        return int(np.floor(len(self.X) / self.batch_size))

    def __getitem__(self, index):
        idx = self.indexes[index*self.batch_size:(index+1)*self.batch_size]    
        batch_X, batch_y = self.X[idx], self.y[idx]
        return batch_X, batch_y

Наконец, подходит модель

training_generator = DataGenerator(X_train, y_train, batch_size=8)
validation_generator = DataGenerator(X_val, y_val, batch_size=8)

model.fit_generator(training_generator,epochs=10, validation_data=validation_generator)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...