Ошибка сцепления: добавленный слой должен быть экземпляром класса Layer - PullRequest
0 голосов
/ 30 августа 2018

Я работаю над фрагментом в Керасе, где у меня есть две последовательные модели, которые должны быть объединены в третью, которая является моей последней моделью. Фрагмент был собран с версией Keras, в которой был разрешен метод Merge, поэтому сейчас я пытаюсь заменить его методом concatenate на axis = 0, поэтому поведение такое же, как и в Merge (). Несмотря на все эти изменения, я получаю следующую трассировку стека в качестве вывода:

Traceback (most recent call last):
  File ".\CaptionGenerator.py", line 738, in <module>
    caption.BeamPredictor('image.PNG')
  File ".\CaptionGenerator.py", line 485, in BeamPredictor
    self.SetNeuralNetworksWithoutApi()
  File ".\CaptionGenerator.py", line 433, in SetNeuralNetworksWithoutApi
    Activation('softmax')
  File "D:\Anaconda\lib\site-packages\keras\engine\sequential.py", line 92, in __init__
    self.add(layer)
  File "D:\Anaconda\lib\site-packages\keras\engine\sequential.py", line 131, in add
    'Found: ' + str(layer))
TypeError: The added layer must be an instance of class Layer. Found: Tensor("concatenate_1/concat:0", shape=(?, 40, 300), dtype=float32)

Код фрагмента:

def SetNeuralNetworksWithoutApi(self):

    embedding_size = 300

    image_model = Sequential([
    Dense(embedding_size, input_shape=(2048,), activation='relu'),
    RepeatVector(self.MaxCaptionLength)
    ])

    caption_model = Sequential([
    Embedding(self.numberOfWords, embedding_size, input_length=self.MaxCaptionLength),
    LSTM(256, return_sequences=True),
    TimeDistributed(Dense(300))
    ])

    image_in = Input(shape=(2048,))
    caption_in = Input(shape=(self.numberOfWords,))
    merged = concatenate([image_model(image_in), caption_model(caption_in)])
    latent = Bidirectional(LSTM(256, return_sequences=False))(merged)
    out = Dense(self.numberOfWords, activation='softmax')(latent)
    self.softmaxModel = Model([image_in, caption_in], out)

    self.softmaxModel.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'])
    self.softmaxModel.summary()

Я не могу понять причину, по которой результат моего concatenate () не должен быть экземпляром класса Layer, учитывая, что в объекте, возвращаемом из функции, которая, согласно Документации, является Tensor, нет свойства layer , Есть ли способ исправить это, не переходя на API? Спасибо.

1 Ответ

0 голосов
/ 30 августа 2018

Вам нужно переключиться на функциональный API хотя бы для окончательной модели, потому что Sequential предназначен для одиночного входа, вы вводите в него 2 тензора, что не собирается работать Это потому, что Sequential создает один заполнитель для своего ввода. Что-то вроде:

image_model = Sequential([
Dense(embedding_size, input_shape=(2048,), activation='relu'),
RepeatVector(self.MaxCaptionLength)
])

caption_model = Sequential([
Embedding(self.numberOfWords, embedding_size, input_length=self.MaxCaptionLength),
LSTM(256, return_sequences=True),
TimeDistributed(Dense(300))
])

image_in = Input(shape=(2048,))
caption_in = Input(shape=(MaxCaptionLength, numberOfWords))
merged = concatenate([image_model(image_in), caption_model(caption_in)], axis=0)
latent = Bidirectional(LSTM(256, return_sequences=False))(merged)
out = Dense(self.numberOfWords, activation='softmax')(latent)
final_model = Model([image_in, caption_in], out)

final_model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'])
final_model.summary()

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

...