Как передать метки нескольких входов в Keras функции model.fit ()? - PullRequest
1 голос
/ 21 октября 2019

Я использую функциональный API Keras. Я хочу создать модель, которая будет работать на нескольких входах, где входы имеют разные метки. Ниже приведена модель, которую я хочу создать:

model

Вот что я пробовал:

import numpy as np
from keras import backend as K
from keras import losses
from keras.models import Model
from keras.utils import to_categorical, plot_model
from keras.layers import Input, Dense, Conv1D, Flatten
from keras.layers.merge import concatenate


# Create data
NUM_TRAINING_SAMPLES_INPUT_1 = 100
NUM_TRAINING_SAMPLES_INPUT_2 = 100
NUM_FEATURES_INPUT_1 = 144
NUM_FEATURES_INPUT_2 = 145
NUM_CLASSES = 15

# Create train data
train_X_1 = np.random.randint(low=0, high=100, size=(NUM_TRAINING_SAMPLES_INPUT_1, NUM_FEATURES_INPUT_1, 1), dtype='int64')
train_X_2 = np.random.randint(low=0, high=100, size=(NUM_TRAINING_SAMPLES_INPUT_2, NUM_FEATURES_INPUT_2, 1), dtype='int64')

# Create labels
train_Y_1 = np.random.randint(low=0, high=NUM_CLASSES, size=(NUM_TRAINING_SAMPLES_INPUT_1, 1), dtype='int64')
train_Y_2 = np.random.randint(low=0, high=NUM_CLASSES, size=(1, 5), dtype='int64')

# Convert labels to categorical
train_Y_1 = to_categorical(train_Y_1, num_classes=NUM_CLASSES)
train_Y_2 = to_categorical(train_Y_2, num_classes=NUM_CLASSES)

# Create model architecture
input_1 = Input(shape=(train_X_1.shape[1], train_X_1.shape[2]))
convl1_input_1 = Conv1D(filters=96, kernel_size=12, strides=2, padding='valid', activation='relu')(input_1)
flat1 = Flatten()(convl1_input_1)

input_2 = Input(shape=(train_X_2.shape[1], train_X_2.shape[2]))
convl1_input_2 = Conv1D(filters=96, kernel_size=13, strides=2, padding='valid', activation='relu')(input_2)
flat2 = Flatten()(convl1_input_2)

# Merge inputs
merge = concatenate([flat1, flat2])

# interpretation model
hidden = Dense(10, activation='relu')(merge)
output = Dense(NUM_CLASSES, activation='sigmoid')(hidden)
model = Model(inputs=[input_1, input_2], outputs=output)

# Plot model
plot_model(model, to_file='multiple_inputs_dummy.png')

# Compile model
model.compile(loss=losses.categorical_crossentropy, optimizer='adam', metrics=["accuracy"])

# Fit model 
BATCH_SIZE = 32
EPOCHS = 3
SHUFFLE = False
VERBOSE = 1
model.fit([train_X_1, train_X_2], [train_Y_1, train_Y_2], epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=VERBOSE, shuffle=SHUFFLE)

Это дает мнеошибка ниже,

ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 1 arrays but instead got the following list of 2 arrays: [array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ..., 
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0...

Как правильно назначать метки в функции model.fit()?

1 Ответ

2 голосов
/ 21 октября 2019

Ваша модель имеет только один выход. Это означает, что для каждой пары входов создается только одна «метка». Используя стандартные функции потерь, эту метку можно сравнить только с одной меткой истинности заземления, поэтому каждая пара входов может иметь только одну метку.

Чтобы исправить это, у вас есть несколько вариантов, но ни одна из них не является быстрой иeasy fix.

  1. Узнайте, как объединить каждую пару базовых меток истинности в одну метку, а затем передать эти комбинированные метки в fit().
  2. Измените модель так, чтобы онадва выхода.
  3. Я не пробовал этого, но вы могли бы сделать пользовательскую функцию потерь, которая сравнивает каждую выходную метку с парой меток истинной земли.

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

...