Большое спасибо за подробное объяснение, вы только что спасли мой день.

ичок в Керасе. Мне нужна помощь в написании пользовательской функции потерь в кератах с бэкэндом TensorFlow для следующего уравнения потерь.

Параметры, передаваемые в функцию потерь:

y_true будет иметь форму(batch_size, N, 2), Здесь мы проходим N(x, y) координаты в каждом образце в партии.y_pred будет иметь форму(batch_size, 256, 256, N), Здесь мы передаем N предсказанных тепловых карт256 x 256 пикселей в каждом образце в пакете.

i[0, 255]

j[0, 255]

Mn(i, j) представляет значение в месте расположения пикселя(i, j) тогдаго прогнозируемая тепловая карта.

Mn∼(i, j) = Guassian2D((i, j), y_truen, std) где

std = standard deviation, то же стандартное отклонение для обоих размеров (5 пикселей).

y_truen затемго (х, у) координата. Это среднее.

$18 будет иметь форму19$Оценка позы человека.

Примечание: я упомянул batch_size в форме y_true и y_pred. Я предположил, что Keras вызывает функцию потерь для всей партии, а не для отдельных выборок в партии. Поправь меня, если я ошибаюсь.

def l2_loss(y_true, y_pred):
     loss = 0
     n = y_true.shape[0]
     for j in range(n):
        for i in range(num_joints):
            yv, xv = tf.meshgrid(tf.arange(0, im_height), tf.arange(0, im_width))
            z = np.array([xv, yv]).transpose(1, 2, 0)
            ground = np.exp(-0.5*(((z - y_true[j, i, :])**2).sum(axis=2))/(sigma**2))
            loss = loss + np.sum((ground - y_pred[j,:, :, i])**2)
     return loss/num_joints

Это код, который я написал до сих пор. Я знаю, что это не будет работать, так как мы не можем использовать прямые нудистые ndarrays внутри функции потери keras. Также мне нужно устранить петли!

 Alex09 дек. 2017 г., 16:05
Да, я добавил свой код, пожалуйста, проверьте!
 desertnaut09 дек. 2017 г., 14:23
ТАКне служба написания кода; Пожалуйста, покажите, что вы уже пробовали, иконкретное программирование проблемы, с которыми вы сталкиваетесь ...

Ответы на вопрос(1)

Решение Вопроса

д-функции Keras. Единственное, на что стоит обратить внимание, это настроить правильную форму трансляции.

def l2_loss_keras(y_true, y_pred):
    # set up meshgrid: (height, width, 2)
    meshgrid = K.tf.meshgrid(K.arange(im_height), K.arange(im_width))
    meshgrid = K.cast(K.transpose(K.stack(meshgrid)), K.floatx())

    # set up broadcast shape: (batch_size, height, width, num_joints, 2)
    meshgrid_broadcast = K.expand_dims(K.expand_dims(meshgrid, 0), -2)
    y_true_broadcast = K.expand_dims(K.expand_dims(y_true, 1), 2)
    diff = meshgrid_broadcast - y_true_broadcast

    # compute loss: first sum over (height, width), then take average over num_joints
    ground = K.exp(-0.5 * K.sum(K.square(diff), axis=-1) / sigma ** 2)
    loss = K.sum(K.square(ground - y_pred), axis=[1, 2])
    return K.mean(loss, axis=-1)

Чтобы проверить это:

def l2_loss_numpy(y_true, y_pred):
     loss = 0
     n = y_true.shape[0]
     for j in range(n):
        for i in range(num_joints):
            yv, xv = np.meshgrid(np.arange(0, im_height), np.arange(0, im_width))
            z = np.stack([xv, yv]).transpose(1, 2, 0)
            ground = np.exp(-0.5*(((z - y_true[j, i, :])**2).sum(axis=2))/(sigma**2))
            loss = loss + np.sum((ground - y_pred[j,:, :, i])**2)
     return loss/num_joints

batch_size = 32
num_joints = 10
sigma = 5
im_width = 256
im_height = 256

y_true = 255 * np.random.rand(batch_size, num_joints, 2)
y_pred = 255 * np.random.rand(batch_size, im_height, im_width, num_joints)

print(l2_loss_numpy(y_true, y_pred))
45448272129.0

print(K.eval(l2_loss_keras(K.variable(y_true), K.variable(y_pred))).sum())
4.5448e+10

Номер усекается по умолчаниюdtype float32. Если вы запустите его сdtype установить в float64:

y_true = 255 * np.random.rand(batch_size, num_joints, 2)
y_pred = 255 * np.random.rand(batch_size, im_height, im_width, num_joints)

print(l2_loss_numpy(y_true, y_pred))
45460126940.6

print(K.eval(l2_loss_keras(K.variable(y_true), K.variable(y_pred))).sum())
45460126940.6

РЕДАКТИРОВАТЬ:

Кажется, что Керас требуетy_true а такжеy_pred иметь одинаковое количество измерений. Например, на следующей модели тестирования:

X = np.random.rand(batch_size, 256, 256, 3)
model = Sequential([Dense(10, input_shape=(256, 256, 3))])
model.compile(loss=l2_loss_keras, optimizer='adam')
model.fit(X, y_true, batch_size=8)

ValueError: Cannot feed value of shape (8, 10, 2) for Tensor 'dense_2_target:0', which has shape '(?, ?, ?, ?)'

Чтобы справиться с этой проблемой, вы можете добавить фиктивное измерение сexpand_dims до кормленияy_true в модель:

def l2_loss_keras(y_true, y_pred):
    ...

    y_true_broadcast = K.expand_dims(y_true, 1)  # change this line

    ...

model.fit(X, np.expand_dims(y_true, axis=1), batch_size=8)
 C.Lee10 мар. 2018 г., 21:18
Большое спасибо за подробное объяснение, вы только что спасли мой день.

Ваш ответ на вопрос