Numpy Overflow в вычислениях, нарушающих код - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь обучить нейронную сеть в Python 3.7. Для этого я использую Numpy для выполнения вычислений и умножения матриц. Я нахожу эту ошибку

RuntimeWarning: overflow encountered in multiply (когда я умножаю матрицы)

Это, в свою очередь, приводит к значениям nan, что приводит к ошибкам типа

RuntimeWarning: invalid value encountered in multiply

RuntimeWarning: invalid value encountered in sign

Теперь я видел много ответов, связанных с этим вопросом, и все объясняли, почему это происходит. Но я хочу знать, «Как мне решить эту проблему?». Я попытался использовать модуль math по умолчанию, но он все еще не работает и вызывает ошибки, такие как

TypeError: only size-1 arrays can be converted to Python scalars

Я знаю, что могу использовать циклы for для умножения, но это очень дорого в вычислительном отношении, а также удлиняет и сильно усложняет код. Есть ли решение этой проблемы? Например, делать что-то с Numpy (я знаю, что есть способы обработки исключений, но не решать их), а если нет, то, возможно, альтернатива Numpy, которая не требует от меня большого изменения кода?

Я не против, если точность моих данных будет немного подорвана. (Если это помогает, dtype для матриц float64)

EDIT: Вот фиктивная версия моего кода:

import numpy as np
network = np.array([np.ones(10), np.ones(5)])
for i in range(100000):
    for lindex, layer in enumerate(network):
        network[lindex] *= abs(np.random.random(len(layer)))*200000

Я думаю, что ошибка переполнения возникает при добавлении больших значений в сеть.

1 Ответ

0 голосов
/ 10 ноября 2018

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

А) Используйте другую функцию активации: атан, танх, сигмоид или любую другую с ограниченным диапазоном

Однако, если вы не найдете подходящих:

B) Ослабить активацию ReLu. Это можно сделать, уменьшив все значения простых функций ReLu и ReLu. Вот разница в коде:

##Normal Code
def ReLu(x,derivative=False):
    if derivative:
        return 0 if x<0 else 1
    return 0 if x<0 else x

##Adjusted Code
def ReLu(x,derivative=False):
    scaling_factor = 0.001
    if derivative:
        return 0 if x<0 else scaling_factor
    return 0 if x<0 else scaling_factor*x

Поскольку вы готовы идти на компромисс в точности, это идеальное решение для вас! В конце, вы можете умножить на обратное значение scaling_factor, чтобы получить приблизительное решение - приблизительное из-за округления расхождений.

...