Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
 Аватар для lovember
152 / 100 / 40
Регистрация: 14.10.2016
Сообщений: 379

Инициализация элементов списка списков (List<List>) происходит одинаково для каждого элемента

22.02.2020, 18:44. Показов 1954. Ответов 7

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Не знаю как лучше озаглавить эту тему, но у меня проблема со следующим участком кода:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
namespace LinearClassifier
{
    class Program
    {
        static void Main(string[] args)
        {
            int TaskDimension = 24;                     // Объём входных данных.
            const int Layer_1_Dimension = 64;       // Размер первого слоя.
            // Первый слой.
            Layer Layer_1 = new Layer(Layer_1_Dimension, TaskDimension, "Alone");
            Layer_1.WeightsInitialization();
 
            // Ещё много кода.
        }
    }
    
}
Класс слоя (Layer):
Кликните здесь для просмотра всего текста
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using System;
using System.Collections.Generic;
 
namespace LinearClassifier
{
    class Layer
    {
        // Конструкторы слоя
        public Layer() : this(_numberOfNeurons)
        { }
        public Layer(int NumberOfNeurons) : this(NumberOfNeurons, _numberOfNeuronInputs)
        { }
        public Layer(int NumberOfNeurons, int NumberOfNeuronInputs) : this(NumberOfNeurons, _numberOfNeuronInputs, _layerName)
        { }
        public Layer(int NumberOfNeurons, int NumberOfNeuronInputs, string LayerName)
        {
            this.NumberOfNeurons = NumberOfNeurons;
            this.NumberOfNeuronInputs = NumberOfNeuronInputs;
            this.LayerName = LayerName;
            Neuron ObjectNeuron = new Neuron(NumberOfNeuronInputs);
            for (int i = 0; i < NumberOfNeurons; i++)
            {
                Neurons.Add(ObjectNeuron);
            }
        }
        // Количество нейронов.
        private static int _numberOfNeurons { get; set; }
        public int NumberOfNeurons
        {
            get
            { return _numberOfNeurons; }
            set
            {
                _numberOfNeurons = value;
            }
        }
        // Набор нейронов
        private List<Neuron> _neurons = new List<Neuron>(_numberOfNeurons);
        public List<Neuron> Neurons
        {
            get
            { return _neurons; }
            set
            {
                bool _volume = value.Capacity == _neurons.Capacity;         // Проверка соответствия объёмов.
                bool _type = true;                                          // TODO: Написать проверку соответствия типов.
                if (_volume && _type)
                {
                    List<Neuron> element = value;
                    _neurons = (element);
                }
                else
                {
                    Console.WriteLine($"А у вас ошибка! Количество или тип входных Neurons не соответствует количеству, установленному для слоя {_layerName}");
                    // Exception
                }
            }
        }
        // Количество входов на нейрон.
        private static int _numberOfNeuronInputs { get; set; }
        public int NumberOfNeuronInputs
        {
            private get
            { return _numberOfNeuronInputs; }
            set
            {
                _numberOfNeuronInputs = value;
            }
        }
        // Инициализация весов слоя случайными значениями.
        internal void WeightsInitialization()
        {
            Random Rnd = new Random();
            for (int i = 0; i < NumberOfNeurons; i++)
            {
                for (int j = 0; j < NumberOfNeuronInputs; j++)
                {
                    double d = Rnd.NextDouble();
                    Neurons[i].Weights[j] = d;
                }
                Neurons[i].Bias = Rnd.NextDouble();
            }
        }
        // Имя слоя
        private static string _layerName {get; set;}
        public string LayerName
        {
            get
            { return _layerName; }
            set
            {
                bool _type = true;                                          // TODO: Написать проверку соответствия типов.
                if (_type)
                {
                    _layerName = value;
                }
                else
                {
                    Console.WriteLine("А у вас ошибка! Вы вводите/передаёте не строку для имени слоя");
                    // Exception.
                }
            }
        }
        // Метод нелинейности ReLu.
        public List<double> ReLu()
        {
            const double k = 0.001;
            List<double> relu = new List<double>(_numberOfNeurons);
            relu.Clear();
            foreach (Neuron neuron in _neurons)
            {
                neuron.Summator();
                double output = neuron.Output;
                if (output <= 1 && output >= 0)
                {
                    relu.Add(output);
                }
                else if (output < 0)
                {
                    relu.Add(output * k);
                }
                else
                {
                    relu.Add(output * k + (1 - k));
                }
            }
            return relu;
        }
        // Метод нелинейности Sigmoid.
        public List<double> Sigmoid()
        {
            List<double> sigmoid = new List<double>(_numberOfNeurons);
            foreach (Neuron neuron in _neurons)
            {
                neuron.Summator();
                double output = neuron.Output;
                sigmoid.Add(1 / (1 + Math.Exp(-output)));
            }
            return sigmoid;
        }
        // Метод регуляризации весов слоя.
        public double Regularization()
        {
            double sum = 0.0;
            foreach (Neuron neuron in _neurons)
            {
                for (int i =0; i < neuron.Weights.Capacity; i++)
                {
                    sum += neuron.Weights[i];
                }
                sum += neuron.Bias;
            }
            return sum;
        }
    }
}

Класс нейрона (Neuron):
Кликните здесь для просмотра всего текста
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System;
using System.Collections.Generic;
namespace LinearClassifier
{
    public class Neuron
    {
        //public Neuron() : this(_numberOfInputs)
        //{ }
        // Конструктор нейрона, требующий количество входов на нейрон.
        public Neuron (int NumberOfInputs)
        {
            this.NumberOfInputs = NumberOfInputs;
            double startValue = 0.0;
            for (int i = 0; i < NumberOfInputs; i++)
            {
                Inputs.Add(startValue);
                Weights.Add(startValue);
                //Inputs.ForEach();
            }
        }
        // Количество входов нейрона.
        private static int _numberOfInputs { get; set; }
        public int NumberOfInputs
        {
            get
            { return _numberOfInputs; }
            set
            {
                _numberOfInputs = value;
            }
        }
        // Набор входных значений.
        private List<double> _inputs = new List<double>(_numberOfInputs);
        public List<double> Inputs
        {
            get
            { return _inputs; }
            set
            {
                if (value.Count == _inputs.Count)
                {
                    List<double> element = value;
                    _inputs = element;
                }
                else
                {
                    Console.WriteLine("А у вас ошибка! Количество входных Inputs не соответствует количеству, установленному для нейрона");
                    // Exception
                }
            }
        }
        // Набор весов.
        private List<double> _weights = new List<double>(_numberOfInputs);
        public List<double> Weights
        {
            get
            { return _weights; }
            set
            {
                if (value.Count == _weights.Count)
                {
                    List<double> element = value;
                    _weights = element;
                }
                else
                {
                    Console.WriteLine("А у вас ошибка! Количество входных Weights не соответствует количеству, установленному для нейрона");
                    // Exception
                }
            }
        }
        // Вес смещения.
        private double _bias { get; set; }
        public double Bias
        {
            get
            { return _bias; }
            set
            { _bias = value; }
        }
        // Сумматор
        internal void Summator()
        {
            _output = 0.0;
            for (int i = 0; i < _weights.Count; i++)
            {
                _output += _weights[i] * _inputs[i];
            }
            _output += _bias;
        }
        // Выход нейрона
        private double _output { get; set; }
        public double Output
        {
            get { return _output; }            
        }
    }
}

Весь проект целиком можно найти тут
Проблема либо в методе WeightsInitialization, либо в самой логике инициализации значений Weights нейронов Neurons слоя Layer_1.
Сам код компилируется и работает, но у каждого нейрона набор весов (Weights) получается абсолютно одинаковый:
Скриншот
Я по-разному пробовал решить проблему - не выходит. Текущий вариант кода последний. Наверняка кривой и бестолковый, но я только начал изучать C# и многого не знаю.
Вот общее описание того, что должна делать программа (Readme на GitHub):
Кликните здесь для просмотра всего текста
Попытка создать простой линейный классификатор через работу с List. Цель программы:

Взять куб 2х2х2 (класс Cube)
Запутать его (Scramble)
Создать нейросеть из входного и выходного слоя. Слои полносвязные (Fully Connected).
Инициализировать все её нейроны случайными весами.
На основании состояния кубика сеть должна выдать какой ход она намерена сделать при таком состоянии кубика.
Обучение нейросети будет добавлено позже. Планируется по приниципу Reinforcement Learning. Если мне удастся разобраться в том как это всё реализовать - буду считать, что я хоть немного продвинулся в изучении C#. В настоящий момент (2020-02-22) проблема в том, что инициализцаия весов нейронов происходит абсолютно одинаковыми числами для каждого нейрона. За основу этой программы была взята предыдущая версия, которая лежит в репозитории Cube-2x2.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.02.2020, 18:44
Ответы с готовыми решениями:

Количество совпадений для каждого элемента List<string>
На входе List&lt;string&gt;, который содержит каждый раз разное количество элементов. Он передается в private static bool HandleElement...

Добавление строк и элементов в коллекцию для коллекций <List<List<T>
Доброго времени суток , никак не могу добавить строку в коллекцию коллекций . У меня нет определенного количества данных . Могли б...

Вернуть список списков (List<List<>>)
Всем доброго дня! Ситуация следующая, из файла построчно читаются значения, одна строка один список, в каждой строке одинаковое...

7
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
22.02.2020, 20:36
В классе Layer, создайте приватное статическое поле рандома,
C#
1
2
3
4
5
namespace LinearClassifier
{
    class Layer
    {
        private static Random _random = new Random();
а потом используйте его в методе WeightsInitialization.
C#
1
2
3
4
5
6
7
8
internal void WeightsInitialization()
{
    for (int i = 0; i < NumberOfNeurons; i++)
    {
        for (int j = 0; j < NumberOfNeuronInputs; j++)
        {
            double d = _random.NextDouble(); // <-------------
        }
0
 Аватар для lovember
152 / 100 / 40
Регистрация: 14.10.2016
Сообщений: 379
22.02.2020, 21:06  [ТС]
Цитата Сообщение от samana Посмотреть сообщение
В классе Layer, создайте приватное статическое поле рандома, а потом используйте его в методе WeightsInitialization.
Сделал так, но не помогло. Веса по-прежнему получаются одинаковыми.

Пока искал по форуму понял, что у меня ещё и количество нейронов в слое (_numberOfNeurons) является статическим, чтобы могло передаваться в конструктор. Но в этом случае получается, что количество нейронов в каждом слое будет одинаковым. А хотелось бы, чтобы это был параметр, настраиваемый для каждого экземпляра класса слоя. Т.е. индивидуальный для каждого слоя. То же самое с количеством входов на нейрон и количеством весов нейрона (_numberOfInputs в классе нейрона и _numberOfNeuronInputs в классе слоя).

Можете подсказать как сделать так, чтобы эти параметры могли быть индивидуальными для экземпляров класса, но при этом их значения могли использоваться в конструкторе?
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
22.02.2020, 21:35
Цитата Сообщение от lovember Посмотреть сообщение
у меня ещё и количество нейронов в слое (_numberOfNeurons) является статическим, чтобы могло передаваться в конструктор.
Я так и не понял, почему вы сделали _numberOfNeurons статичным, в этом ведь нет необходимости.

Цитата Сообщение от lovember Посмотреть сообщение
Можете подсказать как сделать так, чтобы эти параметры могли быть индивидуальными для экземпляров класса, но при этом их значения могли использоваться в конструкторе?
О конструкторе какого класса идёт речь? Я просто не увидел где вы напрямую обращаетесь к этим статичным полям, тем более они приватные....
0
 Аватар для lovember
152 / 100 / 40
Регистрация: 14.10.2016
Сообщений: 379
22.02.2020, 21:41  [ТС]
Цитата Сообщение от samana Посмотреть сообщение
почему вы сделали _numberOfNeurons статичным, в этом ведь нет необходимости.
Потому что иначе не работает объявление конструктора слоя (см. ниже)
"Для нестатического поля метода или свойства требуется ссылка на объект".

Цитата Сообщение от samana Посмотреть сообщение
О конструкторе какого класса идёт речь?
Имелось в виду объявление конструктора в коде класса.
C#
1
2
3
4
5
6
7
8
// Конструкторы слоя
        public Layer() : this(_numberOfNeurons)
        { }
        public Layer(int NumberOfNeurons) : this(NumberOfNeurons, _numberOfNeuronInputs)
        { }
        public Layer(int NumberOfNeurons, int NumberOfNeuronInputs) : this(NumberOfNeurons, _numberOfNeuronInputs, _layerName)
        { }
        public Layer(int NumberOfNeurons, int NumberOfNeuronInputs, string LayerName)
0
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
22.02.2020, 21:52
Да, увидел, спасибо за подсказку.
Но я не вижу причин делать эти поля статичными.. Неужели эта статика лишь для того, чтобы можно было создать экземпляр Layer не передавая ничего в конструктор? Мне кажется что наоборот, нужно чтобы пользователь обязательно передавал все важные данные в конструктор, тем более если эти данные должны быть индивидуальными.
0
 Аватар для lovember
152 / 100 / 40
Регистрация: 14.10.2016
Сообщений: 379
22.02.2020, 22:01  [ТС]
Цитата Сообщение от samana Посмотреть сообщение
нужно чтобы пользователь обязательно передавал все важные данные в конструктор
Полностью согласен. Можно полностью закомментить первые три конструктора. Я, как это часто со мной бывает, замахнулся слишком на многое (см. Readme). Когда писал класс, то хотел на будущее иметь более широкий потенциал. Заодно потренироваться в написании конструкторов. Посмотреть что можно, что нельзя, на что ругается компилятор и т.п. Я совсем ещё зелёный в программировании, поэтому всё это - просто эксперименты ради изучения языка. У меня есть цель изучить C# к концу года до уровня "что-то типа Junior-a". Вот и придумываю себе задачи посложнее.
0
 Аватар для lovember
152 / 100 / 40
Регистрация: 14.10.2016
Сообщений: 379
24.02.2020, 16:50  [ТС]
Нашёл ошибку! Проблема была в том, что список нейронов содержал одинаковые объекты:
C#
1
2
3
4
5
6
7
8
9
10
11
12
public Layer(int NumberOfNeurons, int NumberOfNeuronInputs, string LayerName)
{
    this.NumberOfNeurons = NumberOfNeurons;
    this.NumberOfNeuronInputs = NumberOfNeuronInputs;
    this.LayerName = LayerName;
    // Neuron ObjectNeuron = new Neuron(NumberOfNeuronInputs);  // Перенёс эту строку ------->
    for (int i = 0; i < NumberOfNeurons; i++)
    {
        Neuron ObjectNeuron = new Neuron(NumberOfNeuronInputs); // <----------- вот сюда
        Neurons.Add(ObjectNeuron);
    }                                                           // и всё заработало!!!
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.02.2020, 16:50
Помогаю со студенческими работами здесь

Копирование списков <List<List>>
Здравствуйте! Допустим есть некоторые метод SomeMethod, который принимает в качестве параметра список someList, копирует его в другой...

Как изменить свойство элемента в list? List<MyClass>
В list содержится класс MyClass у которого есть свойства, как изменить у элемента в list требуемое свойство? Например: class...

Вывод элемента списка List
Есть код, и надо вывести информацию об самом высоком, самом молодом и самом легком спортсмене. using System; using...

Получение элемента из списка List<class>
Здравствуйте подскажите как вывести элемент из списка ( выполнить элегантно задачу не получается ). список List&lt;stack&gt;...

Конвертировать один элемент из List<List<Class>> в list и string
Как можно перевести один выбранный элемент из List&lt;List&lt;Data&gt;&gt; myList в list и string? Например, myList. Сейчас я могу с помощью...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru