Мне жаль описывать проблему в несколько этапов, поскольку я не могу описать это в одном абзаце.
У меня 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
, то ошибки нет.
Кто-нибудь может помочь мне выяснить, в чем проблема?