Вверх ↑
Этот топик читают: Гость
Ответов: 844
Рейтинг: 17
#1: 2024-12-17 18:01:19 ЛС | профиль | цитата
Аннотация
В данной статье представлена реализация простой нейросети на языке программирования JavaScript.
Мы сосредоточим внимание на архитектуре сети, процессе обучения с использованием алгоритма обратного распространения ошибки и функцией активации ReLU (Rectified Linear Unit).
Пример приведен на основе задачи классификации, используя логическую функцию AND в качестве обучающего набора данных.

Введение
Машинное обучение и нейросети находят широкое применение в различных областях, включая обработку изображений, анализ текста и предсказание временных рядов.
В данной работе мы сосредоточимся на разработке простой нейросети с использованием JavaScript, которая может быть легко интегрирована в веб-приложения.
Нейросети состоят из слоев нейронов, которые обрабатывают данные и обучаются на примерах для выполнения задач классификации или регрессии.

Архитектура нейросети
Функции активации
Нейросеть использует функции активации для управления выходными значениями нейронов.
В нашем примере используется функция ReLU, которая возвращает входное значение, если оно положительное, и ноль в противном случае.
Эта функция эффективна для решения задач с ненормализованными входными данными и помогает избежать проблемы исчезающего градиента.
function relu(x) {
return x › 0 ? x : 0;
}

function reluDerivative(x) {
return x › 0 ? 1 : 0;
}

Структура нейросети
Наша нейросеть состоит из одного скрытого слоя и одного выходного нейрона.
Веса и смещение инициализируются случайными значениями, что позволяет нейросети начинать обучение с произвольной конфигурации.
function SimpleNeuralNetwork(inputSize, outputSize) {
this.weights = [];
for (var i = 0; i ‹ inputSize; i++) {
this.weights.push(Math.random());
}
this.bias = Math.random();
this.learningRate = 0.01;
Процесс обучения
Прямой проход
На этапе прямого прохода нейросеть принимает входные данные и применяет к ним веса и смещение, получая выходное значение.
Это значение затем передается через функцию активации.
this.forward = function(input) {
var weightedSum = 0;
for (var i = 0; i ‹ inputSize; i++) {
weightedSum += this.weights[i] * input[i];
}
weightedSum += this.bias;
return relu(weightedSum);
};
Обратное распространение
Обратное распространение ошибки позволяет нейросети обновлять свои веса на основе ошибки, найденной при сравнении выходного значения с ожидаемым результатом.
На каждом шаге алгоритма, после вычисления градиента для каждого веса и смещения, происходит их обновление с учетом скорости обучения.
this.train = function(inputs, targets, epochs) {
for (var epoch = 0; epoch ‹ epochs; epoch++) {
for (var index = 0; index ‹ inputs.length; index++) {
var input = inputs[index];
var target = targets[index];
var output = this.forward(input);
var error = target - output;
var gradient = reluDerivative(output);
var slope = error * gradient;

for (var i = 0; i ‹ inputSize; i++) {
this.weights[i] += slope * input[i] * this.learningRate;
}
this.bias += slope * this.learningRate;
}
}
};
Пример использования
Для демонстрации работы нейросети был использован обучающий набор данных, представляющий логическую функцию AND:
var inputs = [    [0, 0],
[0, 1],
[1, 0],
[1, 1]
];

var targets = [0, 0, 0, 1]; // Ожидаемый вывод для функции AND

nn.train(inputs, targets, 10000); // Обучение нейросети

После обучения результаты нейросети выводятся на консоль для каждой комбинации входных данных.
for (var i = 0; i ‹ inputs.length; i++) {    var input = inputs[i];
sys.onEvent("Input: " + input + " -› Output: " + nn.forward(input));
}

Заключение
Данная статья описывает основы построения простой нейросети на JavaScript. Мы рассмотрели архитектуру, функцию активации, процесс обучения и пример использования с логической функцией AND.
Данная реализация служит основой для дальнейших исследований и более сложных архитектур, включая многослойные нейросети и использование других функций активации.
Потенциал JavaScript в области машинного обучения открывает новые горизонты для разработки интерактивных приложений, основанных на нейросетях.

[scroll=]
Add(MainForm,2953706,581,126)
{
Width=816
Height=662
}
Add(VBJScript,9290393,630,168)
{
WorkPoints=#6:doWork|
EventPoints=#7:onEvent|
DataPoints=#2:D1|
Language=1
Script=#16:function Main() |1:{|21: // Функции активации|18:function relu(x) {|25: return x > 0 ? x : 0;|1:}|0:|28:function reluDerivative(x) {|25: return x > 0 ? 1 : 0;|1:}|0:|20:// Простая нейросеть|53:function SimpleNeuralNetwork(inputSize, outputSize) {|37: // Инициализация весов и смещения|22: this.weights = [];|41: for (var i = 0; i < inputSize; i++) {|41: this.weights.push(Math.random());|5: }|30: this.bias = Math.random();|29: this.learningRate = 0.01;|0:|20: // Прямой проход|36: this.forward = function(input) {|28: var weightedSum = 0;|45: for (var i = 0; i < inputSize; i++) {|54: weightedSum += this.weights[i] * input[i];|9: }|33: weightedSum += this.bias;|33: return relu(weightedSum);|6: };|0:|25: // Обучение нейросети|52: this.train = function(inputs, targets, epochs) {|54: for (var epoch = 0; epoch < epochs; epoch++) {|65: for (var index = 0; index < inputs.length; index++) {|42: var input = inputs[index];|44: var target = targets[index];|0:|32: // Прямой проход|49: var output = this.forward(input);|0:|36: // Вычисление ошибки|44: var error = target - output;|0:|43: // Обратное распространение|54: var gradient = reluDerivative(output);|45: var slope = error * gradient;|0:|46: // Обновление весов и смещения|53: for (var i = 0; i < inputSize; i++) {|76: this.weights[i] += slope * input[i] * this.learningRate;|17: }|55: this.bias += slope * this.learningRate;|13: }|9: }|6: };|1:}|0:|33:// Пример использования нейросети|39:var nn = new SimpleNeuralNetwork(2, 1);|0:|33:// Обучающие данные (AND функция)|14:var inputs = [|11: [0, 0],|11: [0, 1],|11: [1, 0],|10: [1, 1]|2:];|0:|62:var targets = [0, 0, 0, 1]; // Ожидаемый вывод для функции AND|0:|54:nn.train(inputs, targets, 1000); // Обучение нейросети|0:|23:// Проверка результатов|41:for (var i = 0; i < inputs.length; i++) {|26: var input = inputs[i];|71: sys.onEvent("Input: " + input + " -> Output: " + nn.forward(input));|1:}|0:|0:|3: }|0:|65:/******************* Начало **********************************/|28:function doWork(Data,Index){|7:Main();|1:}|68:/************* Конец *********************************************/|
UseName=0
link(onEvent,13834763:doString,[])
}
Add(Button,16270591,581,168)
{
Left=5
Top=15
link(onClick,9290393:doWork,[])
}
Add(Memo,62219,728,168)
{
Left=90
Top=5
Width=710
Height=615
}
Add(FormatStr,13834763,672,168)
{
Mask="%1\r\n||======================================||\r\n%2"
link(onFString,62219:doAdd,[])
}

[/scroll]
Редактировалось 3 раз(а), последний 2024-12-17 18:05:10
карма: 0

0
Ответов: 8927
Рейтинг: 823
#2: 2024-12-17 22:45:39 ЛС | профиль | цитата
GAv, вот здесь https://forum.hiasm.com/post/71901 почитайте
карма: 19

0
Ответов: 844
Рейтинг: 17
#3: 2024-12-18 09:52:33 ЛС | профиль | цитата
Леонид, Мы говорим о разном , тут я показываю принципы и для чего и зачем.
Ветка будет нацелена на понимания и обучения . с примерами в хиасме.
карма: 0

0
Ответов: 8927
Рейтинг: 823
#4: 2024-12-18 11:11:58 ЛС | профиль | цитата
GAv, нейросеть отличается от простого компьютера тем, что "второй слой" представлен процессорами, каждый из которых (и все они одновременно) сравнивает сигнал от всех ячеек первого слоя с одним или несколькими образцами в своей памяти.
Поэтому чтобы делать пример на HiAsm, надо добраться до видеокарты, где этих процессоров несколько сотен
карма: 19

0
Ответов: 844
Рейтинг: 17
#5: 2024-12-18 11:14:17 ЛС | профиль | цитата
Леонид, Это будет в 3 части запланировано , работа с куда ядрами через С и Скоиплятор кудо ядер





--- Добавлено в 2024-12-18 12:11:36


Очень простой пример текстового варианта. для изучений
Add(MainForm,7335087,413,413)
{
Width=705
Height=459
}
Add(VBJScript,9290393,504,364)
{
WorkPoints=#6:doWork|
EventPoints=#7:onEvent|
DataPoints=#8:ChatText|9:CountEpoh|10:CountTrain|
Language=1
Script=#17:function Main() {|24: // Простая нейросеть|36: function SimpleNeuralNetwork() {|59: this.weights = new Array(16); // Количество токенов|55: for (var i = 0; i < this.weights.length; i++) {|85: this.weights[i] = Math.random(); // Инициализация весов случайным образом|9: }|60: this.bias = Math.random(); // Инициализация смещения|65: this.learningRate = sys.CountTrain; // Обучающая скорость|0:|24: // Прямой проход|40: this.forward = function(input) {|58: var output = this.bias; // Начинаем с смещения|59: for (var i = 0; i < this.weights.length; i++) {|78: output += input[i] * this.weights[i]; // Умножаем вход на веса|13: }|46: return output; // Возвращаем выход|10: };|0:|29: // Обучение нейросети|54: this.train = function(input, target, epochs) {|58: for (var epoch = 0; epoch < epochs; epoch++) {|67: var output = this.forward(input); // Получаем выход|67: var error = target - output; // Рассчитываем ошибку|63: for (var i = 0; i < this.weights.length; i++) {|94: this.weights[i] += error * input[i] * this.learningRate; // Обновляем веса|17: }|77: this.bias += error * this.learningRate; // Обновляем смещение|13: }|10: };|5: }|0:|29:var trainingDataQuestions = [|61: "привет", "как дела", "что тебя зовут", "как тебя зовут",|45: "рад тебя видеть", "пока", "до свидания",|47: "добрый день", "приветствую", "до встречи",|84: "как ты?", "что нового?", "как ты поживаешь?", "тебе нравится программировать?",|89: "чем ты занимаешься?", "все в порядке?", "как твой день?", "что ты думаешь об этом?",|112: "что ты делаешь на выходных?", "как давно ты программируешь?", "на какой язык программирования ты учишься?",|100: "какие у тебя хобби?", "где ты учишься?", "что самое интересное ты узнал про программирование?",|112: "какую книгу ты недавно прочитал?", "как ты проводишь свободное время?", "что ты любишь делать по вечерам?",|105: "есть ли у тебя друзья-программисты?", "как ты справляешься со стрессом?", "что ты изучаешь сейчас?",|144: "как ты относишься к онлайн-курсам?", "что ты думаешь о новых технологиях?", "какие языки программирования считаешь самыми перспективными?",|121: "что ты посоветуешь новичкам в программировании?", "какие программы или инструменты ты используешь в своей работе?", |135: "где ты находишь вдохновение для своих проектов?", "как часто ты участвуешь в хакатонах?", "чем ты мечтаешь заниматься в будущем?",|151: "какая твоя самая большая победа в программировании?", "что для тебя значит успешный проект?", "что ты делал в последний раз, когда был на отдыхе?"|2:];|0:|27:var trainingDataAnswers = [|61: "привет", "хорошо", "меня зовут Иван", "меня зовут Иван",|45: "рад видеть тебя", "до свидания", "пока",|38: "привет", "привет", "до свидания",|70: "все отлично", "все хорошо", "я в порядке", "да, очень нравится!",|87: "программирую", "занимаюсь учебой", "да, все нормально", "жду не дождусь выходных",|90: "на выходных собираюсь отдыхать", "программирую уже несколько лет", "учусь на Python",|84: "мое хобби - фотография", "я учусь в университете", "узнал о новых технологиях",|82: "недавно прочитал роман", "провожу время с друзьями", "люблю смотреть фильмы",|111: "да, у меня есть несколько друзей-программистов", "занимаюсь спортом", "в данный момент изучаю JavaScript",|128: "отлично отношусь, это удобно", "новые технологии всегда интересны", "считаю, что Python и Java сейчас очень перспективные",|93: "практиковаться и не бояться ошибаться", "использую разные редакторы кода и библиотеки", |107: "вдохновение приходит от просмотра работ других", "участвую каждый год", "мечтаю создать свой стартап",|168: "мой самый большой проект - это веб-приложение", "успешный проект - это тот, который решает реальные проблемы", "последний раз я был на даче, отдыхал от компьютера"|2:];|0:|14:// Токенизация|18:var tokenMap = {};|23:tokenMap["привет"] = 0;|20:tokenMap["как"] = 1;|21:tokenMap["дела"] = 2;|20:tokenMap["что"] = 3;|21:tokenMap["тебя"] = 4;|22:tokenMap["зовут"] = 5;|20:tokenMap["рад"] = 6;|23:tokenMap["видеть"] = 7;|21:tokenMap["пока"] = 8;|19:tokenMap["до"] = 9;|26:tokenMap["свидания"] = 10;|24:tokenMap["добрый"] = 11;|22:tokenMap["день"] = 12;|29:tokenMap["приветствую"] = 13;|25:tokenMap["встречи"] = 14;|20:tokenMap["ты"] = 15;|23:tokenMap["новый"] = 16;|26:tokenMap["поживать"] = 17;|26:tokenMap["нравится"] = 18;|33:tokenMap["программировать"] = 19;|21:tokenMap["чем"] = 20;|28:tokenMap["заниматься"] = 21;|21:tokenMap["все"] = 22;|27:tokenMap["в порядке"] = 23;|26:tokenMap["выходные"] = 24;|23:tokenMap["давно"] = 25;|23:tokenMap["учусь"] = 26;|22:tokenMap["язык"] = 27;|34:tokenMap["программирования"] = 28;|23:tokenMap["хобби"] = 29;|21:tokenMap["где"] = 30;|23:tokenMap["самое"] = 31;|28:tokenMap["интересное"] = 32;|23:tokenMap["книга"] = 33;|25:tokenMap["недавно"] = 34;|27:tokenMap["свободное"] = 35;|23:tokenMap["время"] = 36;|24:tokenMap["друзья"] = 37;|29:tokenMap["справляться"] = 38;|26:tokenMap["стрессом"] = 39;|24:tokenMap["изучаю"] = 40;|31:tokenMap["онлайн-курсам"] = 41;|29:tokenMap["технологиям"] = 42;|23:tokenMap["языки"] = 43;|34:tokenMap["программирования"] = 44;|26:tokenMap["новичкам"] = 45;|27:tokenMap["программы"] = 46;|29:tokenMap["инструменты"] = 47;|29:tokenMap["вдохновение"] = 48;|27:tokenMap["хакатонах"] = 49;|24:tokenMap["мечтаю"] = 50;|24:tokenMap["победа"] = 51;|26:tokenMap["успешный"] = 52;|24:tokenMap["проект"] = 53;|24:tokenMap["отдыхе"] = 54;|39: var nn = new SimpleNeuralNetwork();|0:|25: // Обучение нейросети|60: for (var i = 0; i < trainingDataQuestions.length; i++) {|57: var tokens = trainingDataQuestions[i].split(" ");|62: var input = new Array(16); // Создаём вектор для входа|48: for (var k = 0; k < input.length; k++) {|73: input[k] = 0; // Инициализация вектора нулями с помощью цикла|9: }|49: for (var j = 0; j < tokens.length; j++) {|88: if (tokenMap[tokens[j]] !== undefined) { // Проверка на существование токена|67: input[tokenMap[tokens[j]]] = 1; // One-hot encoding|13: }|9: }|84: nn.train(input, i, sys.CountEpoh); // Увеличено количество эпох для обучения|5: }|3: |0:|24: // Получение ответов|34: function getAnswer(question) {|41: var tokens = question.split(" ");|62: var input = new Array(16); // Создаём вектор для входа|48: for (var k = 0; k < input.length; k++) {|73: input[k] = 0; // Инициализация вектора нулями с помощью цикла|9: }|49: for (var j = 0; j < tokens.length; j++) {|88: if (tokenMap[tokens[j]] !== undefined) { // Проверка на существование токена|67: input[tokenMap[tokens[j]]] = 1; // One-hot encoding|13: }|9: }|0:|92: var predictedIndex = Math.round(nn.forward(input)); // Получаем предсказанный индекс|0:|72: // Ограничение индекса, чтобы избежать выхода за границы массива|95: predictedIndex = Math.max(0, Math.min(predictedIndex, trainingDataAnswers.length - 1));|0:|58: // Отладочные сообщения для предсказанного индекса|91: sys.onEvent("Input: " + input.join(", ") + ", Predicted Index: " + predictedIndex);|0:|76: return trainingDataAnswers[predictedIndex]; // Возврат текста ответа|5: }|0:|15: // Проверка|61: var testQuestions = ["привет", "что тебя зовут", "пока"];|0:|54: // for (var j = 0; j < testQuestions.length; j++) {|42: // var question = testQuestions[j];|78: // sys.onEvent("Question: " + question + " -> " + getAnswer(question));|7: // }|3: |37: var userInput = sys.ChatText;|29: sys.onEvent(sys.ChatText); |43: var answer = getAnswer(userInput); |64: sys.onEvent("Question: " + userInput + " -> " + answer);|4: |1:}|0:|0:|65:/******************* Начало **********************************/|29:function doWork(Data, Index) |1:{|21: if(Data == "train")|3: {|11: Main();|3: }|20: if(Data == "chat")|5: {|0:|2: }|1:}|67:/************* Конец ********************************************/|
UseName=0
link(onEvent,62219:doAdd,[])
link(ChatText,8784344:Text,[])
link(CountEpoh,13854119:Text,[])
link(CountTrain,14212265:Text,[])
}
Add(Memo,62219,637,364)
{
Left=15
Top=35
Width=665
Height=330
ScrollBars=3
}
Add(Edit,8784344,504,308)
{
Left=10
Top=370
Width=600
}
Add(Button,14654769,420,364)
{
Left=625
Top=375
Data=String(train)
link(onClick,9290393:doWork,[])
}
Add(Edit,13854119,511,266)
{
Left=50
Top=10
Width=75
Text="5000"
}
Add(Label,1533231,420,308)
{
Left=20
Top=10
Width=28
Height=17
Caption="Эпох"
}
Add(Label,11845371,420,259)
{
Left=140
Top=10
Width=101
Height=17
Caption="Скорость обучения"
}
Add(Edit,14212265,518,224)
{
Left=245
Top=10
Text="0.001"
}


Редактировалось 2 раз(а), последний 2024-12-18 12:12:31
карма: 0

0
5
Сообщение
...
Прикрепленные файлы
(файлы не залиты)