Использование логарифмов для нормализации вектора во избежание переполнения - PullRequest
2 голосов
/ 08 марта 2010

Проблема с арифметикой с использованием логарифмов во избежание потери числового значения (дубль 2)

Увидев вышесказанное и увидев нормализацию softmax, я пытался нормализовать вектор, избегая переполнения -

это если у меня есть массив x[1], x[2] x[3], x[4], ... , x[n]

нормализованная форма для меня имеет сумму квадратов элементов как 1.0 и получается путем деления каждого элемента на sqrt(x[1]*x[1]+x[2]*x[2]+...+x[n]*x[n])

теперь сумма квадратов может переполняться, даже если корень квадратный достаточно мал, чтобы поместиться в переменную с плавающей запятой, поэтому я подумал, что можно сделать что-то вроде s=(2*log(fabs(x[1]))+2*log(fabs(x[2]))+...+2*log(fabs(x[n])))/2

и вычисление элементов как

exp(log(fabs(x[1]))-s), ..., exp(log(fabs(x[n]))-s

НО

Вышеприведенное неверно, так как log (A + B) не является log (A) + log (B) - теперь есть ли способ нормализации вектора, который лучше избегает переполнения?

Ответы [ 3 ]

4 голосов
/ 08 марта 2010

вместо

norm  = sqrt(x[1] * x[1] + ... + x[n] * x[n])

Вы можете разделить элементы вектора на максимально возможное значение перед возведением в квадрат

max_x = max(x[1], ..., x[n])
y[1] = x[1] / max_x / n
...
y[n] = x[n] / max_x / n
norm = n * sqrt(y[1] * y[1] + ... + y[n] * y[n]) * max_x

Норма вектора y должна быть равна или меньше нуля. Значение n * max_x все еще может быть переполнено, поэтому вам также следует быть осторожным, чтобы операции выполнялись в непересекающемся порядке.

3 голосов
/ 08 марта 2010

KennyTM верен - ваши представления о логарифмах неверны.

Нельзя использовать норму L2, потому что она требует, чтобы вы вычислили величину вектора, именно с этим у вас возникают проблемы переполнения.

Возможно, будет лучше норма L-бесконечности, где вы делите каждый компонент в векторе на абсолютное значение максимального компонента в первую очередь. Обязательно держитесь за это максимальное абсолютное значение, чтобы вы могли получить правильную величину обратно.

Я полностью понимаю, что вам нужна норма L2, но если переполнение действительно является проблемой, вам нужно предпринять промежуточные шаги, чтобы получить его:

  1. Найти максимальное абсолютное значение вектора.
  2. Разделите каждый компонент на максимальное абсолютное значение для нормализации; максимальное значение теперь +/- 1.
  3. Вычислить квадратный корень из суммы квадратов нормализованных компонентов. Я бы порекомендовал отсортировать значения и добавить их в порядке возрастания, чтобы убедиться, что небольшие компоненты не потеряны.
  4. Умножьте на максимальное абсолютное значение, чтобы получить норму L2 исходного вектора.
3 голосов
/ 08 марта 2010

Вы, похоже, делаете предположение, что:

log(x^2 + y^2)

совпадает с:

log(x^2) + log(y^2)

Однако это не правильно, так как вы не можете упростить логарифм такой суммы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...