У меня есть младший брат, который начал изучать программирование и однажды спросил меня о нейронных сетях (НС). К сожалению, у меня не было опыта работы с TensorFlow, но я знал, что он лучше всего подходит для работы с NN. Итак, я провел пару часов, играясь с ним, и решил написать свой собственный учебник, так как официальное руководство мне показалось немного недостаточным.

Необходимые инструменты

Для этого урока вам понадобится следующее:

Не стесняйтесь следовать самостоятельно или скачать готовый Блокнот Jupyter.

Понимание данных

Давайте начнем с понимания того, с какими данными мы работаем. Сначала импортируйте все необходимые пакеты и загрузите набор данных, поставляемый с TensorFlow:

Что мы там только что делали? x_train и y_train — это входные данные, на которых мы будем обучать нашу модель NN. x_train содержит 60 000 изображений, каждое из которых представлено двумерным массивом размером 28x28 (поскольку каждое изображение имеет размер 28x28 пикселей). Мы можем видеть это по форме массива numpy:

x_train.shape
...
(60000, 28, 28)

Теперь y_train содержит правильные классы каждого изображения. В этом наборе данных изображения представляют собой нарисованные от руки числа от 0 до 9. Таким образом, y_train представляет собой одномерный массив из 60 000 чисел, каждое из которых находится в диапазоне от 0 до 9.

Точно так же x_test и y_test — это данные, на которых мы будем тестировать нашу модель (поскольку мы обычно не тестируем те же данные, на которых обучались). Тестовые данные содержат 10 000 пар изображений/классов.

Обучение модели

Давайте теперь обучим модель. Во-первых, нам нужно нормализовать данные. Значения пикселей варьируются от 0 до 255. Эти большие значения создают большие различия между данными пикселей, что приводит к плохой работе моделей машинного обучения. Подробнее о нормализации можно прочитать здесь.

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

Собрав их вместе, а затем обучив модель, мы получим:

Делать прогнозы

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

predictions = model.predict(x_test[:5])

Если мы напечатаем первый прогноз, мы получим массив из 10 чисел:

predictions[0]
...
array([ -4.377306 ,  -7.1420827,  -0.6452609,   2.2365096, -12.595956 ,         -5.505544 , -18.151062 ,  12.16708  ,  -6.1867275,  -2.0528457],       dtype=float32)

Каждый индекс в этом массиве соответствует классу в нашей модели. В этом случае у нас есть классы от 0 до 9, представляющие числа для прогнозирования. Чем выше число в выходных данных прогноза, тем больше вероятность того, что тестовое изображение содержит класс, представленный этим индексом. В приведенном выше примере 12,16708 — это наибольшее число, и оно расположено под индексом 7. Это означает, что наша модель считает, что первое тестовое изображение (индекс 0 в x_test) показывает 7.

Модель правильная? Мы можем проверить, взглянув на значение y_test[0]. Если мы напечатаем его, мы действительно увидим, что это 7.

Есть ли более интересный способ увидеть это? Вы держите пари!

Визуализация данных

Помимо интеграции с Jupyter, VSC также интегрируется с TensorBoard, который является мощным инструментом для визуализации всевозможных вещей из TensorFlow. В этом уроке мы только поцарапаем его поверхность, визуализируя первые 5 тестовых изображений.

Вставьте следующий фрагмент в свой блокнот:

Сейчас:

  • Нажмите Ctrl/Cmd+Shift+P, чтобы открыть палитру команд.
  • Введите «Python: Launch TensorBoard» и нажмите Enter.
  • Он спросит вас, какой каталог вы хотите использовать — выберите первый вариант («Использовать текущий рабочий каталог») и нажмите Enter.
  • TensorBoard откроется в отдельной вкладке, и вы увидите тестовые изображения:

Теперь давайте сравним эти изображения с нашими прогнозами, найдя индекс максимального числа в каждом массиве прогнозов:

np.argmax(predictions, axis=1)
...
array([7, 2, 1, 0, 4], dtype=int64)

Как видите, прогнозы соответствуют реальным изображениям. Довольно круто!