Как выровнять размеры в Keras CNN, чтобы выходные данные соответствовали пользовательской функции потерь? - PullRequest
0 голосов
/ 09 апреля 2019

У меня проблемы с компиляцией этой модели.

Я пытаюсь реализовать VGG16, но я буду использовать пользовательскую функцию потерь.Целевая переменная имеет форму (?, 14, 14, 9, 6), где мы используем только двоичную кроссентропию на Y_train[:,:,:,:,0], а затем Y_train[:,:,:,:,1] в качестве переключателя, чтобы эффективно отключить потерю, делая этот мини-пакет - остальные будут использоваться в отдельной ветвинейронной сети.Это проблема двоичной классификации в этой ветке, поэтому я хочу, чтобы выходные данные имели форму (?, 14, 14, 9, 1).

. Я перечислил свою ошибку ниже.Можете ли вы объяснить, во-первых, что происходит не так, а во-вторых, как решить эту проблему?

Код модели

img_input = Input(shape = (224,224,3))

x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)

# # Block 2
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)

# Block 3
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)

# # Block 4
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)

# # Block 5
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)

x = Conv2D(512, (3, 3), padding='same', activation='relu', kernel_initializer='normal', name='rpn_conv1')(x)

x_class = Conv2D(9, (1, 1), activation='sigmoid', kernel_initializer='uniform', name='rpn_out_class')(x)

x_class = Reshape((14,14,9,1))(x_class)
model = Model(inputs=img_input, outputs=x_class)
model.compile(loss=rpn_loss_cls(), optimizer='adam')

Код функции потери:

def rpn_loss_cls(lambda_rpn_class=1.0, epsilon = 1e-4):

    def rpn_loss_cls_fixed_num(y_true, y_pred):
        return lambda_rpn_class * K.sum(y_true[:,:,:,:,0] 
                                * K.binary_crossentropy(y_pred[:,:,:,:,:], y_true[:,:,:,:,1]))
                                / K.sum(epsilon + y_true[:,:,:,:,0])
    return rpn_loss_cls_fixed_num

Ошибка:

ValueError: logits and labels must have the same shape ((?, ?, ?, ?) vs (?, 14, 14, 9, 1))

Примечание. На этом сайте я прочитал несколько вопросов с одной и той же ошибкой, но ни одно из решений не позволило скомпилировать мою модель.

Потенциальное решение:

Iпродолжил возиться с этим и обнаружил, что, добавив

y_true = K.expand_dims(y_true, axis=-1)

, я смог скомпилировать модель.Все еще сомнительно, что это будет работать правильно.

1 Ответ

0 голосов
/ 09 апреля 2019

Набор моделей Keras y_true Форма, эквивалентная входной форме. Поэтому, когда ваша функция потерь получает ошибку несоответствия формы. Так что вам нужно выровнять размеры с помощью expand_dims. Это, однако, должно быть сделано с учетом вашей модели архитектуры, данных и функции потерь. Код ниже будет скомпилирован.

def rpn_loss_cls(lambda_rpn_class=1.0, epsilon = 1e-4):

    def rpn_loss_cls_fixed_num(y_true, y_pred):
        y_true = tf.keras.backend.expand_dims(y_true, -1)
        return lambda_rpn_class * K.sum(y_true[:,:,:,:,0] 
                                * K.binary_crossentropy(y_pred[:,:,:,:,:], y_true[:,:,:,:,1]))
                                / K.sum(epsilon + y_true[:,:,:,:,0])
    return rpn_loss_cls_fixed_num
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...