Я пытаюсь обучить и протестировать сиамскую сеть, и у меня есть положительные и отрицательные пары изображений.
Когда я запускаю модель, в какой-то момент я получаю:
InvalidArgumentError: Nan в сводной гистограмме для: расстояние
В некоторых прогонах это происходит в самом начале, шаг 4 или 5, в то время как в некоторых других запусках это происходит через несколько шагов.
Аргументы модели:
n_steps: 600
share_weights: True
маржа: 100
порог: 0,3
стоимость обучения: 0,001
размер партии: 64
Я использую Adam Optimizer.
Способ вычисления расстояния:
loss, distance_0 = contrastive_loss(self.net0.output(), self.net1.output(), self.y, self.margin)
distance = network_layers.get_scaled_tensor(self.distance_0, 'scaled_distance')
Я использую контрастную потерю с этим кодом:
def contrastive_loss(out0, out1, y_true, margin):
with tf.name_scope('contrastive_loss'):
d = tf.reduce_sum(tf.square(tf.subtract(out0, out1)), 1)
d_sqrt = tf.sqrt(1e-6 + d)
loss = (y_true * d) + ((1 - y_true) * tf.square(tf.maximum(tf.subtract(margin, d_sqrt), 0)))
loss = tf.reduce_mean(loss) # Note: constant component removed (/2)
return loss, d_sqrt
А позже я выполню масштабирование на тензоре расстояния.
def get_scaled_tensor(inputs, name, vmin=0., vmax=1.):
"""
:param inputs: input tensor
:param name: name of tensor
:param vmin: min value for scaling
:param vmax: max value for scaling
:return: a tensor to scale inputs to the interval of [vmin, vmax]
"""
inputs_min = tf.reduce_min(inputs)
inputs_max = tf.reduce_max(inputs)
if inputs_min == inputs_max:
return inputs
scaled = (inputs - inputs_min) / (inputs_max - inputs_min)
scaled = tf.add(scaled * (vmax - vmin), vmin, name=name)
return scaled
Я пытался распечатать тензор расстояния на каждом шаге, чтобы увидеть, генерируются ли какие-либо значения NaN. Прямо перед ошибкой вот что у меня есть:
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
Как видите, в тензоре все значения равны 0, кроме одного значения, равного 1.
То же самое происходит в разных сериях, только позиция «1» меняется.
Например, другой тензор расстояния прямо перед ошибкой:
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
Вот некоторые из тензоров расстояния из предыдущих шагов, которые успешно выполняются:
Шаг 0:
[0,03674867 0,00787617 0,2477202 0,3154928 0,10931009 0,2735154
0,13083686 0,14834054 0,09842198 0,09132127 0,0856637 0,6076441
0,100755 0,09179091 0,11605983 0,3297588 0,28090978 0,01025809
0,12361664 0,11507085 0,06570645 0,0616716 0,12276769 0,12957902
0,2234131 0,5456302 0,16503233 0,03914422 0,15807444 0,9947304
0,5870102 0,17302574 0,15670143 0,07926143 0,12775105 0,06380077
0,5533038 0,7977735 0,22019525 0,07887711 0,18530448 0,12723611
0,05254128 0,46612477 0,5007302 0. 0,03045994 0.
0,25195697 0,03005651 0,900458 0. 0,36718735 0,15492864
0,42535746 0,151013 0,7009924 0,12371618 0,05326976 0,04238863
0.08139887 1. 0.14789903 0.02012084]
Шаг 1:
[0.00000000e + 00 5,47710210e-02 9,02850509e-01 8,88542950e-01
4.31583114e-02 6.15703311e-09 6.10682368e-01 9.25455615e-02
1.00000000e + 00 5.41838706e-01 4.48709205e-02 2.73277704e-02
2.96332520e-02 1.20817451e-02 2.27759629e-02 3.11016534e-02
6.85849637e-02 5.71546005e-03 6.70421779e-01 6.15703311e-09
1.96496379e-02 4.62664776e-02 2.84987278e-02 6.15703311e-09
5.13420582e-01 1.88366547e-02 1.45142935e-02 8.92327540e-03
6.32246491e-03 8.08481336e-01 0.00000000e + 00 5.63631430e-02
3.69409472e-02 7.36759901e-01 5.46008237e-02 1.17494063e-02
1.54513204e-02 1.68218538e-02 6.69234037e-01 3.33906822e-02
3.26752402e-02 3.83973792e-02 5.73891141e-02 1.11822821e-01
5.12272008e-02 6.93304315e-02 5.14047369e-02 1.80864055e-03
1.57557316e-02 1.11042978e-02 1.07334806e-02 6.15703311e-09
0,00000000e + 00 1,03809848e-01 0,00000000e + 00 6,15703311e-09
2.19233677e-01 1.49917230e-02 1.25507280e-01 1.75409820e-02
7.54028440e-01 5.22847399e-02 8.12488422e-02 1.12156458e-01]
Шаг 2:
[0. 0,01425315 0,6806311 0,63107663 0,00653503 0,00653504
0,00653503 0,00653503 0,0405196 0,00653503 0,00653503 0,02334335
0.08763484 0.12318593 0.8585707 0. 0.00653504 0.01887737
0,00653503 0,78051955 0,00653503 0,02088702 0,00653503 0,03008028
0,03201023 0,36658844 0,00653503 0,01497512 0,0114087 0,03001456
0,00653503 0,00653503 0,00653503 0,95640105 0,01957083 0,00653503
0,08598939 0,00653503 0,49910328 0,00653503 0,00653503 0,02415803
0,02409992 0,71698534 0,00653503 0,00659794 0,01573122 0,6454014
0,00653503 0,81859267 0,00653503 0,00653503 0,03296572 0,00653504
0,07882535 0,2214024 1. 0,00653503 0,00653503 0,00653503
0,02502085 0,05808342 0,00653503 0,03955946]
Шаг 3:
[0.01213129 0.01213101 0.01213105 0.01213101 0.01213105 0.01213116
0,01213094 0,01213101 0,01213147 0,01213094 0,01213105 0.
0,0121312 0,01213112 0,01213133 0,01213125 0,01213105 0,01213096
0,55621964 0,01213142 0,01213109 0,01213114 0,01213133 0.
0. 0. 0.01213133 0.01213101 0. 0.
0,01213129 0. 0,01213153 0. 0. 0,01213114
0,01245531 0,01213101 0,01213105 0,01213105
0,01213129 0,01213101 0,0121312 0,01213079 0,35860753 0.
0,01213118 0,01213101 0,01213112 0,01213114 0,01213101
0,01213103 0,72302234 0,01213101 0,5268527 0.
0.01213123 1. 0. 0.]
Я попытался найти эту проблему, и одним из предложений было увеличение размера пакета; однако увеличение размера пакета до 128 приводит к ошибке памяти.
Буду признателен за предложения о том, как двигаться вперед.
Проблема вызвана тем, что в тензоре расстояния столько нулей?
Имеет ли смысл всегда добавлять небольшое значение, чтобы значения не становились равными 0?
Должен ли я пересмотреть свою функцию потерь и функцию масштабирования?
Имеет ли смысл испытать для меня методы предотвращения взрыва градиента?
Стоит ли менять используемый мной оптимизатор?