Тензор потока Керас cusomt потери парного вывода с метками - PullRequest
0 голосов
/ 19 марта 2020

(Первое сообщение, пожалуйста, будьте добры <3). </p>

Фон

В ядерной реакции часть энергии выделяется в виде излучения, то есть фотонов, и с 162 окружающими детекторами следов от них можно обнаружить. Проблема в том, что фотоны могут взаимодействовать с детекторами (например, комптоновское рассеяние и образование пар), так что один фотон, полученный в результате реакции, откладывает энергию, распределенную в нескольких детекторах.


Задача

Я хочу создать нейронную сеть, которая имеет:

  • вход: 162 значения энергии
  • выход: энергия, два угла направления для каждого исходного фотона

При обучении сети я буду использовать смоделированные данные, в которых я установлю максимальное количество исходных фотонов N, чтобы размер вывода был фиксированным (3xN).


Мой вопрос

При таком подходе я должен соединить упорядоченные результаты с упорядоченными метками при расчете потерь во время тренировки. Есть ли способ обойти это? То, что я пытался сделать, это реализовать эту сложную функцию потерь в тенор-потоке Keras, но я не уверен, работает ли это. Имея в виду сопряжение, я рассчитываю потери для каждой перестановки порядка меток и выбираю комбинацию с минимальными потерями. До сих пор я придумал следующее:

def energy_theta_phi_permutation_loss(y, y_):
    #Dividing into individual gamma-ray blocks
    num_splits = 2
    splited_y = tf.split(y, num_splits, axis=1)
    splited_y_ = tf.split(y_, num_splits, axis=1)
    temp_shape = tf.shape(tf.split(splited_y[0], 3, axis=1))

    #Calculates the loss for ONE of the possible permutations of the pairing
    def one_comb_loss(splited_y, splited_y_, index_list):
    temp = tf.zeros(temp_shape, dtype=tf.float32)

    for i in range(len(index_list)):
        E, theta, phi = tf.split(splited_y[i], 3, axis=1)
        E_, theta_, phi_ = tf.split(splited_y_[index_list[i]], 3, axis=1)

        tmp_loss_E = LAMBDA_ENERGY*tf.square(tf.divide(E-E_, E_+OFFSET_ENERGY))
        tmp_loss_theta = LAMBDA_THETA*tf.square(theta-theta_)
        tmp_loss_phi = LAMBDA_PHI*tf.square(tf.math.mod(phi - phi_ + np.pi, 2*np.pi) - np.pi)

        temp = temp + tmp_loss_E + tmp_loss_theta + tmp_loss_phi
    return temp

    #Loops over every possible pairing permutation and calculates the losses with one_comb_loss, gathered losses in list_of_tensors
    list_of_tensors = [one_comb_loss(splited_y, splited_y_, index_list) for index_list in it.permutations(range(num_splits), num_splits)]

    #Initialize infinite loss and then iterate over all the losses to find the lowest
    loss = tf.divide(tf.constant(1, dtype=tf.float32), tf.zeros(temp_shape, dtype=tf.float32))
    for i in range(len(list_of_tensors)):
        loss = tf.minimum(loss, list_of_tensors[i])
    return tf.reduce_mean(loss)

, который затем используется в

model.compile(optimizer=keras.optimizers.Adam(),
         loss=energy_theta_phi_permutation_loss,
         metrics=['accuracy'])

. Это дает действительно странные прогнозы, когда я запускаю это в FCN 128x10. во время теста запуска кода. Это даже хороший способ решить проблему? Есть ли у этой функции потерь градиент, который может рассчитывать керас?

Мне бы очень понравилась любая помощь и рекомендации! Я впервые использую tenorflow, поэтому мой опыт ограничен ^^

...