То, чего я сейчас пытаюсь достичь, - это создать пользовательскую функцию потерь в Keras, которая принимает два тензора (y_true, y_pred)
с формами (None, None, None)
и (None, None, 3)
соответственно. Однако None
таковы, что две фигуры всегда равны для каждого (y_true, y_pred)
. Из этих тензоров я хочу получить две матрицы расстояний, которые содержат квадраты расстояний между каждой возможной парой точек (третье измерение длины 3 содержит пространственные значения x, y и z) внутри них, а затем вернуть разницу между этими матрицами расстояний. Первый код, который я попробовал, был такой:
def distanceMatrixLoss1(y_true, y_pred):
distMatrix1 = [[K.sum(K.square(y_true[i] - y_true[j])) for j in range(i + 1, y_true.shape[1])] for j in range(y_true.shape[1])]
distMatrix2 = [[K.sum(K.square(y_pred[i] - y_pred[j])) for j in range(i + 1, y_pred.shape[1])] for j in range(y_pred.shape[1])]
return K.mean(K.square(K.flatten(distMatrix1) - K.flatten(distMatrix2)))
(K - бэкэнд TensorFlow.) Излишне говорить, что я получил следующую ошибку:
'NoneType' object cannot be interpreted as an integer
Это понятно, так как range(None)
не имеет большого смысла, а y_true.shape[0]
или y_pred.shape[0]
- это None
. Я искал, сталкивались ли другие люди с той же проблемой или нет, и я обнаружил, что могу использовать функцию scan
TensorFlow:
def distanceMatrixLoss2(y_true, y_pred):
subtractYfromXi = lambda x, y: tf.scan(lambda xi: K.sum(K.square(xi - y)), x)
distMatrix = lambda x, y: K.flatten(tf.scan(lambda yi: subtractYfromXi(x, yi), y))
distMatrix1 = distMatrix(y_true, y_true)
distMatrix2 = distMatrix(y_pred, y_pred)
return K.mean(K.square(distMatrix1-distMatrix2))
То, что я получил от этого, - это другая ошибка, которую я не полностью понять.
TypeError: <lambda>() takes 1 positional argument but 2 were given
Так что это пошло в тра sh тоже. Моей последней попыткой было использование функции map_fn
бэкэнда:
def distanceMatrixLoss3(y_true, y_pred):
subtractYfromXi = lambda x, y: K.map_fn(lambda xi: K.sum(K.square(xi - y)), x)
distMatrix = lambda x, y: K.flatten(K.map_fn(lambda yi: subtractYfromXi(x, yi), y))
distMatrix1 = distMatrix(y_true, y_true)
distMatrix2 = distMatrix(y_pred, y_pred)
return K.mean(K.square(distMatrix1-distMatrix2))
Это не выдало ошибку, но когда началось обучение, потеря была постоянной 0 и оставалась такой же. Так что теперь у меня нет идей, и я прошу вас помочь мне решить эту проблему. Я уже пытался сделать то же самое в Mathematica и тоже не смог ( здесь - ссылка на соответствующий вопрос, если это помогает).