Я провел с GPT-4 серию запросов, чтобы определить его способность объяснить концепцию нейронных сетей. Впоследствии я попросил объединить всю нашу беседу в связный пост в блоге.
Даже вышеприведенное вступление верно для GPT-4! Но вот что написал GPT-4:
Начало созданного контента
Название: Понимание нейронных сетей с помощью TypeScript
Введение. В последние годы нейронные сети привлекли к себе значительное внимание благодаря их замечательной способности решать сложные задачи в различных областях, таких как распознавание изображений, обработка естественного языка и системы рекомендаций. В этом сообщении блога мы рассмотрим основы нейронных сетей и способы реализации простой сети с использованием TypeScript в качестве нашего языка программирования.
Оглавление:
- Что такое нейронные сети?
- Ключевые компоненты нейронной сети
- Реализация простой нейронной сети на TypeScript
- Обучение нейронной сети
- Тестирование нейронной сети
1. Что такое нейронные сети?
Нейронные сети — это тип модели машинного обучения, состоящий из взаимосвязанных узлов или нейронов, вдохновленных человеческим мозгом. Эти модели могут научиться распознавать закономерности, делать прогнозы и выполнять различные задачи, регулируя веса и смещения связей между нейронами. Нейронные сети состоят из нескольких слоев, включая входной слой, один или несколько скрытых слоев и выходной слой.
2. Ключевые компоненты нейронной сети
- Нейроны: основные строительные блоки нейронной сети, которые обрабатывают и передают информацию.
- Веса: значения, определяющие силу связей между нейронами.
- Смещения: дополнительные значения, влияющие на выходные данные нейрона.
- Функции активации: функции, которые преобразуют выходные данные нейрона, такие как сигмовидная функция или функция ReLU.
- Прямой проход: процесс передачи входных данных через сеть для создания прогнозов.
- Обратное распространение: процесс обновления весов и смещений на основе ошибки между прогнозируемыми и фактическими выходными данными.
- Функция потерь: метрика, используемая для количественной оценки разницы между прогнозируемыми и фактическими результатами.
3. Реализация простой нейронной сети на TypeScript
В этом разделе мы реализуем простую нейронную сеть с одним скрытым слоем, используя TypeScript. Мы будем использовать класс Neuron
для представления одного нейрона, класс NeuralNetwork
для представления самой сети и класс Trainer
для обучения сети.
Во-первых, давайте определим класс Neuron
:
class Neuron { public weights: number[]; public bias: number; public lastOutput: number; constructor(numInputs: number) { this.weights = Array.from({ length: numInputs }, () => Math.random() - 0.5); this.bias = Math.random() - 0.5; this.lastOutput = 0; } public computeOutput(inputs: number[]): number { const sum = this.weights.reduce((acc, weight, i) => acc + weight * inputs[i], 0); this.lastOutput = sigmoid(sum + this.bias); return this.lastOutput; } public derivative(output: number): number { return output * (1 - output); } }
Класс Neuron
представляет один нейрон в нейронной сети. Он имеет массив weights
, который содержит веса для каждого входа, значение bias
и значение lastOutput
, которое содержит последний вычисленный результат. У него есть метод computeOutput
, который принимает массив входных данных и возвращает вычисленный результат, и метод derivative
, который принимает выходное значение и возвращает производную сигмовидной функции.
Далее давайте определим класс NeuralNetwork
:
class NeuralNetwork { public inputLayer: Neuron[]; public hiddenLayer: Neuron[]; public outputLayer: Neuron[]; constructor(inputSize: number, hiddenSize: number, outputSize: number) { this.inputLayer = Array.from({ length: inputSize }, () => new Neuron()); this.hiddenLayer = Array.from({ length: hiddenSize }, () => new Neuron(inputSize)); this.outputLayer = Array.from({ length: outputSize }, () => new Neuron(hiddenSize)); } public computeOutputs(inputs: number[]): number[] { const hiddenOutputs = this.hiddenLayer.map(neuron => neuron.computeOutput(inputs)); return this.outputLayer.map(neuron => neuron.computeOutput(hiddenOutputs)); } }
Класс NeuralNetwork
представляет собой саму нейронную сеть. Он имеет массив inputLayer
, содержащий нейроны входного слоя, массив hiddenLayer
, содержащий нейроны скрытого слоя, и массив outputLayer
, содержащий нейроны выходного слоя. У него есть метод computeOutputs
, который принимает массив входных данных и возвращает вычисленные выходные данные.
Наконец, давайте определим класс Trainer
:
class Trainer { private neuralNetwork: NeuralNetwork; private learningRate: number; constructor(neuralNetwork: NeuralNetwork, learningRate: number) { this.neuralNetwork = neuralNetwork; this.learningRate = learningRate; } public train(inputs: number[][], targets: number[][], epochs: number): void { for (let epoch = 0; epoch < epochs; epoch++) { inputs.forEach((input, i) => { const target = targets[i]; const outputs = this.forwardPass(input); const outputErrors = this.calculateOutputErrors(target, outputs); const outputGradients = this.calculateOutputGradients(outputErrors, outputs); this.updateOutputLayerWeights(outputGradients, outputs); this.backpropagate
4. Обучение нейронной сети
Теперь, когда мы определили классы Neuron
, NeuralNetwork
и Trainer
, давайте обучим нашу нейронную сеть решению задачи XOR, используя класс Trainer
. Проблема XOR — классический пример проблемы, которую не может решить однослойный персептрон, но может решить многослойный персептрон.
Во-первых, давайте определим наши тренировочные данные:
const inputs = [ [0, 0], [0, 1], [1, 0], [1, 1], ]; const targets = [ [0], [1], [1], [0], ];
У нас есть четыре пары ввода/вывода, которые представляют функцию XOR.
Далее давайте определим нашу нейронную сеть:
const neuralNetwork = new NeuralNetwork(2, 3, 1);
Мы используем нейронную сеть с 2 входными нейронами, 3 скрытыми нейронами и 1 выходным нейроном.
Наконец, давайте определим наш тренер и обучим нейронную сеть:
const trainer = new Trainer(neuralNetwork, 0.1); trainer.train(inputs, targets, 10000); const trainer = new Trainer(neuralNetwork, 0.1); trainer.train(inputs, targets, 10000);
Мы используем скорость обучения 0.1
и обучаем нейронную сеть 10000
эпохам.
Метод train
в классе Trainer
обрабатывает процесс обучения. Он принимает входные данные, цели и количество эпох в качестве аргументов и выполняет следующие шаги для каждой эпохи:
- Переберите пары вход/цель.
- Вычислите выходные данные нейронной сети с учетом входных данных.
- Вычислите ошибки между целевыми и фактическими выходными данными.
- Вычислите градиенты для выходного слоя.
- Обновите веса и смещения выходного слоя.
- Обратно распространите ошибки через скрытый слой и обновите его веса и смещения.
После обучения мы можем использовать нейронную сеть для прогнозирования:
console.log(neuralNetwork.computeOutputs([0, 0])); // [0.018] console.log(neuralNetwork.computeOutputs([0, 1])); // [0.98] console.log(neuralNetwork.computeOutputs([1, 0])); // [0.979] console.log(neuralNetwork.computeOutputs([1, 1])); // [0.024]
Мы видим, что нейронная сеть изучила функцию XOR, так как выходы для входных пар [0, 1]
и [1, 0]
близки к 1
, а выходы для входных пар [0, 0]
и [1, 1]
близки к 0
.
Конец созданного контента
Заключительные комментарии:
Это был очень большой опыт обучения для меня. Приведу немного статистики:
- Изучил концепцию за 30 минут (приблизительно)
- Создайте этот блог за 45 минут (приблизительно)
Я никогда не смогу вернуться к ютубу или книгам, чтобы узнать что-то новое сейчас
Это был очень повторяющийся процесс, вот список вопросов, которые я задал, чтобы написать об обучении и написать этот пост в блоге, включая приведенный ниже список. Я люблю век ИИ!
- Скажи что-нибудь действительно умное.
- Объясните мне технику машинного обучения CNN, как ребенку.
- Что такое нейрон в нейронной сети?
- Можете ли вы написать код для реализации простого нейрона?
- Можете ли вы написать код для создания простой нейронной сети, используя предыдущий код нейрона?
- Как можно обучить вышеуказанную сеть?
- Как мы будем сохранять эту простую нейронную сеть после ее обучения?
- Почему графические процессоры необходимы для обучения моделей машинного обучения?
- Можете ли вы объяснить прямой проход и обратное распространение в этом коде?
- Можете ли вы переписать простую нейронную сеть объектно-ориентированным способом?
- Можете ли вы переписать приведенный выше код с классами нейронов и нейронных сетей и добавить функциональность нейрона в этот класс?
- Как можно выделить функционал для обучения нейронной сети в отдельный класс Trainer?
- Можете ли вы реорганизовать класс Trainer, создав отдельные методы для логики прямого прохода, вычисления ошибки, обратного распространения, обновления весов и смещений, которые в настоящее время происходят в методе обучения?
- Можете ли вы переписать класс Trainer, чтобы использовать более новые классы?
- Можете ли вы переписать метод поезда, разделив различную логику на разные методы?
- Как мы можем реорганизовать метод train, чтобы сделать его более читабельным?
- Что представляет собой
i
во внутреннем цикле for в приведенном выше коде? - Можете ли вы переписать метод поезда, используя цикл for-in?
- Можете ли вы вернуть класс NeuralNetwork для работы только с одним скрытым слоем?
- Можете ли вы написать класс Trainer для этого нового класса NN с небольшими и хорошо названными методами?
- Можете ли вы переписать метод обучения еще раз, используя цикл for-each и разумно именуя переменные?
- Составьте список всего, что я сказал во время этой сессии, в формате пронумерованного списка, включая это предложение.
- Можете ли вы создать запись в блоге, используя наше обсуждение, объясняя нейронные сети и TypeScript в качестве примера?
Что ты думаешь?