Параллельные вычисления в нейросетях

133
05 сентября 2019, 07:20

Имеется нейронная сеть со следующей структурой: Я последовательно выполняю тренировку нейронной сети, прогоняя через неё набор тренировочных данных, а именно:

1) Прямое прохождение сигнала (inputs) через каждую матрицу весов (да да да, сумматор, функция активации, все дела...)

2) Расчёт ошибки выходного слоя (сопоставление outputs и targets)

3) Расчёт ошибки скрытых слоёв (производная функции активации, учёт влияния матрицы весов на ошибку, все как надо)

4)Поправка весовых коэффициентов (с учётом вычисленной ошибки)

Эти действия в процессе обучения выполняются N раз (100......1000000)

Вопрос? Как можно организовать вычисления параллельно ? ведь цикл обучения для каждого из наборов входных значений, подразумевает работу с текущими значениями матриц весов. Чтобы обновить веса для одного набора inputs(x1....xn), нужно на этих весах рассчитать outputs(Y-1...Y-m), выполнить поправку и только потом загонять следующий inputs(x....)... ну с соответствующим набором targets(y......) конечно же

//нейронная сеть уже написана на С/C++ в планах использовать несколько потоков для ускорения работы (Просьба не кидайте ссылки работ на CUDA, я знаю что он похож на Cи и там всё работает, я не могу понять что конкретно вычисляется параллельно и как эти результаты влияют друг на друга, для получения результирующего набора матриц весов)

UPD: как это примерно сейчас работает(слой абстрактный)

for (out = 0 ; out < outputsNeuerons ; out++)
 {
     float sum = 0.0;
     for (inp = 0 ; inp < inputsNeuerons ; inp++)
     {
    //inputs - то что вошло в слой
     sum += inputs[inp] * weightsMatrix[inp][out];
     }
     sum += weightsMatrix[inputsNeuerons][out];
    //outputs -  то что вышло из слоя 
    outputs[out] = sigmoid( sum );
 }
Answer 1

Делим входной вектор на 2 (условно) части, каждая половина считается в своём потоке, результирующие вектора суммируем и отправляем получившееся на функцию активации.

//Замечания в комментарии (и да сумму двух векторов на картинке не корректно записана)

Для одного потока:

for (out = 0 ; out < outputsNeuerons ; out++)
 {
     outputs[out] = 0.0;
     for (inp = 0 ; inp < inputsNeuerons/2 ; inp++)
     {
     outputs[out]  += inputs[inp] * weightsMatrix[inp][out];
     }
     outputs[out]  += weightsMatrix[inputsNeuerons][out];
 }

Для другого потока:

for (out = 0 ; out < outputsNeuerons ; out++)
 {
     outputs[out] = 0.0;
     for (inp = inputsNeuerons/2; inp < inputsNeuerons; inp++)
     {
     outputs[out]  += inputs[inp] * weightsMatrix[inp][out];
     }
     outputs[out]  += weightsMatrix[inputsNeuerons][out];
 }

//если это чушь, то хоть дайте знать

READ ALSO
Как создать массив строк?

Как создать массив строк?

Как в C++ создается массив строк? В JS это делается вот так: var arr = ['one', 'two']; В C++ нет типа данных String как я понялКак решить вопрос?

133
Обратная совместимость DirectX

Обратная совместимость DirectX

Всем добрый день! Начал учить разработку с помощью DirectX по книгеКнига довольно старая и примеры используемые в ней написаны на DirectX 7 версии...

131
Перегрузка оператора присваивания C++ без использования strcpy

Перегрузка оператора присваивания C++ без использования strcpy

Изучаю C++Буду очень признателен за любую помощь

131