Добавление делегатов в цикле
От: Svat_P Россия http://svyatoslavpankratov.blogspot.com/
Дата: 27.11.10 12:33
Оценка:
Всем Добрый День!



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

К сожалению старая версия с циклами не сохранилась. Сейчас это выглядит так:


      Layer1.Add(new Neuron(10));
            for (int i = 0; i < 10; i++)
            {
                Layer1[0].X[i] = Layer0[i].OUT;
                Layer1[0].W[i] = 1;
            }
 
            Layer1[0].activationFunction = new Neuron.ActivationFunction(
                    delegate
                    {
                        double sum = 0;
                        for (int i = 0; i < Layer1[0].X.Count/2; i++)
                        {
                            if (Layer1[0].X[i] == 1)
                            {
                                sum += Layer1[0].X[i] * Layer1[0].W[i];
                            }
                            else if (Layer1[0].X[i + 5] == 1)
                            {
                                sum += Layer1[0].X[i + 5] * Layer1[0].W[i];
                            }
                        }
                        sum = sum / Layer1[0].X.Count;
 
                        if(sum >= 0.5) return 1;
                        else return sum;
                    });


У части нейронов активационные функции (выход нейрона) одинаковые, собственно активационная функция и назначается с помощью делегата. Отличия ряда нейронов только во входах, они идут с разных выходов нейронов предыдущего слоя. Соответственно их инициализацию я попытался написать с помощью цикла. Тут видно что все действия идут с нулевым нейроном первого слоя.

Дак вот собственно проблема, которую я до конца так и не понял:

Все ниже написанное относится к случаю, если вся инициализация написана через циклы.

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

Однако, если выполнять программу по прежнему в режиме отладки, но пропустить несколько итераций цикла (зажать F10/F11), то делегаты не назначаются нейронам.



Почему такое странное поведение? Причем поведение чего, я так и не понял...



Буду благодарен за любую помощь!

Всем заранее спасибо!
Re: Добавление делегатов в цикле
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.11.10 12:47
Оценка:
Здравствуйте, Svat_P, Вы писали:

Похоже, у вас получаются временные объекты, на которые нет ссылок. Со временем они собираются сборщиком мусора.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Добавление делегатов в цикле
От: Svat_P Россия http://svyatoslavpankratov.blogspot.com/
Дата: 27.11.10 12:55
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Svat_P, Вы писали:


A>Похоже, у вас получаются временные объекты, на которые нет ссылок. Со временем они собираются сборщиком мусора.


Хм...А как от этого можно избавиться?
Re[3]: Добавление делегатов в цикле
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.11.10 14:12
Оценка:
Здравствуйте, Svat_P, Вы писали:

A>>Похоже, у вас получаются временные объекты, на которые нет ссылок. Со временем они собираются сборщиком мусора.

S_P>Хм...А как от этого можно избавиться?

Сохранять эти ссылки куда-то
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Добавление делегатов в цикле
От: Svat_P Россия http://svyatoslavpankratov.blogspot.com/
Дата: 27.11.10 19:44
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Svat_P, Вы писали:


A>>>Похоже, у вас получаются временные объекты, на которые нет ссылок. Со временем они собираются сборщиком мусора.

S_P>>Хм...А как от этого можно избавиться?

A>Сохранять эти ссылки куда-то :-)


Вообще, по идее, ссылки все должны сохраниться, тк указатель на коллекцию нейронов храниться в объекте всей нейронной сети. Поэтому и все внутренние ссылки, включая ссылки на делегаты, должны сохраняться, тк они не временные, они входят во всю внутреннюю иерархию объекта.
Re[5]: Добавление делегатов в цикле
От: Svat_P Россия http://svyatoslavpankratov.blogspot.com/
Дата: 27.11.10 23:07
Оценка:
Здравствуйте, Svat_P, Вы писали:

S_P>Здравствуйте, adontz, Вы писали:


A>>Здравствуйте, Svat_P, Вы писали:


A>>>>Похоже, у вас получаются временные объекты, на которые нет ссылок. Со временем они собираются сборщиком мусора.

S_P>>>Хм...А как от этого можно избавиться?

A>>Сохранять эти ссылки куда-то :-)


S_P>Вообще, по идее, ссылки все должны сохраниться, тк указатель на коллекцию нейронов храниться в объекте всей нейронной сети. Поэтому и все внутренние ссылки, включая ссылки на делегаты, должны сохраняться, тк они не временные, они входят во всю внутреннюю иерархию объекта.


Проблема решена. Решение см здесь
Re[6]: Добавление делегатов в цикле
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.11.10 05:01
Оценка:
Здравствуйте, Svat_P, Вы писали:

S_P>Проблема решена. Решение см здесь


Скопировал код оттуда
            Layer1 = new List<Neuron>(6);

            for (int j = 0; j < 2; j++)
            {
                ....

                Layer1[j].activationFunction = new Neuron.ActivationFunction(
                        delegate
                        {
                            double sum = 0;
                            for (int i = 0; i < Layer1[j].X.Count / 2; i++)
                            {
                                ....
                        });
            }

Я не очень понял, что там пропадает, но вот что там происходит на самом деле:
переменная цикла j захватывается. Одна на все созданные функции. И ее значение равно значению j при выходе из цикла, полагаю j=2.

Что бы избежать этого, нужно перед анонимным методом ввести новую переменную int curJ = j;
после чего в теле анонимного метода использовать curJ а не j.
Re[7]: Добавление делегатов в цикле
От: Svat_P Россия http://svyatoslavpankratov.blogspot.com/
Дата: 28.11.10 08:54
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Svat_P, Вы писали:


S_P>>Проблема решена. Решение см здесь


S>Скопировал код оттуда

S>
S>            Layer1 = new List<Neuron>(6);

S>            for (int j = 0; j < 2; j++)
S>            {
S>                ....

S>                Layer1[j].activationFunction = new Neuron.ActivationFunction(
S>                        delegate
S>                        {
S>                            double sum = 0;
S>                            for (int i = 0; i < Layer1[j].X.Count / 2; i++)
S>                            {
S>                                ....
S>                        });
S>            }
S>

S>Я не очень понял, что там пропадает, но вот что там происходит на самом деле:
S>переменная цикла j захватывается. Одна на все созданные функции. И ее значение равно значению j при выходе из цикла, полагаю j=2.

S>Что бы избежать этого, нужно перед анонимным методом ввести новую переменную int curJ = j;

S>после чего в теле анонимного метода использовать curJ а не j.

Да, теперь я это понял =) Всем большое спасибо, что помогали! =)
Re: Добавление делегатов в цикле
От: Undying Россия  
Дата: 29.11.10 06:14
Оценка:
Здравствуйте, Svat_P, Вы писали:

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


Есть подозрения, что было как-то так:

for (int i = 0; i < count; ++i)
{
  new ActivationFunction(delegate { return i; });
}


Чтобы работало надо так:

for (int _i = 0; _i < count; ++_i)
{
  int i = _i;
  new ActivationFunction(delegate { return i; });
}


В первом варианте все делегаты работают с одним и тем же экземпляром i, естественно правильно это работать не может.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.