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 (или как оно там называется), но оно вроде в определённых случаях в тихую отказывается работать.
Спасибо большое! Теперь стилизация, как и обучение нейросетей, будет работать раза в два быстрее!
Но это CPU всё равно. Нормально распараллеливание это с использованием GPU. А с ним я разве что могу подсказать искать glsl, я сам пока только собираюсь изучить.
Далеко не все GPU возможно так использовать. Большинство либо просто непригодно для этого, либо не даёт значительного ускорения. А CPU есть везде, следовательно программа будет универсальной(для Windows). Касательно GPU - самая популярная библиотека - CUDA, однако она заточена(а по сути предназначена) под определённые видеокарты от NVIDIA, которые стоят неслабых денег: самая дешёвая - от 20 килорублей за Б/У.
Любой GPU поддерживает умножение векторов и матриц (иначе он бесполезен для графики), а это всегда можно подстроить под нейронные сети.
С этим никто и не спорит. Дело в том, что использование обычных GPU не имеет особого смысла. На нём и так нагрузка в виде монитора(а он на большее и не рассчитан), а тут ещё и нейросеть. Проект станет достаточно сложным, а серьёзного выигрыша в скорости не будет. Смысл в GPU появляется, если у Вас мощная игровая/нейросетевая карта. У меня, например, ноутбук и GPU на нём поменять ооочень сложно и дорого(если вообще возможно, учитывая его 7-и летний стаж).
- На сколько я знаю, когда не запущено ни 1 игры - GPU ничего не делает, потому что винда сама рисует через GDI.
- Даже если он слабый, CPU+GPU > CPU )))
Да, но вот выигрыш от этого чуть больше 0. Если говорить о существующих реализациях, то все основные операции производятся на GPU, а CPU просто управляет этим. Если параллелить задачу между GPU и CPU, то в лучшем случае - получится так же, как и на просто CPU.
Даже если так, GPU всё равно играет исключительную роль в работе компьютера. Например, для стилизации(той самой, что я представлял месяц назад) есть браузерная офф-лайн версия, запускаемая как раз на GPU. Должен сказать, что если “перебрать” с размером изображения, то компьютер начинает страшно виснуть, что в приводит к вылету последнего по синему экрану в случае любого действия(даже попытки переместить указатель мыши). Я ведь не просто так недолюбливаю такие манипуляции, по сути - попытки использования систем компьютера не по их прямому назначению.
Давно пытаюсь понять, какое различие между структурами и классами в .NET. Они по составу идентичны, но вот структуры лишены наследования. По сути, это единственное отличие, которое я нашёл.
Структуры - размерные, классы - ссылочные
А если в структуре полем будет строка (или любой другой объект динамического размера)?
Возможно, тут “размерные” подразумевает механизм распределения памяти и доступ, как в С, а ссылочные - как в С#. От объектной модели.