Увеличение изображения в смешанной функциональной модели Keras

Я создал смешанную модель в Keras, создав веса для метаданных и данных изображения, а затем объединил их для классификации. Вот модель:

      Model: "model_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_5 (InputLayer)            [(None, 80, 120, 3)] 0                                            
__________________________________________________________________________________________________
xception (Functional)           (None, 3, 4, 2048)   20861480    input_5[0][0]                    
__________________________________________________________________________________________________
input_4 (InputLayer)            [(None, 10)]         0                                            
__________________________________________________________________________________________________
conv2d_9 (Conv2D)               (None, 3, 4, 8)      409608      xception[0][0]                   
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 4)            44          input_4[0][0]                    
__________________________________________________________________________________________________
global_average_pooling2d_1 (Glo (None, 8)            0           conv2d_9[0][0]                   
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 12)           0           dense_3[0][0]                    
                                                                 global_average_pooling2d_1[0][0] 
__________________________________________________________________________________________________
dense_4 (Dense)                 (None, 4)            52          concatenate_1[0][0]              
__________________________________________________________________________________________________
dense_5 (Dense)                 (None, 1)            5           dense_4[0][0]                    
==================================================================================================
Total params: 21,271,189
Trainable params: 21,216,661
Non-trainable params: 54,528
__________________________________________________________________________________________________

Я решил увеличить изображения из-за дисбаланса. Я использовал следующий ImageDataGenerator:

      aug = ImageDataGenerator(rescale=1/255.,
                        rotation_range=180,
                        height_shift_range=0.2,
                        width_shift_range=0.2,
                        brightness_range=[0.5,1.5],
                        channel_shift_range=100.0,
                        horizontal_flip=True,
                        vertical_flip=True,
                        shear_range=45.0)

Затем я скомпилировал и попытался обучить модель, используя ImageDataGenerator().flow():

      epochs = 10
BATCH_SIZE = 20
flow = aug.flow(img_train, y_train, batch_size=BATCH_SIZE)

history = model.fit([meta_train, flow], y_train, epochs=epochs, batch_size=100, validation_data=([meta_test, img_test], y_test), class_weight=class_weight)

Это дает мне ошибку:

      ValueError: Failed to find data adapter that can handle input: (<class 'list'> containing values of
types {"<class 'pandas.core.frame.DataFrame'>", "<class 'tensorflow.python.keras.preprocessing.image.NumpyArrayIterator'>"}),
<class 'numpy.ndarray'>

Я пробовал несколько версий кода, но я недостаточно знаком с серверной частью, чтобы правильно диагностировать проблему. Кто-нибудь может мне с этим помочь?

2 ответа

во-первых, если вы генерируете следующие массивы, ваши модели работают без ошибок;

      import tensorflow as tf
import numpy as np
LEARNING_RATE = 0.001

# Define inputs
meta_inputs = tf.keras.layers.Input(shape=(10,))
img_inputs = tf.keras.layers.Input(shape=(80,120,3,))

# Model 1
meta_layer1 = tf.keras.layers.Dense(4, activation='relu')(meta_inputs)

# Model 2
xception_layer = tf.keras.applications.Xception(include_top=False, input_shape=(80,120,3,))(img_inputs)
img_conv_layer1 = tf.keras.layers.Conv2D(8, kernel_size=(5,5), padding='same', activation='relu')(xception_layer)
img_gap_layer = tf.keras.layers.GlobalAveragePooling2D()(img_conv_layer1)
# img_sdense_layer = Dense(4, activation='relu')(img_gap_layer)

# Merge models
merged_layer = tf.keras.layers.Concatenate()([meta_layer1, img_gap_layer])
merged_dense_layer = tf.keras.layers.Dense(4, activation='relu')(merged_layer)
merged_output = tf.keras.layers.Dense(1, activation='sigmoid')(merged_dense_layer)


# Define functional model
model = tf.keras.models.Model(inputs=[meta_inputs, img_inputs], outputs=merged_output)

# Compile model
auc = tf.keras.metrics.AUC(name = 'auc')
model.compile(tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE), loss='binary_crossentropy', metrics=[auc])
model.summary()

Давайте сгенерируем массивы, как показано ниже;

      y_array = np.zeros((23188, 1))
train_array = np.zeros((23188, 80, 120,3))
meta_array = np.zeros((23188, 10))

Теперь протестируйте вашу модель;

      model.fit(x = [meta_array, train_array], y = y_array, epochs = 1)

как вы можете видеть, это работает

      >>> model.fit(x = [meta_array, train_array], y = y_array, epochs = 1)
2021-05-17 10:30:03.430303: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2021-05-17 10:30:03.447843: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3093120000 Hz
 47/725 [>.............................] - ETA: 6:52 - loss: 0.6818 - auc: 0.0000e+00

Теперь проблема в ваших входах:

(1) сначала преобразуйте все ваши метаданные в массив, допустим, у него есть пакет из 1000, в результате он должен иметь форму meta_train.shape является (1000,10)

(2) ваш img_train.shape является (1000,80,120,3)

(3) ваш y_train.shape является (1000,1)

здесь 1000 также может быть 23188. Но предположим, что у вас 1000 изображений, y_train(цель) и 1000 метаданных.

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

      import tensorflow as tf
import numpy as np
import time

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

      y_train = np.zeros((1000, 1))
img_train = np.zeros((1000, 80, 120,3))
meta_train= np.zeros((1000, 10))

aug = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255.,
                        rotation_range=180,
                        height_shift_range=0.2,
                        width_shift_range=0.2,
                        brightness_range=[0.5,1.5],
                        channel_shift_range=100.0,
                        horizontal_flip=True,
                        vertical_flip=True,
                        shear_range=45.0)

aug.fit(img_train)
# NOTE; change batch_size to 32 if your img_train is too high or your device has less memory
# set shuffle to false, you have to concatenate at each loop the meta_train and y_train for each image, so do not shuffle the images!
imagenerator = aug.flow(img_train, batch_size = img_train.shape[0], shuffle=False, sample_weight=None, seed=123, save_to_dir=None, save_prefix="", save_format="png", subset=None)

new_meta = meta_train.copy() # concatenate meta_train at each loop to new_meta
new_y = y_train.copy()       # concatenate y_train at each loop to new_y


batches = 0
#let's iterate 5 times.
for x_batch in imagenerator:
    print(batches, time.strftime("%Y:%m%d-%H:%M:%S"))
    batches += 1
    img_train = np.concatenate((img_train, x_batch), axis = 0)
    new_meta = np.concatenate((new_meta, meta_train), axis = 0) # concatenate corresponding meta data
    new_y = np.concatenate((new_y, y_train), axis = 0) #concatenate corresponding label/target data!
    if batches >= 5:
        break

model.fit(x = [new_meta, img_train], y = new_y, epochs = 1, batch_size = 32)

ПРИМЕЧАНИЕ: вы можете перетасовать свои данные, как показано ниже, прежде чем использовать их в model.fit

      idxs = np.array([x for x in range(img_train.shape[0])])
np.random.shuffle(idxs)

img_train = img_train[idx]
new_y = new_y[idx]
new_meta = new_meta[idx]

Это не прямой ответ, но поможет решить вопрос. Отсутствует информация для решения вашей проблемы.

НО во-первых : самая очевидная проблема; Вы предоставляете meta_trainкоторый является фреймом данных pandas. Преобразуйте его в массив. Пожалуйста, сначала попробуйте это.

Во-вторых , если у вас все еще есть проблема, то model.fit не может обрабатывать список [meta_train, flow], то вам, возможно, придется найти способ предоставить два ввода, которые будут обрабатываться вашей моделью.

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

(1) Ваш код для модели, даже если одна и та же модель может быть сгенерирована на основе предоставленного резюме.

(2) форма y_train.

Другие вопросы по тегам