Извлечение первого измерения тензора без использования функций get_shape, size и shape? - PullRequest
0 голосов
/ 03 сентября 2018

Я написал функцию потерь в Керасе. Он имеет два параметра, y_true и y_pred. Моя первая строка кода была: batch = y_pred.get_shape()[0]. Затем в моей переменной batch у меня первое измерение y_pred, поэтому я зациклился на range(batch) и написал то, что написал. Это не имеет значения. Дело в том, что когда я все компилирую, я получаю сообщение об ошибке, в котором говорится, что пакет не целое число, а тензор. Затем, как новичок в Tensorflow, я начал думать, как получить целое число из batch, которое должно быть целым числом, но тензором. Я пытался сделать sess.run(batch), но это совсем не помогло. Итак, моя проблема заключается в том, как получить целое число из тензора, который представляет целочисленную переменную. Я хотел бы использовать некоторую функцию, которая действительно дает мне целое число, а не тензор. Пожалуйста помоги. Вот мой код:

def custom_loss(y_true, y_pred):

    batch = y_pred.get_shape()[0]

    list_ones = returnListOnes(batch)
    tensor_ones = tf.convert_to_tensor(list_ones)

    loss = 0
    for i in range(batch):
      for j in range(S):
        for k in range(S):
            lista = returnListOnesIndex(batch, [j,k,0])

            lista_bx = returnListOnesIndex(batch, [j,k,1])
            lista_by = returnListOnesIndex(batch, [j,k,2])
            lista_bw = returnListOnesIndex(batch, [j,k,3])
            lista_bh = returnListOnesIndex(batch, [j,k,4])

            lista_to_tensor = tf.convert_to_tensor(lista)

            lista_bx_to_tensor = tf.convert_to_tensor(lista_bx)
            lista_by_to_tensor = tf.convert_to_tensor(lista_by)
            lista_bw_to_tensor = tf.convert_to_tensor(lista_bw)
            lista_bh_to_tensor = tf.convert_to_tensor(lista_bh)

            element = tf.reduce_sum(tf.multiply(lista_to_tensor,y_pred))
            element_true = tf.reduce_sum(tf.multiply(lista_to_tensor, y_true))

            element_bx = tf.reduce_sum(tf.multiply(lista_bx_to_tensor, y_pred))
            element_bx_true = tf.reduce_sum(tf.multiply(lista_bx_to_tensor, y_true))

            element_by = tf.reduce_sum(tf.multiply(lista_by_to_tensor, y_pred))
            element_by_true = tf.reduce_sum(tf.multiply(lista_by_to_tensor, y_true))

            element_bw = tf.reduce_sum(tf.multiply(lista_bw_to_tensor, y_pred))
            element_bw_true = tf.reduce_sum(tf.multiply(lista_bw_to_tensor, y_true))

            element_bh = tf.reduce_sum(tf.multiply(lista_bh_to_tensor, y_pred))
            element_bh_true = tf.reduce_sum(tf.multiply(lista_bh_to_tensor, y_true))

            distance = tf.square(tf.subtract(element, element_true))
            distance_bx = tf.square(tf.subtract(element_bx, element_bx_true))
            distance_by = tf.square(tf.subtract(element_by, element_by_true))
            distance_bw = tf.square(tf.subtract(element_bw, element_bw_true))
            distance_bh = tf.square(tf.subtract(element_bh, element_bh_true))

            suma = tf.add(distance, distance_bx)
            suma = tf.add(suma, distance_by)
            suma = tf.add(suma, distance_bw)
            suma = tf.add(suma, distance_bh)



            loss += tf.cond(tf.greater(element_true,0.),
                            lambda: suma,
                            lambda: distance)
    return loss

Как видите, я хочу, чтобы переменная batch была int, чтобы я мог зацикливаться и что-то делать. Я также использовал size и shape, и это тоже не сработало бы.

1 Ответ

0 голосов
/ 04 сентября 2018

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

Однако, если вы не можете сделать это, вы можете прибегнуть к tf.map_fn.

Из вашего кода я не вижу, где i используется внутри вашего цикла. Я предполагаю, что это ошибка (batch должно быть i внутри цикла, возможно) или моя собственная слепота - в противном случае вы можете просто умножить результат на размер пакета ...

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