Нейросеть изменение весов по формуле w^ = w + f^(v3) * E3 * V2
Я делаю нейросеть, мне нужно применить формулу w^ = w + f^(v3) * E3 * V2 для обновление весов методом backpropagation в виде матриц, где:
- w^ - это новые веса
- w - старые веса
- f^(v3) - производная функции активации в точке значения нейрона 3 слоя
- E3 - значение ошибки 3 слоя
- v2 значение нейрона 2 слоя
Когда я умножаю F^(v3) * E3 у меня есть массив из 10 элементов производных в точках выходных данных из 3 слоя которые я могу представить в виде матрицы- вектора из (столбцы = 1 , строки = 10 ) так как e3 у меня тоже массив из 10 элементов который я так же конвертирую в матрицу-вектор и транспонирую ее и получается матрица размера (10,1) в результате умножения получиться матрица (1,1) или если первая матрица будет (10,1), а вторая (1,10) то получиться матрица (10,10).
И если этот результат умножить дальше на v2 значение 2 слоя в нем 88 нейронов матрица будет (1,88) на вариант (10,10) не умножиться остается (1,1) и будет в итоге при умножении (1,88). Я не могу этот результат сложить "+" с w матрицей весов которая размерами (88,10) или (10,88). Возможно это я не правильно формулу понял или не правильно умножаю или что- то еще не правильно делаю?
Вот как в коде я это пытался реализовать:
for (int i = l - 1; i > 0; i--) {
matrix e(layers[i], 1); matrix n(1, layers[i]);
double* pro_ner = new double[layers[i]];
for (int h = 0; h < layers[i]; h++) {
pro_ner[h] = nerons[i][h] * (1 - nerons[i][h]);
}
e.arrtomatrix(err[i]); n.arrtomatrix(pro_ner);
matrix n2(1, layers[i - 1]); n2.arrtomatrix(nerons[i - 1]);
matrix t = e * n;
matrix t2 = е * n2;
matrix w(layers[i], layers[i - 1]);
w.arrtomatrix(weights[i - 1]);
cout << endl << endl;;
w = w + t;
weights[i - 1] = w.matrixtoarray();
}
где l это количество слоев массива layers ={28*28,88,10}.
int* layers;
double** weights;
double** nerons;
double** err;
int l = 3;
я формулу взял с видео на ютубе и она могла быть не правильная , автор мог сделать опечатку
Ответы (1 шт):
Например у вас есть матрица весов между вторым и третьим слоем размерностью [4, 3] (4 нейрона во втором слою и 3 нейрона в третьем), так же у вас имеется:
- Вектор
f'(V)- вектор значений производной функции активации 3 слоя получаетсядлина = 3, e3- вектор ошибок нейронов третьего слоя, то естьдлина = 3v2- вектор выходных значений нейронов второго слоя,длина = 4
В уравнении w' = w + ... мы должны сложить матрицу размерностью [4, 3] с матрицей такой же размерности.
То есть результатом f'(v) * e3 * v2 * 0.2 должна быть матрицы размерностью [4, 3].
Для начала пусть x - вектор в нашем случае длинной 3, где x[i] = f'(v)[i] * e3[i]. То есть вектор x это результат поэлементного умножения вектора f'(v) и e3.
После чего, приводим вектор x к матрице размерностью [1, 3] (Можно сразу в какой нибудь функции поэлементного умножения векторов приводить результирующий вектор к матрице, чтобы меньше времени тратить), а так же вектор v2 к матрице размерностью [4, 1].
Далее просто перемножаем эти матрицы и складываем с матрицей w.
x[1, 3] = { {f'(v)[0] * e3[0], f'(v)[1] * e3[1], f'(v)[2] * e3[2]} }
v2[4, 1] = { {v2[0]}, {v2[1]}, {v2[2]}, {v2[3]} }
v2 * x = { { v2[0, 0] * x[0, 0], v2[0, 0] * x[0, 1], v2[0, 0] * x[0, 2] },
{ v2[1, 0] * x[0, 0], v2[1, 0] * x[0, 1], v2[1, 0] * x[0, 2] },
{ v2[2, 0] * x[0, 0], v2[2, 0] * x[0, 1], v2[2, 0] * x[0, 2] },
{ v2[3, 0] * x[0, 0], v2[3, 0] * x[0, 1], v2[3, 0] * x[0, 2] }}
Можно заметить, что например первая строка (v2 * x)[0] это результат посимвольного перемножения v2[0] * x, то есть функция, которую мы сделали для получения вектора x может пригодится и тут для расчета. А вообще т.к. v2 это матрица с 1 столбиком, то по факту (v2 * x)[0] = v2[0][0] * x, то есть умножение вектора на число.