Merge branch 'main' of http://bipfr.servebeer.com:3000/KoDer/BiPy
This commit is contained in:
+17
-67
@@ -2,19 +2,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#define USE_PARALLEL // Çàêîììåíòèðóéòå, ÷òîáû îòêëþ÷èòü ïàðàëëåëèçì
|
|
||||||
#define MAX_THREADS 0 // Óêàæèòå ÷èñëî ÿäåð (0 — èñïîëüçîâàòü âñå äîñòóïíûå)
|
|
||||||
|
|
||||||
#ifdef USE_PARALLEL
|
|
||||||
#include <omp.h>
|
|
||||||
#define OMP_PARALLEL _Pragma("omp parallel for")
|
|
||||||
#define OMP_SET_THREADS() { if (MAX_THREADS > 0) omp_set_num_threads(MAX_THREADS); }
|
|
||||||
#else
|
|
||||||
#define OMP_PARALLEL
|
|
||||||
#define OMP_SET_THREADS()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
NeuralNetwork::NeuralNetwork(LayerStructure_t layers[], int count) : numLayers(count) {
|
NeuralNetwork::NeuralNetwork(LayerStructure_t layers[], int count) : numLayers(count) {
|
||||||
for (int i = 0; i < count; i++) sizes.push_back(layers[i].size);
|
for (int i = 0; i < count; i++) sizes.push_back(layers[i].size);
|
||||||
for (int i = 0; i < count - 1; i++) {
|
for (int i = 0; i < count - 1; i++) {
|
||||||
@@ -32,32 +19,18 @@ NeuralNetwork::NeuralNetwork(LayerStructure_t layers[], int count) : numLayers(c
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> NeuralNetwork::feedForward(const std::vector<double>& input) {
|
std::vector<double> NeuralNetwork::feedForward(const std::vector<double>& input) {
|
||||||
OMP_SET_THREADS(); // Ïðèìåíÿåì ëèìèò ÿäåð
|
|
||||||
|
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
outputs.push_back(input);
|
outputs.push_back(input);
|
||||||
|
|
||||||
std::vector<double> curr = input;
|
std::vector<double> curr = input;
|
||||||
|
|
||||||
for (int i = 0; i < numLayers - 1; i++) {
|
for (int i = 0; i < numLayers - 1; i++) {
|
||||||
// Çàðàíåå ãîòîâèì âåêòîð íóæíîãî ðàçìåðà äëÿ òåêóùåãî ñëîÿ
|
std::vector<double> next;
|
||||||
std::vector<double> next(sizes[i + 1]);
|
for (int j = 0; j < sizes[i+1]; j++) {
|
||||||
|
double sum = biases[i][j];
|
||||||
// Ðàñïàðàëëåëèâàåì ðàñ÷åò êàæäîãî íåéðîíà â ñëîå
|
for (int k = 0; k < (int)curr.size(); k++) sum += curr[k] * weights[i][j][k];
|
||||||
OMP_PARALLEL
|
next.push_back(1.0 / (1.0 + exp(-sum)));
|
||||||
for (int j = 0; j < sizes[i + 1]; j++) {
|
}
|
||||||
double sum = biases[i][j];
|
|
||||||
|
|
||||||
// Âíóòðåííèé öèêë îáû÷íî îñòàâëÿåì ïîñëåäîâàòåëüíûì,
|
|
||||||
// òàê êàê ñîçäàíèå ïîòîêîâ çäåñü äàñò áîëüøå òîðìîçîâ, ÷åì ïîëüçû
|
|
||||||
for (int k = 0; k < (int)curr.size(); k++) {
|
|
||||||
sum += curr[k] * weights[i][j][k];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ñèãìîèäà. Òåïåðü ïèøåì ïî èíäåêñó j — ýòî áåçîïàñíî äëÿ ïîòîêîâ
|
|
||||||
next[j] = 1.0 / (1.0 + exp(-sum));
|
|
||||||
}
|
|
||||||
|
|
||||||
curr = next;
|
curr = next;
|
||||||
outputs.push_back(curr);
|
outputs.push_back(curr);
|
||||||
}
|
}
|
||||||
@@ -66,53 +39,30 @@ std::vector<double> NeuralNetwork::feedForward(const std::vector<double>& input)
|
|||||||
|
|
||||||
|
|
||||||
double NeuralNetwork::train(const std::vector<double>& input, const std::vector<double>& target, double lr) {
|
double NeuralNetwork::train(const std::vector<double>& input, const std::vector<double>& target, double lr) {
|
||||||
// 0. Óñòàíàâëèâàåì êîëè÷åñòâî ïîòîêîâ (åñëè âêëþ÷åíî â define)
|
|
||||||
OMP_SET_THREADS();
|
|
||||||
|
|
||||||
// 1. Ïðÿìîé ïðîõîä (ïîëó÷àåì ïðåäñêàçàíèå)
|
|
||||||
std::vector<double> pred = feedForward(input);
|
std::vector<double> pred = feedForward(input);
|
||||||
|
|
||||||
std::vector<std::vector<double>> errors(numLayers);
|
std::vector<std::vector<double>> errors(numLayers);
|
||||||
errors[numLayers - 1].resize(sizes[numLayers - 1]);
|
errors[numLayers - 1].resize(sizes[numLayers - 1]);
|
||||||
|
|
||||||
double totalErr = 0;
|
double totalErr = 0;
|
||||||
|
for (int i = 0; i < sizes[numLayers-1]; i++) {
|
||||||
// 2. Âû÷èñëåíèå îøèáêè íà âûõîäíîì ñëîå
|
|
||||||
for (int i = 0; i < sizes[numLayers - 1]; i++) {
|
|
||||||
double e = target[i] - pred[i];
|
double e = target[i] - pred[i];
|
||||||
// Ïðîèçâîäíàÿ ôóíêöèè àêòèâàöèè (ñèãìîèäû): pred * (1 - pred)
|
errors[numLayers-1][i] = e * pred[i] * (1.0 - pred[i]);
|
||||||
errors[numLayers - 1][i] = e * pred[i] * (1.0 - pred[i]);
|
|
||||||
totalErr += e * e;
|
totalErr += e * e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Îáðàòíîå ðàñïðîñòðàíåíèå îøèáêè (Backpropagation) ïî ñêðûòûì ñëîÿì
|
|
||||||
for (int i = numLayers - 2; i > 0; i--) {
|
for (int i = numLayers - 2; i > 0; i--) {
|
||||||
errors[i].resize(sizes[i]);
|
errors[i].resize(sizes[i]);
|
||||||
|
for (int j = 0; j < sizes[i]; j++) {
|
||||||
// Ïàðàëëåëèì âû÷èñëåíèÿ äëÿ êàæäîãî íåéðîíà â ñëîå
|
double e = 0;
|
||||||
OMP_PARALLEL
|
for (int k = 0; k < sizes[i+1]; k++) e += errors[i+1][k] * weights[i][k][j];
|
||||||
for (int j = 0; j < sizes[i]; j++) {
|
errors[i][j] = e * outputs[i][j] * (1.0 - outputs[i][j]);
|
||||||
double e = 0;
|
}
|
||||||
for (int k = 0; k < sizes[i + 1]; k++) {
|
|
||||||
e += errors[i + 1][k] * weights[i][k][j];
|
|
||||||
}
|
|
||||||
// outputs[i][j] — ýòî ñîõðàíåííûé ðåçóëüòàò àêòèâàöèè ýòîãî íåéðîíà èç feedForward
|
|
||||||
errors[i][j] = e * outputs[i][j] * (1.0 - outputs[i][j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Îáíîâëåíèå âåñîâ è ñìåùåíèé (Biases)
|
|
||||||
for (int i = 0; i < numLayers - 1; i++) {
|
for (int i = 0; i < numLayers - 1; i++) {
|
||||||
|
for (int j = 0; j < sizes[i+1]; j++) {
|
||||||
// Ïàðàëëåëèì îáíîâëåíèå âåñîâ ñëåäóþùåãî ñëîÿ
|
for (int k = 0; k < sizes[i]; k++) weights[i][j][k] += lr * errors[i+1][j] * outputs[i][k];
|
||||||
OMP_PARALLEL
|
biases[i][j] += lr * errors[i+1][j];
|
||||||
for (int j = 0; j < sizes[i + 1]; j++) {
|
}
|
||||||
for (int k = 0; k < sizes[i]; k++) {
|
|
||||||
// Ãðàäèåíòíûé ñïóñê: ïðèáàâëÿåì (lr * îøèáêà * âõîäíîé ñèãíàë)
|
|
||||||
weights[i][j][k] += lr * errors[i + 1][j] * outputs[i][k];
|
|
||||||
}
|
|
||||||
biases[i][j] += lr * errors[i + 1][j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalErr;
|
return totalErr;
|
||||||
|
|||||||
Reference in New Issue
Block a user