0 / 0 / 0
Регистрация: 11.04.2018
Сообщений: 53
1

Неправильно отнимаются числа типа float(double)

06.02.2019, 18:11. Показов 2476. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Сразу говорю, что перезайти в решение - не вариант.

Итак, у меня есть малюсенькая нейронная сеть, но это так, что б понимать код, но смысл не в этом. В ней есть поле Error. При вызове функции Evaluate(подсчитать) рассчитывается значение Error. Первые 5 "генераций" всё хорошо, однако на шестой при отладке я вижу: Error = 1 - 0.6. Но Error = 0.383333333. Как так то?

Neuron.cs:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace ButtonAI
{
    public class Neuron
    {
        public float Input;     // button (pressed/no)
        public float Weigth;    // weigth
 
        public Neuron(float input, float weigth)
        {
            Input = input;
            Weigth = weigth;
        }
    }
}
NeuralNetwork.cs:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
namespace ButtonAI
{
    public class NeuralNetwork
    {
        public Neuron[] Neurons { get; private set; }
        public float Error { get; private set; }
        public float DesiredOutput { get; private set; }
        public float LearningRate { get; private set; }
 
        public NeuralNetwork(Neuron[] neurons, float desiredOutput, float learningRate)
        {
            Neurons = neurons;
            DesiredOutput = desiredOutput;
            LearningRate = learningRate;
        }
 
        public float Evaluate()
        {
            float neuralNetworkOutput = 0;
 
            for (int i = 0; i < Neurons.Length; i++)
            {
                neuralNetworkOutput += Neurons[i].Input * Neurons[i].Weigth;
            }
 
            Error = DesiredOutput - neuralNetworkOutput;
 
            return neuralNetworkOutput;
        }
 
        public void Training()
        {
            for (int i = 0; i < Neurons.Length; i++)
            {
                if (Neurons[i].Input > 0)
                {
                    Neurons[i].Weigth += LearningRate;
                }
            }
        }
    }
}
Program.cs:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
 
namespace ButtonAI
{
    class Program
    {
        static void Main(string[] args)
        {
            Neuron[] neurons = new Neuron[] { new Neuron(0, 0),
                                              new Neuron(1, 0),
                                              new Neuron(0, 0),
                                              new Neuron(0, 0) };
            int Generation = 0;
            NeuralNetwork NeuralNetwork = new NeuralNetwork(neurons, 1, 0.1);
            string answer;
 
            do
            {
                var NeuralNetworkOutput = NeuralNetwork.Evaluate();
                Generation++;
 
                if (NeuralNetworkOutput >= 1)
                {
                    answer = "Еда будет - ";
                }
                else
                {
                    answer = "Еды не будет - ";
                }
 
                if (NeuralNetwork.Error == 0)
                {
                    answer += "Правильно \t";
                }
                else
                {
                    answer += "НЕправильно ";
                }
 
                answer += $"\t| Gen = {Generation}";
 
                Console.WriteLine(answer);
                Console.WriteLine("-----------------------------------------");
 
                NeuralNetwork.Training();
            } while (NeuralNetwork.Error > 0);
 
            
            Console.ReadKey();
        }
    }
}
Если у вас есть предположения, почему так происходит, пишите буду очень рад и благодарен.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.02.2019, 18:11
Ответы с готовыми решениями:

Неправильно сравнивает числа типа double
Помогите пожалуйста!!!!!неправильно сравнивает числа типа double!!!что не так? if (p == 0) ...

Как сгенерировать случайное число типа я double имея на входе 2 числа типа double - минимальное и максимальное
Например: public class ExtendedRandom : Random { public ExtendedRandom() ...

Преобразование типа double во float
Добрый день! Возникла такая проблема. Написал в 1 строчке то, как мне нужно сделать и, конечно же,...

Неправильно работает cout для чисел типа double и float
Здравствуйте. Скажите, почему эта программа выводит на экран число 2, а не 2.5 ? #include...

4
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
06.02.2019, 18:34 2
Лучший ответ Сообщение было отмечено C_programmer как решение

Решение

Цитата Сообщение от C_programmer Посмотреть сообщение
на шестой при отладке я вижу: Error = 1 - 0.6. Но Error = 0.383333333. Как так то?
Арифметические операции с числами с плавающей запятой склонны к наличию ошибок, а если операции производятся в цикле, как у вас, то эта ошибка имеет свойство еще и накапливаться.

Более того, размер ошибки может различаться в зависимости от процессора, на котором производятся вычисления. Например, у меня ваш код на шестой итерации выдает значение 0.399999976.

Ситуацию может усугублять еще и то, что в шарпе разрешено производить вычисления с бóльшим типом, чем тип переменной.
То есть у вас float, а рантайм может производить вычисления в double, после чего делать приведение double к float, что нередко приводит к появлению дополнительных ошибок.

Если вам важна точность десятичной части, то используйте decimal или на каждой итерации округляйте значение до нужного вам количества знаков после запятой.
1
0 / 0 / 0
Регистрация: 11.04.2018
Сообщений: 53
06.02.2019, 19:17  [ТС] 3
Спасибо, насчёт того что у вас на 6той итерации получается 0.399 и так далее, это так и у меня, я просто написал на глаз, как запомнил

Добавлено через 36 минут
decimal мне не помог, а округление не точно, но всёравно спасибо за ответ.

Добавлено через 3 минуты
Сорян, decimal всётаки помог!
0
Эксперт .NETАвтор FAQ
10409 / 5139 / 1824
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
07.02.2019, 01:33 4
Цитата Сообщение от C_programmer Посмотреть сообщение
насчёт того что у вас на 6той итерации получается 0.399 и так далее, это так и у меня, я просто написал на глаз, как запомнил
Если у вас получается 0.399, то что вас смущает? Что оно не точно 0.4? Так это всегда так будет для чисел с ограниченной точностью.

Цитата Сообщение от C_programmer Посмотреть сообщение
decimal всётаки помог!
Только вот учтите, что decimal будет работать намного медленнее чем float или double. На порядки медленнее. Что для нейронки будет очень даже критично на больших масштабах.

Цитата Сообщение от C_programmer Посмотреть сообщение
if (NeuralNetwork.Error == 0)
А вот так писать точно нельзя. Вычисляемые значения с плавающей запятой вообще нельзя сравнивать через == или !=.
Нужно сравнивать вот так:
C#
1
if (Math.Abs(NeuralNetwork.Error) < epsilon) ...
0
0 / 0 / 0
Регистрация: 11.04.2018
Сообщений: 53
07.02.2019, 11:36  [ТС] 5
Окей, спасибо за совет, а нейронка это маленькая, по этому decimal норм подходит
0
07.02.2019, 11:36
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2019, 11:36
Помогаю со студенческими работами здесь

2-ичное представление числа типа double или float?
помогите разобратся,,,, плиз)) double a=1991.829; a==01000000 10011111 00011111 01010000 11100101...

Нужна компонента: что-то типа StringGrid, но значения ячеек должны иметь тип числа (float, double и т.д.)
Уважаемые дамы и господа! Если у кого-то есть, или кто-то знает где можно взять компоненту под...

Передача переменной типа double из c# в переменную типа float в SQL
Здравствуйте, имеется проблема с передачей данных из кода c# в бд SQL Имеется переменная типа...

Преобразовать 2 числа int в 1 число float(double) | double int1.int2
Всем привет. Изучая азы C++, столкнулся с такой проблемой. Есть два значения типа int, их...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru