Помощь новичкам

Add создаёт новый кортеж

Нет, тут Add вызывается для списка.

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

begin
  var t := (1, 2, [30, 40]);
  t := (t[0], t[1], t[2] + [50, 60]);
end.

В этом случае создаётся новый кортеж. Все элементы копируются, кроме третьего, для которого возвращается изменённая копия.


Что касается второго случае - List это класс, поэтому когда вы пишете:

var t1 := new List<integer>;

t1 присваивается только указатель но новый созданный список. Когда вы написали:

var tuple := (1,2,t1);

Вы скопировали в третий элемент кортежа адрес этого списка, а не сам список. То есть третий элемент кортежа тут указатель, и когда вы пишете t1.Add - указатель от этого не меняется. Изменяется лишь содержимое списка которое находится по тому указателю.

А, да - с телефона не увидел

у меня этот код не работает, не получается обратиться к элементам кортежа если в кортеже присутствует элемент множество, воспроизводится та же самая ошибка

Да, ну issue создали - значит через некоторое время исправят. Пока откажитесь от множеств в кортежах.

Нужно, чтобы у нас в каком-то режиме воспроизвелось

Как распараллелить этот метод?

public void Backward()
        {
            var V = this.Input;
            V.DW = new float[V.W.Length];
            var inputWidth = V.Width | 0;
            var inputHeight = V.Height | 0;
            var xy_stride = this.Stride | 0;

            for (var d = 0; d < this.OutputDepth; d++)
            {
                var f = this.Filters[d];
                var x = -this.Pad | 0;
                var y = -this.Pad | 0;
                for (var ay = 0; ay < this.OutputHeight; y += xy_stride, ay++)
                {  // xy_stride
                    x = -this.Pad | 0;
                    for (var ax = 0; ax < this.OutputWidth; x += xy_stride, ax++)
                    {  // xy_stride

                        // convolve centered at this particular location
                        var chain_grad = this.Output.Get_Grad(ax, ay, d); // gradient from above, from chain rule
                        for (var fy = 0; fy < f.Height; fy++)
                        {
                            var oy = y + fy; // coordinates in the original input array coordinates
                            for (var fx = 0; fx < f.Width; fx++)
                            {
                                var ox = x + fx;
                                if (oy >= 0 && oy < inputHeight && ox >= 0 && ox < inputWidth) // check if oy not <0 or oy > input height
                                {
                                    for (var fd = 0; fd < f.Depth; fd++)
                                    {
                                        // avoid function call overhead (x2) for efficiency, compromise modularity :(
                                        //V(ox,oy,fd)
                                        //f(fx,fy,fd)
                                        var ix1 = ((inputWidth * oy) + ox) * V.Depth + fd;
                                        var ix2 = ((f.Width * fy) + fx) * f.Depth + fd;
                                        f.DW[ix2] += V.W[ix1] * chain_grad;
                                        V.DW[ix1] += f.W[ix2] * chain_grad;
                                    }
                                }
                            }
                        }
                        this.Biases.DW[d] += chain_grad;
                    }
                }
            }
        }

Я бы взял первый цикл и разбил его на разные потоки. Можно, в теории, и все разбить. Ещё есть $omp (или как оно там называется), но оно вроде в определённых случаях в тихую отказывается работать.

1 лайк

Спасибо большое! Теперь стилизация, как и обучение нейросетей, будет работать раза в два быстрее!

Но это CPU всё равно. Нормально распараллеливание это с использованием GPU. А с ним я разве что могу подсказать искать glsl, я сам пока только собираюсь изучить.

Далеко не все GPU возможно так использовать. Большинство либо просто непригодно для этого, либо не даёт значительного ускорения. А CPU есть везде, следовательно программа будет универсальной(для Windows). Касательно GPU - самая популярная библиотека - CUDA, однако она заточена(а по сути предназначена) под определённые видеокарты от NVIDIA, которые стоят неслабых денег: самая дешёвая - от 20 килорублей за Б/У.

Любой GPU поддерживает умножение векторов и матриц (иначе он бесполезен для графики), а это всегда можно подстроить под нейронные сети.

С этим никто и не спорит. Дело в том, что использование обычных GPU не имеет особого смысла. На нём и так нагрузка в виде монитора(а он на большее и не рассчитан), а тут ещё и нейросеть. Проект станет достаточно сложным, а серьёзного выигрыша в скорости не будет. Смысл в GPU появляется, если у Вас мощная игровая/нейросетевая карта. У меня, например, ноутбук и GPU на нём поменять ооочень сложно и дорого(если вообще возможно, учитывая его 7-и летний стаж).

  1. На сколько я знаю, когда не запущено ни 1 игры - GPU ничего не делает, потому что винда сама рисует через GDI.
  2. Даже если он слабый, CPU+GPU > CPU )))

Да, но вот выигрыш от этого чуть больше 0. Если говорить о существующих реализациях, то все основные операции производятся на GPU, а CPU просто управляет этим. Если параллелить задачу между GPU и CPU, то в лучшем случае - получится так же, как и на просто CPU.

Даже если так, GPU всё равно играет исключительную роль в работе компьютера. Например, для стилизации(той самой, что я представлял месяц назад) есть браузерная офф-лайн версия, запускаемая как раз на GPU. Должен сказать, что если “перебрать” с размером изображения, то компьютер начинает страшно виснуть, что в приводит к вылету последнего по синему экрану в случае любого действия(даже попытки переместить указатель мыши). Я ведь не просто так недолюбливаю такие манипуляции, по сути - попытки использования систем компьютера не по их прямому назначению.

Давно пытаюсь понять, какое различие между структурами и классами в .NET. Они по составу идентичны, но вот структуры лишены наследования. По сути, это единственное отличие, которое я нашёл.

Структуры - размерные, классы - ссылочные

А если в структуре полем будет строка (или любой другой объект динамического размера)?

Возможно, тут “размерные” подразумевает механизм распределения памяти и доступ, как в С, а ссылочные - как в С#. От объектной модели.