Как избавиться от ошибки деления на 0? - страница 4

 

Не спец по экстриму... Но имхо, у вас в знаменателе не должно быть числа по модулю меньше 2.2250738585072014e-308. Это минимальное положительное значение, которое может быть  представлено типом double.

 



Если будет меньше, то поймаете zero divide.

Проверочный скрипт:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   double pos_min_val = 2.2250738585072014e-308;
   double res;
   double stop_val = -1000.;
   double prev_val = 0.;
   for(double x = 0.; x > stop_val; x = x - 1.e-6)
     {
      double denominator = MathPow(2.71, x);
      bool no_zero = true;
      // no_zero = fabs(denominator) >= pos_min_val;
      if(no_zero)
        {
         res = 1 / denominator;
         prev_val = denominator;
        }
     }
   DebugBreak();
  }

Здесь при закомментированной строчке zero divide я поймал при знаменателе = 4.9406564584124654E-324. Результат = inf.

Если убрать комментарий, то ошибок нет, а результат = 4.4942315186780362E+307. Что где-то вблизи потолка для double (1.7976931348623158e+308).

А вообще коллеги Вам правильно советовали, что на ноль делить нельзя. Самая простая штука - нормализация числа с заданной точностью. Неужели есть такая потребность копать так глубоко в дебри double? И насколько это эффективно? Сумлеваюсь...



 
Denis Kirichenko:

Не спец по экстриму... Но имхо, у вас в знаменателе не должно быть числа по модулю меньше 2.2250738585072014e-308. Это минимальное положительное значение, которое может быть  представлено типом double.

 



Если будет меньше, то поймаете zero divide.

Проверочный скрипт:

Здесь при закомментированной строчке zero divide я поймал при знаменателе = 4.9406564584124654E-324. Результат = inf.

Если убрать комментарий, то ошибок нет, а результат = 4.4942315186780362E+307. Что где-то вблизи потолка для double (1.7976931348623158e+308).

А вообще коллеги Вам правильно советовали, что на ноль делить нельзя. Самая простая штука - нормализация числа с заданной точностью. Неужели есть такая потребность копать так глубоко в дебри double? И насколько это эффективно? Сумлеваюсь...



Если не копать, тогда все статьи по нейронным сетям просто мусор) т.к. на входы на подавать нормализованные значения от 0 до 1, веса нейронов от -1 до 1. И получается что при 1-25 нейронов в входном слое и 1-25 скрытом слое, а так же 1 выходном, сеть работает. При 100 нейронах и уж темболее при 1000 ошибка zero devide при обучении. Или веса становятся NAN или inf. А выход сети который после функции активации должен быть от 0 до 1 становится более 1000. Так же это наблюдается у сети с 10 входами, при начальных значениях весов от 1 до 10 соответственно, при 5-ти изменениях весов веса становятся от -2 до -12 примерно, а выход уже более 1000. Что впринципе не возможно.
 
Александр Алексеевич:
Если не копать, тогда все статьи по нейронным сетям просто мусор) т.к. на входы на подавать нормализованные значения от 0 до 1, веса нейронов от -1 до 1. И получается что при 1-25 нейронов в входном слое и 1-25 скрытом слое, а так же 1 выходном, сеть работает. При 100 нейронах и уж темболее при 1000 ошибка zero devide при обучении. Или веса становятся NAN или inf. А выход сети который после функции активации должен быть от 0 до 1 становится более 1000. Так же это наблюдается у сети с 10 входами, при начальных значениях весов от 1 до 10 соответственно, при 5-ти изменениях весов веса становятся от -2 до -12 примерно, а выход уже более 1000. Что впринципе не возможно.

Имхо, Вы ошиблись с темой. Это скорее проблема не zero divide, а проблема определения допустимых значений для весов и ошибки...

Если передача стоит на нейтралке, то как не дави на газ, машина не поедет...

 
Александр Алексеевич:
Если не копать, тогда все статьи по нейронным сетям просто мусор) т.к. на входы на подавать нормализованные значения от 0 до 1, веса нейронов от -1 до 1. И получается что при 1-25 нейронов в входном слое и 1-25 скрытом слое, а так же 1 выходном, сеть работает. При 100 нейронах и уж темболее при 1000 ошибка zero devide при обучении. Или веса становятся NAN или inf. А выход сети который после функции активации должен быть от 0 до 1 становится более 1000. Так же это наблюдается у сети с 10 входами, при начальных значениях весов от 1 до 10 соответственно, при 5-ти изменениях весов веса становятся от -2 до -12 примерно, а выход уже более 1000. Что впринципе не возможно.

Так и должно быть. 

 
Denis Kirichenko:

Имхо, Вы ошиблись с темой. Это скорее проблема не zero divide, а проблема определения допустимых значений для весов и ошибки...

Если передача стоит на нейтралке, то как не дави на газ, машина не поедет...

Как раз таки нет), с ошибкой выхода все предельно ясно. А вот ошибка скрытого N-го нейрона счиается как? Ошибка выхода же делится на все нейроны, а в нейронках ошибка всегда меньше 1. От сюда и получаются такие малые значения когда в сетке 1000 нейронов в скрытом слое. Сетка из 10 нейронов нормально обучается сходится, а вот из 1000 или из 200 уже нет. 
 
Александр Алексеевич:
Добрый день, возникла проблема mql4 не правильно расчитывает формулу :
1/MathPow(2.71,x) выдает ошибка деления на 0. Но насколько я помню со школьной программы такого быть не может)
1/MathPow(2.71,MathAbs(x));
 
   if (MathIsValidNumber(1.0/(1.0+exp(-z))))
     {
      value=1.0/(1.0+exp(-z));
     }
   else
     {
      if (z>1.0)
        {
         value=DBL_EPSILON-1.0;
        }
      else
        {
         value=DBL_MIN;
        }
      CustomError="NaN/Inf error in sigmoid function with input z="+DoubleToString(z)+", result set to "+DoubleToString(value);
     }

Мало ли вдруг кому пригодится))) все норм работает) нашел на форуме)))