(Первое сообщение, пожалуйста, будьте добры <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, поэтому мой опыт ограничен ^^