Keras: model.fit() выдает ошибку для нескольких входных данных в siamese_model

#python #keras #deep-learning

#python #keras #глубокое обучение

Вопрос:

Я новичок в Keras и сиамской сетевой архитектуре. Я разработал сиамскую сеть с тремя входами и одним выходом следующим образом.

 def get_siamese_model(input_shape):


# Define the tensors for the three input phrases
anchor = Input(input_shape, name='anchor')
positive = Input(input_shape, name='positive')
negative = Input(input_shape, name='negative')

# Convolutional Neural Network
model = Sequential()
model.add(Conv2D(64, kernel_size=(2, 2), activation='relu', input_shape=input_shape, padding='same'))
model.add(Conv2D(32, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(Conv2D(16, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(Conv2D(8, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(Conv2D(4, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(Conv2D(2, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(Conv2D(1, kernel_size=(2, 2), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2,1)))
model.add(Flatten())

# Generate the encodings (feature vectors) for the three phrases
anchor_out = model(anchor)
positive_out = model(positive)
negative_out = model(negative)

# Add a customized layer to combine individual output
concat = Lambda(lambda tensors:K.concatenate((tensors[0],tensors[1],tensors[2]),0))
output = concat([anchor_out, positive_out, negative_out])


# Connect the inputs with the outputs
siamese_net = Model(inputs=[anchor,positive,negative],outputs=output)

#plot the model
plot_model(siamese_net, to_file='siamese_net.png',show_shapes=True, show_layer_names=True)

#Error optimization
siamese_net.compile(optimizer=Adam(), 
 loss=triplet_loss)

# return the model
return siamese_net
  

при использовании model.fit() я написал следующий код:

 model = get_siamese_model(input_shape)
X = {
    'anchor' : anchor,
    'positive' : positive,
    'negative' : negative
}

model.fit(np.asarray(X), Y)
  

Я получаю следующее сообщение об ошибке:

 ValueError: Error when checking model input: 
The list of Numpy arrays that you are passing to your model is not the size the model expected. 
Expected to see 3 array(s), but instead got the following list of 1 arrays: [array({'anchor': array([[[[ 4.49218750e-02]...
  

Приветствуется любая помощь. Заранее благодарю вас.

Комментарии:

1. Просто передайте X как словарь, предполагая, что ваши входные данные имеют одинаковые имена. В противном случае вам необходимо передать свои входные данные в виде списка: [i for i in X.values()] . Вы получаете эту ошибку, потому что np.asarray(X) возвращает один массив.

2. @LukeDeLuccia благодарю вас, сэр, за вашу помощь. Но когда я передаю входные данные с помощью list, я получаю ошибку: AttributeError: объект ‘tuple’ не имеет атрибута ‘ndim’, и если я передаю dictionary, я получаю ошибку: ValueError: данные для «input_4» не предоставлены. Нужны данные для каждого ключа в: [‘input_4’, ‘input_5’, ‘input_6’]

3. Вы должны включить определение вашей модели в вопрос. Ошибка словаря означает, что ваши входные данные не названы anchor, ... , а вместо этого названы input_4, ... . Кроме того, первая ошибка означает, что вы преобразовали в tuple вместо list . Если вы хотите, чтобы это временно заработало, вы можете передать словарь с anchor, positive, negative заменой на input_4, input_5, input_6 , хотя это не очень хорошее решение. Ваши входные имена должны быть anchor, positive, negative , когда вы их определяете.

4. Спасибо .. обновил код с именем .. но все еще выдает ошибку.. У кортежа нет атрибута ndim. Обновленный вопрос с определением модели. Спасибо..

Ответ №1:

Следующий код работает для меня. Поскольку ваши имена являются (anchor, positive, negative) , вы можете использовать их непосредственно в качестве ключей к вашему словарю при передаче входных данных. Кроме того, вам следует использовать concatenate слой в Keras вместо определения Lambda . Обратите внимание, что я изменил значение loss для целей этого примера.

 from keras.layers import Input, Conv2D, MaxPooling2D, Flatten, concatenate
from keras.models import Model, Sequential
from keras.optimizers import Adam
from keras.losses import mean_squared_error
import numpy as np

def get_siamese_model(input_shape):


    # Define the tensors for the three input phrases
    anchor = Input(input_shape, name='anchor')
    positive = Input(input_shape, name='positive')
    negative = Input(input_shape, name='negative')

    # Convolutional Neural Network
    model = Sequential()
    model.add(Conv2D(64, kernel_size=(2, 2), activation='relu', input_shape=input_shape, padding='same'))
    model.add(Conv2D(32, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(Conv2D(16, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(Conv2D(8, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(Conv2D(4, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(Conv2D(2, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(Conv2D(1, kernel_size=(2, 2), activation='relu', padding='same'))
    model.add(MaxPooling2D(pool_size=(2,1)))
    model.add(Flatten())

    # Generate the encodings (feature vectors) for the three phrases
    anchor_out = model(anchor)
    positive_out = model(positive)
    negative_out = model(negative)

    # Add a concatenate layer
    output = concatenate([anchor_out, positive_out, negative_out])

    # Connect the inputs with the outputs
    siamese_net = Model(inputs=[anchor,positive,negative],outputs=output)

    # Error optimization
    siamese_net.compile(optimizer=Adam(), loss=mean_squared_error)

    # Summarize model
    siamese_net.summary()

    # Return the model
    return siamese_net

input_shape = (100, 100, 1)
model = get_siamese_model(input_shape)
X = {'anchor': np.ones((5, 100, 100, 1)),   # define input as dictionary
     'positive': np.ones((5, 100, 100, 1)), 
     'negative': np.ones((5, 100, 100, 1))}
Y = np.ones((5, 15000))
model.fit(X, Y)                        # use a dictionary
model.fit([i for i in X.values()], Y)  # use a list
  

Комментарии:

1. Спасибо.. Это сработало. Я передавал Y как Y = shape (None, Нет), поскольку я работаю с внедрением и потерей триплета. Вот почему я получал ошибку, у кортежа нет атрибута ndim.