Несовместимые формы Keras выдают, когда форма целевых данных и выходных слоев модели отличаются - PullRequest
0 голосов
/ 11 июля 2019

Мне жаль описывать проблему в несколько этапов, поскольку я не могу описать это в одном абзаце.

У меня main_model определено следующим образом:

input_layer=Input(shape=(896,896,3))
new_layer = Conv2D(filters=32, kernel_size=(3,3), padding="same")(input_layer)
new_layer = MaxPooling2D(pool_size=(2, 2), strides=(2,2), padding='same')(new_layer)
new_layer = Conv2D(filters=100, kernel_size=(k,k), dilation_rate=4, padding="same", name="dilation_1")(new_layer)
main_model = Model(input_layer, new_layer)

Форма выходного слоя - (448,448,100), и у меня нет целевого вектора (Y_train) этой формы. Я создаю целевые данные в тензорной форме из входного тензора и использую их для расчета потерь с помощью пользовательской функции потерь. Функция потерь использует другую модель Keras, которая имеет все постоянные ядра и применяется к одному и тому же входному тензору main_model для генерации целевого тензора.

y=input_layer #same input tensor from the main_model
y = Conv2D(filters=100, kernel_size=(3,3), padding="same", trainable=False, kernel_initializer='some_custom_method', name="non_trainable_layer")(y)
y=MaxPooling2D(pool_size=(2, 2), strides=(2,2), padding='same')(y)
constant_model=Model(input_layer, y)

constant_model.trainable=False
for l in constant_model.layers:
    l.trainable=False

И для пользовательской функции потерь, поскольку у меня нет данных y_true в форме (448,448,100), я генерирую y_true из input_layer, используя constant_model, показанный следующим образом:

def custom_loss_wrapper(constant_model):
    def custom_loss(y_true, y_pred):
        eval_true=constant_model(y_true)
        l= keras.losses.mean_absolute_error(eval_true, y_pred)
        return d
    return custom_loss

Тогда я compile и fit main_model:

main_model.compile(optimizer='adam',
          loss=custom_loss_wrapper(constant_model),
          metrics=['accuracy'])

history = model.fit(x=X_train, y=X_train, batch_size=2, ...)

Важно, чтобы мне нужно было предоставить y=X_train (что на самом деле y_true в функции потерь), поскольку этот X_train фактически используется для генерации main_model меток размером (448,448,100)

Но во время тренировки я получаю следующую ошибку:

...........

tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [2,896,896] vs. [2,448,448]
     [[Node: metrics_1/acc/Equal = Equal[T=DT_INT64, _device="/job:localhost/replica:0/task:0/device:GPU:0"](metrics_1/acc/ArgMax, metrics_1/acc/ArgMax_1)]]
     [[Node: loss_1/mul/_99 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_440_loss_1/mul", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Полагаю, есть проблема с несоответствием размеров в y_true и y_pred.

Однако, если я не использую слои MaxPooling в main_model и constant_model, т.е. форма выходного слоя равна 896,896,100, то ошибки нет.

Кто-нибудь может помочь мне выяснить, в чем проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...