update console design

This commit is contained in:
2026-04-29 19:32:36 +07:00
parent 0a7974260d
commit 83420a314a
6 changed files with 212 additions and 79 deletions
+75 -19
View File
@@ -2,6 +2,19 @@
#include <cmath>
#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) {
for (int i = 0; i < count; i++) sizes.push_back(layers[i].size);
for (int i = 0; i < count - 1; i++) {
@@ -19,45 +32,88 @@ NeuralNetwork::NeuralNetwork(LayerStructure_t layers[], int count) : numLayers(c
}
std::vector<double> NeuralNetwork::feedForward(const std::vector<double>& input) {
OMP_SET_THREADS(); // Ïðèìåíÿåì ëèìèò ÿäåð
outputs.clear();
outputs.push_back(input);
std::vector<double> curr = input;
for (int i = 0; i < numLayers - 1; i++) {
std::vector<double> next;
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];
next.push_back(1.0 / (1.0 + exp(-sum)));
}
// Çàðàíåå ãîòîâèì âåêòîð íóæíîãî ðàçìåðà äëÿ òåêóùåãî ñëîÿ
std::vector<double> next(sizes[i + 1]);
// Ðàñïàðàëëåëèâàåì ðàñ÷åò êàæäîãî íåéðîíà â ñëîå
OMP_PARALLEL
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;
outputs.push_back(curr);
}
return curr;
}
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<std::vector<double>> errors(numLayers);
errors[numLayers-1].resize(sizes[numLayers-1]);
errors[numLayers - 1].resize(sizes[numLayers - 1]);
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];
errors[numLayers-1][i] = e * pred[i] * (1.0 - pred[i]);
// Ïðîèçâîäíàÿ ôóíêöèè àêòèâàöèè (ñèãìîèäû): pred * (1 - pred)
errors[numLayers - 1][i] = e * pred[i] * (1.0 - pred[i]);
totalErr += e * e;
}
// 3. Îáðàòíîå ðàñïðîñòðàíåíèå îøèáêè (Backpropagation) ïî ñêðûòûì ñëîÿì
for (int i = numLayers - 2; i > 0; i--) {
errors[i].resize(sizes[i]);
for (int j = 0; j < sizes[i]; j++) {
double e = 0;
for (int k = 0; k < sizes[i+1]; k++) e += errors[i+1][k] * weights[i][k][j];
errors[i][j] = e * outputs[i][j] * (1.0 - outputs[i][j]);
}
// Ïàðàëëåëèì âû÷èñëåíèÿ äëÿ êàæäîãî íåéðîíà â ñëîå
OMP_PARALLEL
for (int j = 0; j < sizes[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 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];
biases[i][j] += lr * errors[i+1][j];
}
// Ïàðàëëåëèì îáíîâëåíèå âåñîâ ñëåäóþùåãî ñëîÿ
OMP_PARALLEL
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;
}
}
+14 -13
View File
@@ -11,21 +11,22 @@ public:
std::map<int, std::string> idToWord;
Tokenizer() {
add("<EOS>"); // 0
add("[SYS]"); // 1
add("[USER]"); // 2
add("[AI]"); // 3
add(" "); // 4
add("\n"); // 5
add("привет"); // 6
add("как"); // 7
add("дела"); // 8
add("?"); // 9
add("я"); // 10
add("робот"); // 11
add("хорошо"); // 12
add("<EOS>"); add("[SYS]"); add("[USER]"); add("[AI]"); add(" "); add("\n");
add("."); add(","); add("!"); add("?"); add(":"); add(";"); add("-"); add("\""); add("("); add(")");
add("а"); add("б"); add("в"); add("г"); add("д"); add("е"); add("ё"); add("ж");
add("з"); add("и"); add("й"); add("к"); add("л"); add("м"); add("н"); add("о");
add("п"); add("р"); add("с"); add("т"); add("у"); add("ф"); add("х"); add("ц");
add("ч"); add("ш"); add("щ"); add("ъ"); add("ы"); add("ь"); add("э"); add("ю"); add("я");
add("и"); add("в"); add("не"); add("на"); add("я"); add("что"); add("тот"); add("быть");
add("с"); add("а"); add("весь"); add("это"); add("как"); add("она"); add("по"); add("но");
add("они"); add("к"); add("у"); add("ты"); add("из"); add("мы"); add("за"); add("вы");
add("привет"); add("дела"); add("робот"); add("хорошо"); add("спасибо");
add("да"); add("нет"); add("могу"); add("помочь"); add("знаю"); add("кто");
add("где"); add("когда"); add("почему"); add("хочу"); add("очень");
add("тебя"); add("зовут"); add("BiPy");
}
void add(std::string word);
int getID(std::string word);
std::string getWord(int id);
+2 -2
View File
@@ -1,9 +1,9 @@
#ifndef TYPEDEF_H
#define TYPEDEF_H
const int MAX_CONTEXT = 4; // Сколько токенов видит сеть
const int MAX_CONTEXT = 8; // Сколько токенов видит сеть
const int EMBED_DIM = 4; // Размер вектора одного токена
const int MAX_VOCAB = 13; // Размер словаря
const int MAX_VOCAB = 90; // Размер словаря
typedef enum { SIGMOID } FunctionActivate_t;
typedef struct { int size; FunctionActivate_t activate; } LayerStructure_t;