Понимание сиамской сети Keras MNIST и ее адаптация к тройкам - PullRequest
0 голосов
/ 20 апреля 2020

Я в настоящее время адаптирую эту сиамскую сеть в Python с помощью Keras. Тем не менее, в настоящее время я не понимаю, как работает потеря (не сама функция, но какие параметры передаются, где)

Хорошо, теперь пошагово, как я думаю, это работает:

distance = Lambda(euclidean_distance,
              output_shape=eucl_dist_output_shape)([processed_a, processed_b])

Это строка, в которой выходы обеих отдельных сетей объединяются, и пользовательский слой применяет следующие функции:

def euclidean_distance(vects):
    x, y = vects
    sum_square = K.sum(K.square(x - y), axis=1, keepdims=True)
    return K.sqrt(K.maximum(sum_square, K.epsilon()))


def eucl_dist_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1[0], 1)

Таким образом, когда вход для этого слоя равен (128, 128), результат будет ( 128, 1). На последнем шаге потери рассчитываются следующим образом:

def contrastive_loss(y_true, y_pred):
    '''Contrastive loss from Hadsell-et-al.'06
    http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
    '''
    margin = 1
    square_pred = K.square(y_pred)
    margin_square = K.square(K.maximum(margin - y_pred, 0))
    return K.mean(y_true * square_pred + (1 - y_true) * margin_square)

Здесь предсказанный вектор 128D сравнивается с вектором истинности земли 128D.

Теперь я изменил слой Lambda на:

distance = Lambda(euclidean_distance,
                  output_shape=eucl_dist_output_shape)([processed_a, processed_b, processed_c])

, поэтому у меня теперь три сети со следующими адаптированными функциями (которые должны просто объединить три выхода в один выход с формой (128, 3)):

def euclidean_distance(vects):
    return vects


def eucl_dist_output_shape(shapes):
    shape1, shape2, shape3 = shapes
    return (shape1, shape2, shape3)

а затем новая функция потерь:

def loss_desc_triplet(vects, margin=5):
    """Triplet loss.
    """
    d1, d2, d3 = vects
    d_pos = K.sqrt(K.sum(K.square(d1 - d2), axis=1))
    pair_dist_1_to_3 = K.sqrt(K.sum(K.square(d1 - d3), axis=1))
    d_neg = pair_dist_1_to_3

    return Activation.relu(d_pos - d_neg + margin)

Но теперь я получаю эту ошибку:

Файл "DeepLearningWithAugmentationWithTriplets.py", строка 233, в output_shape = eucl_dist_output_shape) ([обработано_a , Обработано_b, обработано_c])

Файл "lib / python3 .7 / site-packages / keras / engine / base_layer.py", строка 497, в вызов arguments = user_kwargs)

Файл "lib / python3 .7 / site-packages / keras / engine / base_layer.py", строка 565, в _add_inbound_node output_tensors [i] ._ keras_shape = output_shapes [i]

IndexError: список индексов выходит за пределы диапазона

Но я не уверен, что является причиной есть.

1 Ответ

0 голосов
/ 20 апреля 2020

Я исправил проблему, объединив выходные данные:

merged_vector = concatenate([processed_a, processed_b, processed_c], axis=-1, name='merged_layer')

, а затем разобрав вектор в моей функции потерь:

d1 = y_pred[:,0:128]
d2 = y_pred[:,128:256]
d3 = y_pred[:,256:384]

Хотя я не уверен, что это лучшее решение.

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