Нажмите ОК, если Вы выражаете свое согласие на обработку Ваших персональных данных в соответствии с Согласием на обработку персональных данных и Политикой конфиденциальности. Вы можете запретить обработку cookies через браузер.
ОК
  • /
  • /

Создание нейросетей для детей: подробный мастер-класс по Python

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

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

Также приглашаем на онлайн-курсы школы программирования Pixel. У нас есть программы по Python и искусственному интеллекту для школьников разного возраста. А сейчас давайте разбираться с теорией.

Попробуйте бесплатно!

Оставьте свой номер: мы позвоним, чтобы записать на бесплатное занятие и ответить на все ваши вопросы.

Немного теории: как устроена нейросеть

Название «нейросеть» возникло потому, что она устроена похоже на сеть нервных клеток в мозге. Основные элементы здесь — нейроны и связи между ними.
Нейроны — это вычислительные элементы. Каждый нейрон получает на вход несколько чисел, выполняет с ними несложные математические операции и выдает одно число на выход.

Сами по себе отдельные нейроны мало что могут, но когда они объединены в сеть, их коллективная работа позволяет решать сложные задачи.

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

Каждая связь между нейронами имеет свой вес. Вес — это число, которое показывает, насколько сильно сигнал от одного нейрона влияет на другой. Можно представить, что каждый входной сигнал умножается на свой вес, и все эти произведения складываются.
Именно веса нейросеть подбирает в процессе обучения. Изначально они выбираются случайно, а затем постепенно корректируются так, чтобы ответы сети становились правильными. В этом мастер-классе по ИИ для детей мы также будем подбирать веса, и вы увидите, как нейросеть обучается на практике.
Скидка 10% для новых клиентов при записи в день обращения*
Отправьте заявку, и мы свяжемся с вами для консультации
* Скидка действует по промокоду на покупку первого абонемента от 12 занятий и более в день обращения. Новым считается клиент, прежде ни разу не приобретавший абонемент в школе.

Как нейросеть учится?

Процесс обучения нейросети напоминает метод проб и ошибок. У нас есть набор примеров — пар «вход — правильный ответ». Сначала нейросеть с текущими (случайными) весами выдает для каждого входа какой-то ответ. Почти наверняка он будет далек от истины.

Дальше в игру вступает обратная связь. Мы вычисляем, насколько ошиблась нейросеть. Для этого используется специальная метрика — функция потерь. Она выдает одно число: если ошибка большая, то и значение функции большое; если ответ близок к правильному, значение мало.

Зная, насколько ошиблась сеть, мы можем немного изменить веса так, чтобы ошибка уменьшилась. Это делается с помощью математического алгоритма, который называется оптимизатор. Он определяет, в какую сторону и на сколько нужно подкрутить каждый вес, чтобы приблизить ответ к правильному.

После корректировки весов мы снова подаем на вход те же примеры и смотрим, изменилась ли ошибка. Один полный проход по всем обучающим данным называется эпохой. Обычно требуется много эпох — сотни или тысячи, — чтобы ошибка стала достаточно маленькой. С каждой эпохой сеть подстраивается все лучше, пока не достигнет приемлемой точности.

Важно: нейросеть не «понимает» задачу в человеческом смысле. Она просто подбирает огромное количество весов так, чтобы для данных из обучения выдавать правильные ответы. Поэтому она хорошо работает на знакомых примерах, но может ошибаться, если задачи новые. Это свойство называется обобщением, и его качество зависит от архитектуры сети и объема данных.

Теперь, когда мы разобрались с основами, перейдем к практике.

Видео мастер-класс по ИИ для детей

У нас видео-урок для детей с мастер-классом по нейросетям на Python. Мы рекомендуем посмотреть его дополнительно к этому пошаговому гайду.

Настраиваем рабочее место: Google Colab

Прежде чем писать код, нам нужно выбрать среду, в которой мы будем создавать нейросеть. Конечно, можно установить Python на свой компьютер, скачать все необходимые библиотеки, настроить окружение. Но есть способ гораздо проще и удобнее — использовать Google Colab.

Что такое Google Colab

Google Colab (сокращение от Colaboratory) — это бесплатный облачный сервис от Google, который позволяет писать и запускать код Python прямо в браузере. Он специально создан для работы с данными и машинным обучением. Вам не нужно ничего устанавливать, все вычисления происходят на серверах Google, а результат вы видите в окне браузера.

Как начать работу

Переходим на сайт colab.research.google.com. Если у вас есть аккаунт Google, вы сразу попадете на главную страницу. Здесь можно создать новый блокнот (ноутбук) — это аналог файла, в котором мы будем писать код и текст.
Нажимаем «Файл» -> «Создать блокнот» или просто кнопку «Новый блокнот». Откроется чистый лист, где можно вводить код. Блокнот состоит из ячеек — в каждой ячейке можно написать несколько строк кода или текста. Ячейки можно выполнять по очереди, и результаты сохраняются между ними.

Почему Google Colab идеально подходит для наших целей

В нашем мастер-классе по ИИ для детей мы используем именно Google Colab, так как у этой платформы есть несколько важных преимуществ:

  1. Все уже предустановлено. В Colab уже установлены самые популярные библиотеки для работы с данными: numpy, matplotlib, tensorflow, keras и многие другие.
  2. Доступ с любого устройства. Вы можете открыть свой блокнот с любого компьютера, где есть интернет, и продолжить работу. Все файлы сохраняются на Google Диске.
  3. Возможность запускать код по частям. Это очень удобно при обучении: мы можем написать небольшой кусок кода, выполнить его, посмотреть результат, и только потом двигаться дальше. Если ошибка, мы сразу ее увидим.
  4. Бесплатные вычислительные ресурсы. Google предоставляет нам бесплатно процессор и GPU (графический процессор), который может ускорять обучение нейросетей. Для нашей простой задачи хватит обычного процессора.
  5. Легко делиться. Можно дать ссылку на блокнот друзьям или преподавателю, они увидят код и результаты.

Теперь, когда мы разобрались с инструментом, создадим новый блокнот, дадим ему название, например «Первая нейросеть», и приступим к подготовке данных.

Готовим данные: числа и их квадраты

Любая нейросеть учится на примерах. Поэтому нам нужны примеры того, что мы хотим, чтобы сеть делала. Нейросеть из нашего мастер-класса для детей будет учиться возводить число в квадрат. Значит для каждого входного числа мы должны подобрать правильный ответ — его квадрат. Эти пары «вход — правильный выход» называются обучающими данными.

Импортируем библиотеки

Сначала импортируем две библиотеки, которые нам понадобятся:

  • numpy — для работы с числами и массивами. Она позволяет легко создавать последовательности чисел и выполнять математические операции.
  • matplotlib.pyplot — для построения графиков. Мы будем рисовать параболу, чтобы наглядно видеть, что должна изучить сеть.

В Colab достаточно написать:

import numpy as np
import matplotlib.pyplot as plt

Выполните эту ячейку (нажмите Ctrl+Enter или кнопку Play слева).

Создаем входные значения (x)

Нам нужно сгенерировать много чисел в некотором диапазоне. Пусть это будут числа от -5 до 5. Это удобно, так как квадратичная функция симметрична, и мы увидим ее полное поведение. Также -5 и 5 дают достаточно большие значения (25), чтобы сеть могла научиться предсказывать не только малые числа.

Возьмем 100 равномерно распределенных точек от -5 до 5. Это сделаем с помощью функции np.linspace:

x = np.linspace(-5, 5, 100)

np.linspace(start, stop, num) создает массив из num чисел, равномерно расположенных между start и stop включительно. То есть у нас будет 100 чисел от -5 до 5. Посмотрим на первые из них:

print(x[:10])

Вы увидите последовательность -5.0, -4.898, -4.797, ... — числа равномерно идут с шагом около 0.1.

Создаем целевые значения (y)

Для каждого числа x вычислим его квадрат:

y = x ** 2

Операция ** в Python означает возведение в степень. Так как x — это массив, то x**2 возводит в квадрат каждый элемент массива сразу.
Теперь у нас есть два массива: x (входные числа) и y (их квадраты). Размерность массивов можно проверить:

print("Размер x:", x.shape)
print("Размер y:", y.shape)

Оба массива содержат по 100 элементов.

Визуализируем данные

Прежде чем обучать нейросеть, визуализируем данные. Построим график зависимости y от x. Это парабола, которая будет тем эталоном, к которому должна стремиться наша сеть.

plt.plot(x, y, 'b-', linewidth=2, label='x^2')
plt.xlabel('x')
plt.ylabel('x^2')
plt.title('Что должна выучить нейросеть')
plt.legend()
plt.grid(True)
plt.show()

Здесь мы используем plt.plot для построения линии. Параметр 'b-' означает синюю сплошную линию. Добавляем подписи осей, заголовок, сетку и легенду.
После выполнения ячейки появится график. Он будет симметричным относительно оси Y, проходящим через ноль. Именно эту зависимость наша нейросеть должна аппроксимировать.

Обратите внимание: данные у нас идеальные, без шума. В реальных задачах данные часто зашумлены, но для первого знакомства мы возьмем чистый пример.

Конструируем нейросеть

Теперь мы переходим к самой интересной части мастер-класса для детей — построению нейросети. Для этого будем использовать библиотеку Keras, которая входит в состав TensorFlow. Нейросети в Keras собираются их из слоев как из конструктора.

Создаем модель Sequential

В Keras есть несколько способов построить модель. Самый простой — использовать класс Sequential. Это означает, что мы создаем последовательную модель, в которой слои идут один за другим. Данные поступают на вход первого слоя, проходят через него, результат передается второму слою и так далее, пока не дойдут до выхода.
Импортируем нужные классы:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

Dense — это полносвязный слой. В таком слое каждый нейрон связан со всеми нейронами предыдущего слоя. Именно такие слои мы и будем использовать.
Теперь создадим модель:

model = Sequential()

Пока модель пустая, в ней нет слоев. Будем добавлять их по очереди.

Добавляем первый (скрытый) слой

Первый слой — скрытый. Он будет получать входные данные и преобразовывать их. Мы зададим, что в этом слое будет 10 нейронов. Также нужно указать, какой размерности ожидаются входные данные — в нашем случае это одно число (параметр input_dim=1).

Кроме того, для скрытых слоев обычно применяют функцию активации. Функция активации добавляет нелинейность, без нее нейросеть не смогла бы выучить ничего сложнее прямой линии. Мы используем функцию 'relu' (relu(x) = max(0, x)).
Отрицательные числа она превращает в ноль, положительные оставляет как есть. Это позволяет сети учиться нелинейным зависимостям.
Добавляем слой:

model.add(Dense(10, input_dim=1, activation='relu'))

Добавляем выходной слой

Выходной слой должен выдавать одно число, поэтому в нем будет один нейрон. Функция активации здесь не нужна. В задачах регрессии (предсказание числа) выходной слой обычно делают без активации.
Добавляем:

model.add(Dense(1))

Посмотрим на структуру модели

Чтобы убедиться, что мы все сделали правильно, можно вывести сводку:

model.summary()

Вы увидите таблицу, где перечислены слои, их выходные размерности и количество параметров (весов), которые будет обучать нейросеть.

Для первого слоя: 10 нейронов, у каждого нейрона есть вес для входа (1 вес) и смещение (bias), итого 10*(1+1)=20 параметров.

Для выходного слоя: 1 нейрон, на входе 10 значений (от предыдущего слоя) + смещение, итого 10+1=11 параметров.

Всего 31 параметр — наша нейросеть довольно простая.

Запускаем обучение

Теперь, когда модель создана, переходим к следующей части мастер-класса по ИИ для детей — обучению модели. Обучение нейросети похоже на тренировку: мы показываем ей примеры, она делает предсказания, мы оцениваем ошибку и говорим ей, как нужно подкрутить внутренние параметры (веса), чтобы в следующий раз ошибка стала меньше. Этот процесс повторяется много раз.

Компиляция модели: выбираем правила игры

Прежде чем начать обучение, нужно сообщить модели два важных элемента: функцию потерь и оптимизатор. Это делается с помощью метода compile.
Функция потерь (loss) — это метрика, которая показывает, насколько сильно предсказания модели отличаются от правильных ответов. Чем меньше значение функции потерь, тем лучше модель. Для задачи предсказания чисел чаще всего используют среднеквадратичную ошибку — MSE.

Она вычисляется так: для каждого примера берется разница между предсказанием и истиной, возводится в квадрат (чтобы отрицательные значения не обнулялись), а затем все эти квадраты усредняются.

Например, если истина 25, а модель предсказала 20, то квадрат ошибки равен 25. Если предсказала 26 — ошибка 1. Математически это выглядит так:

mse = mean((y_true - y_pred)^2)

На практике мы просто укажем loss='mse'.

Оптимизатор (optimizer) — это алгоритм, который решает, как именно менять веса, чтобы уменьшить ошибку. Существует много оптимизаторов, но один из самых популярных и эффективных — Adam (сокращение от Adaptive Moment Estimation). Он адаптивно подбирает шаг обучения для каждого веса и обычно быстро приводит к хорошему решению. Мы укажем optimizer='adam'.
Запишем код компиляции:

model.compile(loss='mse', optimizer='adam')

Все, модель готова к обучению.

Запускаем обучение: метод fit

Обучение выполняется методом fit. Мы передаем ему входные данные (x), правильные ответы (y) и количество эпох.

Эпоха (epoch) — это один полный проход всех обучающих примеров через модель. За одну эпоху модель видит каждый пример один раз. Обычно требуется много эпох, чтобы ошибка достаточно уменьшилась. Мы начнем со 100 эпох.
Код обучения:

history = model.fit(x, y, epochs=100, verbose=1)

Параметр verbose=1 означает, что мы хотим видеть процесс обучения на экране: после каждой эпохи будет выводиться номер эпохи и текущее значение функции потерь. Это полезно, чтобы наблюдать, как ошибка уменьшается.

После запуска этой ячейки начнется обучение. Вы увидите на экране:

Epoch 1/100
4/4 [==============================] - 0s 2ms/step - loss: 210.1234
Epoch 2/100
4/4 [==============================] - 0s 2ms/step - loss: 190.4567
...

Цифры будут быстро меняться. Обратите внимание, что loss в начале может быть очень большим (сотни или тысячи), а к концу 100 эпох значительно уменьшится. В идеале оно должно стремиться к нулю, но для нашей задачи оно, скорее всего, остановится где-то между 5 и 20.

Объект history сохраняет историю обучения, в частности значения loss на каждой эпохе. Позже мы можем построить график, чтобы увидеть, как уменьшалась ошибка.
После окончания обучения можно вывести финальное значение loss:
print("Финальное значение потерь:", history.history['loss'][-1])

Анализируем процесс обучения

Построим график изменения loss во времени:

plt.plot(history.history['loss'])
plt.xlabel('Эпоха')
plt.ylabel('Потери (MSE)')
plt.title('Обучение модели')
plt.grid(True)
plt.show()

На графике мы увидим, как ошибка резко падает в первые эпохи, а затем постепенно сглаживается. Это нормально: сначала модель быстро учится грубой зависимости, а потом долго уточняет детали.

Смотрим, что получилось

Мастер-класс по ИИ для детей не будет полным проверки. Давайте же посмотрим, что именно выучила наша нейросеть!

Используем метод predict, он принимает на вход массив данных и возвращает предсказания модели. В нашем случае мы можем подать все те же 100 чисел и посмотреть, насколько близко предсказания к истинным квадратам.

y_pred = model.predict(x)

Результат y_pred — это массив той же формы, что и y. Теперь построим и сравним истинную параболу и предсказания модели:

plt.plot(x, y, 'b-', label='Истинная функция (x^2)')
plt.plot(x, y_pred, 'r--', label='Предсказание модели')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Сравнение истины и предсказания после 100 эпох')
plt.legend()
plt.grid(True)
plt.show()

Что мы увидим? Скорее всего, график предсказания будет довольно далек от идеальной параболы. Возможно, он будет напоминать ломаную линию, которая лишь приблизительно повторяет форму. В некоторых областях (например, вблизи нуля) ошибка может быть небольшой, а на краях — значительной.

Графики не совпадают по нескольким причинам:

  1. Мало эпох. 100 эпох — это недостаточно для точной аппроксимации. Модель просто не успела полностью настроить веса.
  2. Простая архитектура. У нас всего один скрытый слой с 10 нейронами. Для высокой точности может потребоваться больше нейронов или больше слоев.
  3. Случайная инициализация весов. В начале обучения веса выбираются случайно. Если старт был неудачным, модель может долго «раскачиваться».
  4. Сложность задачи. Хотя возведение в квадрат — простая функция, она нелинейная, и для ее точного воспроизведения нейросети нужно научиться правильно комбинировать нелинейности.

Однако даже при таком неидеальном результате мы видим, что модель все же уловила общую тенденцию. Она понимает, что функция возрастает при удалении от нуля и что в нуле значение близко к нулю.

Для начала это неплохо, но очевидно, что качество модели можно улучшить. Этим мы и займемся в следующей части мастер-класса по нейросетям для детей.

Улучшаем результат: экспериментируем

Теперь мы попробуем два способа улучшить нашу модель: увеличим количество эпох и добавим еще один скрытый слой.

Увеличиваем количество эпох

Самый простой способ — дать модели больше времени на обучение. Увеличим число эпох до 1000. Для этого создадим новую модель (или дообучим старую, но лучше создать новую, чтобы начать с нуля и честно сравнить). Используем ту же архитектуру, но теперь укажем epochs=1000:

model2 = Sequential()
model2.add(Dense(10, input_dim=1, activation='relu'))
model2.add(Dense(1))

model2.compile(loss='mse', optimizer='adam')
history2 = model2.fit(x, y, epochs=1000, verbose=0)

Обучаться будет дольше, но в Colab это займет всего несколько секунд. После обучения посмотрим на предсказания и график:

y_pred2 = model2.predict(x)

plt.plot(x, y, 'b-', label='Истина')
plt.plot(x, y_pred2, 'r--', label='Предсказание (1000 эпох)')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.show()

Скорее всего, график стал заметно ближе к идеальной параболе. Обе линии почти сольются вместе, особенно в центральной части. Ошибки на краях могут присутствовать, но их станет меньше.

Добавляем второй скрытый слой

Увеличение количества слоев (глубины) позволяет модели изучать более сложные зависимости. Добавим еще один полносвязный слой с 10 нейронами и функцией активации ReLU. Теперь архитектура будет такой:

  • Входной слой (одно число)
  • Скрытый слой-1: 10 нейронов, ReLU
  • Скрытый слой-2: 10 нейронов, ReLU
  • Выходной слой: 1 нейрон, без активации

Создадим новую модель:

model3 = Sequential()
model3.add(Dense(10, input_dim=1, activation='relu'))
model3.add(Dense(10, activation='relu'))  # второй скрытый слой
model3.add(Dense(1))

model3.compile(loss='mse', optimizer='adam')
history3 = model3.fit(x, y, epochs=1000, verbose=0)

Посмотрим на результат:

y_pred3 = model3.predict(x)

plt.plot(x, y, 'b-', label='Истина')
plt.plot(x, y_pred3, 'r--', label='Предсказание (2 слоя, 1000 эпох)')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.show()

Теперь предсказание должно быть еще точнее. Возможно, графики почти полностью совпадут.

Сравним численно

Возьмем несколько чисел, например -2, -1, 0, 1, 2, 3. Для них легко вычислить точный квадрат. Посмотрим, что предскажет нейросеть:

X_new = np.array([-2, -1, 0, 1, 2, 3]).reshape(-1, 1)
y_true = X_new.flatten() ** 2
y_pred_new = model2.predict(X_new)

print(" x | Истина | Предсказание | Разница")
print("---|------------|---------------------|-------------")
for i in range(len(X_new)):
    diff = abs(y_true[i] - y_pred_new[i, 0])
    print(f"{X_new[i,0]:2} | {y_true[i]:6} | {y_pred_new[i,0]:10.3f} | {diff:.3f}")

Результат будет примерно таким:

x | Истина | Предсказание | Разница
---|-----------|----------------------|--------
-2 |       4.0 |             4.124    | 0.124
-1 |       1.0 |             1.067    | 0.067
 0 |       0.0 |             0.089    | 0.089
 1 |       1.0 |             0.934    | 0.066
 2 |       4.0 |             4.087    | 0.087
 3 |       9.0 |             9.213    | 0.213

Ошибка порядка 0,1 для чисел в диапазоне обучения — вполне приемлемо. Для числа 3, которое находится на границе диапазона, ошибка чуть выше. Если взять число сильно за пределами, например 10, ошибка будет большой.

Заключение

На этом мастер-классе по ИИ для детей мы создали нейросеть, которая научилась возводить числа в квадрат. Пусть задача простая, но принципы те же, что и в сложных промышленных моделях: подготовка данных, выбор архитектуры, обучение, оценка.
Важно помнить: нейросеть не «понимает» математику, она просто подбирает огромное количество коэффициентов так, чтобы для данных из обучения выдавать близкие ответы. Именно поэтому она хорошо работает на знакомых числах и может ошибаться на новых.

Понравилась статья?

Читайте также:

    Подборка курсов

    Заполните заявку
    на доступ
    кбесплатным
    курсам для детей
    После заполнения формы вы получите доступ в личный кабинет
    Понадобится помощь взрослого*