Разработчик переписал нейросеть для распознавания цифр с Python на Java

Разработчик переписал нейросеть для распознавания цифр с Python на Java

Разработчик из Сбера, работающий с Java, решил разобраться, как устроены нейронные сети. Для этого он переписал с нуля готовую модель для распознавания рукописных цифр MNIST — с Python на Java. Опыт оказался полезным: код заработал, а значит, теперь любой программист на Java может экспериментировать с ИИ без необходимости осваивать Python. «Когда-то я начинал с Python, но потом перешёл на Java и работал с ней много лет, — говорит Антон. — Хотелось понять, как нейросети работают „под капотом“, и проверить, получится ли реализовать их на любимом языке».

Нейронная сеть, о которой идёт речь, выполняет простую задачу: по изображению 28×28 пикселей определить, какая цифра на нём написана. Обучают её на наборе данных MNIST, где собрано 60 тысяч тренировочных изображений и 10 тысяч для проверки. Каждое изображение в этом наборе представлено в виде CSV-файла: первое число — это правильный ответ (цифра от 0 до 9), а следующие 784 значения (28×28) кодируют яркость каждого пикселя от 0 (белый) до 255 (чёрный).

Чтобы лучше понять данные, разработчик написал простое приложение MnistCsvViewer, которое позволяет визуализировать цифры из набора. Оказалось, что цифры в MNIST, хоть и выглядят привычно, но написаны по-американски. Например, «единицу» часто изображают как одну прямую линию, а не двумя линиями под углом, как привыкли в России. «Девятка» в наборе тоже выглядит иначе, чем привыкли мы: без завитка внизу. Это подтолкнуло к идее создать инструмент для анализа изображений и классификации цифр по сложности, но реализация такой задачи осталась на будущее.

Технически сеть состоит из трёх слоёв: входного (784 нейрона, по одному на каждый пиксель), скрытого (200 нейронов) и выходного (10 нейронов, каждый соответствует цифре от 0 до 9). Когда сигнал проходит через сеть, каждый нейрон умножает входное значение на вес, суммирует результаты, пропускает через функцию активации (например, сигмоиду) и передаёт дальше. На выходе получаем вектор вероятностей: чем выше значение, тем выше уверенность сети, что это именно та цифра.

Ключевая часть работы — инициализация весов. Разработчик использовал три подхода: случайные значения близкие к нулю, нормальное распределение с определёнными параметрами и фиксированные значения (нули или единицы). Последний вариант заведомо неидеален, но зато позволяет сравнить результаты с эталонной реализацией на Python и проверить, что код работает одинаково. Для расчётов автор написал собственный класс для работы с матрицами, чтобы не зависеть от библиотек и лучше понять процесс.

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

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

0 комментариев