Перебрать тензор в пользовательской функции потерь - PullRequest
0 голосов
/ 02 апреля 2019

Мне нужно использовать эту функцию потерь для CNN, list_distance и list_residual являются выходными тензорами из скрытых слоев, которые важны для вычисления потерь, но когда я выполняю код, он возвращает мне эту ошибку

TypeError: Тензорные объекты могут повторяться только тогда, когда включено активное выполнение.Чтобы перебрать этот тензор, используйте tf.map_fn.

Есть ли другой способ перебрать тензоры без использования costruct x в X или преобразовать его в массив numpy или с помощью внутренней функции keras?


def DBL(y_true, y_pred, list_distances, list_residual, l=0.65):
    prob_dist = []
    Li = []

    # mean of the images power spectrum
    S = np.sum([np.power(np.abs(fp.fft2(residual)), 2)
                for residual in list_residual], axis=0) / K.shape(list_residual)[0]
    # log-ratio between the geometric and arithmetic of S
    R = np.log10((scistats.gmean(S) / np.mean(S)))

    for c_i, dis_i in enumerate(list_distances):
        prob_dist.append([
            np.exp(-dis_i) / sum([np.exp(-dis_j) if c_j != c_i else 0 for c_j, dis_j in enumerate(list_distances)])
        ])
    for count, _ in enumerate(prob_dist):
        Li.append(
            -1 * np.log10(sum([p_j for c_j, p_j in enumerate(prob_dist[count])
                               if y_pred[count] == 1 and count != c_j])))

    L0 = np.sum(Li)

    return L0 - l * R

1 Ответ

1 голос
/ 02 апреля 2019

Вам необходимо определить пользовательскую функцию для подачи в tf.map_fn() - Tensorflow dox

Функции Mapper отображают (как ни странно) существующий объект (тензор) в новый, используя определяемую вами функцию.

Они применяют пользовательскую функцию к каждому элементу в объекте, без всякого шумихи вокруг циклов for.

Например (не проверенный код, может не работать - на моем телефоне атм):

def custom(a):
    b = a + 1
    return b

original = np.array([2,2,2])
mapped = tf.map_fn(custom, original)
# mapped == [3, 3, 3] ... hopefully

Во всех примерах Tensorflow используются функции lambda, поэтому вам может потребоваться определить ваши функции таким образом, если вышеперечисленное не работает. Пример тензорного потока:

elems = np.array([1, 2, 3, 4, 5, 6])
squares = map_fn(lambda x: x * x, elems)
# squares == [1, 4, 9, 16, 25, 36]

Редактировать:

Кроме того, функции карты намного проще распараллелить, чем для циклов - предполагается, что каждый элемент объекта обрабатывается уникально - так что вы можете увидеть повышение производительности, используя их.

Редактировать 2:

Что касается части "уменьшить сумму, но не по этому индексу", я настоятельно рекомендую вам начать оглядываться на матричные операции ... Как уже упоминалось, map функции работают поэлементно - они не знают о других элементах , Функция reduce - это то, что вам нужно, но даже если вы пытаетесь и суммируете «не этот индекс», они даже финишируют, а тензорный поток строится на основе матричных операций ... Не парадигмы MapReduce.

Что-то в этом роде может помочь:

sess = tf.Session()
var = np.ones([3, 3, 3]) * 5

zero_identity = tf.linalg.set_diag(
    var, tf.zeros(var.shape[0:-1], dtype=tf.float64)
)
exp_one = tf.exp(var)
exp_two = tf.exp(zero_identity)
summed = tf.reduce_sum(exp_two, axis = [0,1])
final = exp_one / summed

print("input matrix: \n", var, "\n")
print("Identities of the matrix to Zero: \n", zero_identity.eval(session=sess), "\n")
print("Exponential Values numerator: \n", exp_one.eval(session=sess), "\n")
print("Exponential Values to Sum: \n", exp_two.eval(session=sess), "\n")
print("Summed values for zero identity matrix\n ... along axis [0,1]: \n", summed.eval(session=sess), "\n")
print("Output:\n", final.eval(session=sess), "\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...