нейронная сеть распознающая цифры из mnist полный код
На предыдущем занятии мы с вами познакомились с пакетом Keras, создали и обучили простейшую НС для перевода градусов Цельсия в градусы Фаренгейта. Пришло время сделать что-то по-настоящему интересное. И на этом занятии мы обучим сеть распознавать рукописные цифры.
Здесь сразу возникает два вопроса: где взять обучающую выборку и какую структуру НС выбрать? На первый вопрос, как ни странно, ответ будет очень простым: мы воспользуемся уже готовой выборкой из уже подготовленной БД изображений:
MNIST – (сокращение от «Modified National Institute of Standards and Technology») – база данных образцов рукописного написания цифр
Эта библиотека образцов поставляется вместе с Keras и для доступа к ней нужно выполнить следующий импорт:
А, затем, загрузить их:
Каждое изображение имеет размер 28х28 пикселей и представлено в градациях серого, т.е. каждый пиксел имеет значение от 0 до 255 (0 – черный цвет, 255 – белый):
Давайте выведем первые 25 изображений из этой базы:
Видим самые разные цифры с произвольным написанием. Все их НС должна научиться правильно распознавать.
В качестве функций активации скрытого слоя выберем популярную на сегодняшний день ReLu, а у выходных нейронов – softmax, т.к. мы хотим интерпретировать выходные значения в терминах вероятности принадлежности к тому или иному классу цифр.
У вас может возникнуть вопрос: почему структура сети именно такая? Почему именно 128 нейронов и один скрытый слой? Да, в общем-то не почему. Просто, мне так захотелось. Вы можете, для примера, взять 100 нейронов или 50 или построить сеть с двумя скрытыми слоями и так далее. Это, на сегодняшний день, делается на уровне шаманства, интуиции разработчика НС. Я решил вот так.
Реализуем эту сеть. Первый слой должен преобразовывать изображение 28×28 пикселей в вектор из 784 элементов. Для такой операции в Keras можно создать слой специального вида – Flatten и в нашем случае мы его пропишем так:
Следующий слой создадим с помощью уже известного нам класса Dense, который свяжет все 784 входа со всеми 128 нейронами. И такой же последний слой из 10 нейронов, который будет связан со всеми 128 нейронами предыдущего слоя. Итоговую модель в Keras можно записать так:
Все, структура сети определена, обучающий набор изображений имеется. Что нужно сделать с этими изображениями до момента обучения? Помните, мы говорили, что желательно входные значения вектора x стандартизировать так, чтобы они находились в диапазоне от 0 до 1? Это мы сейчас и сделаем вот такими строчками:
Здесь каждое значение тензоров x_train и x_test будет делиться на максимальное число 255, которое они могут принимать. На выходе получим вещественные величины от 0 до 1.
Еще нам нужно подготовить правильный формат выходных значений. Опять же, для каждого изображения цифры вектор y_train содержит число:
А нам нужен вектор с 1 на месте соответствующего числа, т.к. наша НС имеет 10 выходов, и каждый выход будет соответствовать определенной цифре: от 0 до 9.
Так как это типовое преобразование, то в Keras уже имеется функция, которая все это делает. Нам достаточно записать строчки:
чтобы получить наборы векторов y_train_cat и y_test_cat по заданному формату. Здесь второй параметр 10 – это размерность каждого вектора.
Отлично, данные подготовлены. Теперь выберем функцию потерь (loss function) и способ оптимизации градиентного алгоритма. И вот как раз здесь нам понадобится та скучная теория прошлых занятий. Помните, мы говорили, что в задачах классификации лучше всего начинать с категориальной кросс-энтропии:
и активационной функции выходных нейронов softmax. Функцию активации мы уже такую прописали, осталось указать этот критерий качества:
Здесь же мы указываем оптимизацию по Adam и еще некую метрику. Что это за метрика и зачем она нужна? Смотрите, в действительности при решении задач классификации нам важно не значение какой-то кросс-энтропии, а процент правильно распознанных цифр. Но построить алгоритм, который бы минимизировал именно процент ошибок сложно (если вообще возможно), поэтому мы привязываемся к более простому с точки зрения математики критерию – категориальной кросс-энтропии, минимизируя которую, надеемся, что будет уменьшаться и процент ошибок, что в общем-то и происходит. Поэтому metrics здесь – это та метрика, которая нужна заказчику и мы ее можем отслеживать в процессе обучения и тестирования НС.
Все, на данном этапе, мы полностью подготовили сеть и данные для запуска процесса обучения. Запишем знакомую нам уже команду:
Давайте ниже, сразу, выполним проверку работы сети на тестовом множестве:
Метод evaluate прогоняет все тестовое множество и вычисляет значение критерия качества и метрики.
Кроме того, давайте выполним распознавания какого-либо тестового изображения:
Здесь мы сначала выделяем из тензора n-е изображение и, затем, прогоняем его по сети, используя метод predict. На выходе получим 10 значений, по которым, затем, нужно будет определить правильность классификации цифр. Запустим эту программу и, смотрите, мы видим вектор выходных значений:
[[3.2027703e-05 4.2498193e-04 9.9881822e-01 4.3836111e-04 1.3467245e-09
8.7383814e-05 1.2201114e-04 1.4552125e-09 7.6896657e-05 4.7233226e-09]]
И полагаем, что максимальное значение как раз и будет соответствовать нужному классу. В данном случае – это число 9.9881822e-01 третьего выхода, то есть, для цифры 2. Чтобы было проще воспринимать выходную информацию, будем выводить номер максимального числа из этого вектора. Для этого воспользуемся довольно удобной функцией argmax модуля numpy:
И, еще, отобразить на экране это тестовое изображение:
Запускаем программу, видим число 2 и картинку с изображением этой цифры. Нейронная сеть верно распознала эту картинку.
Давайте теперь выделим и посмотрим на неверные результаты распознавания. Пропустим через НС всю тестовую выборку и векторы выходных значений преобразуем в числа от 0 до 9:
Затем, сформируем маску, которая будет содержать True для верных вариантов и False – для неверных. И с помощью этой маски выделим из тестовой выборки все неверные результаты:
И выведем первые 5 из них на экран:
Вот мы с вами сделали следующий шаг к более сложной реализации НС для распознавания рукописных цифр. Попробуйте самостоятельно повторить этот пример и поиграться с разным числом нейронов скрытого слоя: посмотрите как это будет сказываться на результатах классификации. А на следующем занятии мы поподробнее поговорим о способе оптимизации на основе стохастического градиента и дополнительных вариантах разделения обучающей выборки на собственно обучающую и проверочную.
Видео по теме
Нейронные сети: краткая история триумфа
Структура и принцип работы полносвязных нейронных сетей | #1 нейросети на Python
Ускорение обучения, начальные веса, стандартизация, подготовка выборки | #4 нейросети на Python
Функции активации, критерии качества работы НС | #6 нейросети на Python
Как нейронная сеть распознает цифры | #9 нейросети на Python
Оптимизаторы в Keras, формирование выборки валидации | #10 нейросети на Python
Batch Normalization (батч-нормализация) что это такое? | #12 нейросети на Python
Как работают сверточные нейронные сети | #13 нейросети на Python
Делаем сверточную нейронную сеть в Keras | #14 нейросети на Python
Примеры архитектур сверточных сетей VGG-16 и VGG-19 | #15 нейросети на Python
Теория стилизации изображений (Neural Style Transfer) | #16 нейросети на Python
Делаем перенос стилей изображений с помощью Keras и Tensorflow | #17 нейросети на Python
Как нейронная сеть раскрашивает изображения | #18 нейросети на Python
Введение в рекуррентные нейронные сети | #19 нейросети на Python
Как рекуррентная нейронная сеть прогнозирует символы | #20 нейросети на Python
Делаем прогноз слов рекуррентной сетью Embedding слой | #21 нейросети на Python
Как работают RNN. Глубокие рекуррентные нейросети | #22 нейросети на Python
Как делать сентимент-анализ рекуррентной LSTM сетью | #24 нейросети на Python
Рекуррентные блоки GRU. Пример их реализации в задаче сентимент-анализа | #25 нейросети на Python
Двунаправленные (bidirectional) рекуррентные нейронные сети | #26 нейросети на Python
Автоэнкодеры. Что это и как работают | #27 нейросети на Python
Вариационные автоэнкодеры (VAE). Что это такое? | #28 нейросети на Python
Делаем вариационный автоэнкодер (VAE) в Keras | #29 нейросети на Python
Расширенный вариационный автоэнкодер (CVAE) | #30 нейросети на Python
Что такое генеративно-состязательные сети (GAN) | #31 нейросети на Python
Делаем генеративно-состязательную сеть в Keras и Tensorflow | #32 нейросети на Python
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Python + OpenCV + Keras: делаем распознавалку текста за полчаса
После экспериментов с многим известной базой из 60000 рукописных цифр MNIST возник логичный вопрос, есть ли что-то похожее, но с поддержкой не только цифр, но и букв. Как оказалось, есть, и называется такая база, как можно догадаться, Extended MNIST (EMNIST).
Если кому интересно, как с помощью этой базы можно сделать несложную распознавалку текста, добро пожаловать под кат.
Примечание: данный пример экспериментальный и учебный, мне было просто интересно посмотреть, что из этого получится. Делать второй FineReader я не планировал и не планирую, так что многие вещи тут, разумеется, не реализованы. Поэтому претензии в стиле «зачем», «уже есть лучше» и пр, не принимаются. Наверно готовые OCR-библиотеки для Python уже есть, но было интересно сделать самому. Кстати, для тех кто хочет посмотреть, как делался настоящий FineReader, есть две статьи в их блоге на Хабре за 2014 год: 1 и 2 (но разумеется, без исходников и подробностей, как и в любом корпоративном блоге). Ну а мы приступим, здесь все открыто и все open source.
Для примера мы возьмем простой текст. Вот такой:
HELLO WORLD
И посмотрим что с ним можно сделать.
Разбиение текста на буквы
Первым шагом разобьем текст на отдельные буквы. Для этого пригодится OpenCV, точнее его функция findContours.
Откроем изображение (cv2.imread), переведем его в ч/б (cv2.cvtColor + cv2.threshold), слегка увеличим (cv2.erode) и найдем контуры.
Мы получаем иерархическое дерево контуров (параметр cv2.RETR_TREE). Первым идет общий контур картинки, затем контуры букв, затем внутренние контуры. Нам нужны только контуры букв, поэтому я проверяю что «родительским» является общий контур. Это упрощенный подход, и для реальных сканов это может не сработать, хотя для распознавания скриншотов это некритично.
Следующим шагом сохраним каждую букву, предварительно отмасштабировав её до квадрата 28х28 (именно в таком формате хранится база MNIST). OpenCV построен на базе numpy, так что мы можем использовать функции работы с массивами для кропа и масштабирования.
В конце мы сортируем буквы по Х-координате, также как можно видеть, мы сохраняем результаты в виде tuple (x, w, letter), чтобы из промежутков между буквами потом выделить пробелы.
Убеждаемся что все работает:
Буквы готовы для распознавания, распознавать их мы будем с помощью сверточной сети — этот тип сетей неплохо подходит для таких задач.
Нейронная сеть (CNN) для распознавания
Исходный датасет EMNIST имеет 62 разных символа (A..Z, 0..9 и пр):
Нейронная сеть соответственно, имеет 62 выхода, на входе она будет получать изображения 28х28, после распознавания «1» будет на соответствующем выходе сети.
Создаем модель сети.
Как можно видеть, это классическая сверточная сеть, выделяющая определенные признаки изображения (количество фильтров 32 и 64), к «выходу» которой подсоединена «линейная» сеть MLP, формирующая окончательный результат.
Обучение нейронной сети
Переходим к самому продолжительному этапу — обучению сети. Для этого мы возьмем базу EMNIST, скачать которую можно по ссылке (размер архива 536Мб).
Для чтения базы воспользуемся библиотекой idx2numpy. Подготовим данные для обучения и валидации.
Мы подготовили два набора, для обучения и валидации. Сами символы представляют собой обычные массивы, которые несложно вывести на экран:
Также мы используем лишь 1/10 датасета для обучения (параметр k), в противном случае процесс займет не менее 10 часов.
Запускаем обучение сети, в конце процесса сохраняем обученную модель на диск.
Сам процесс обучения занимает около получаса:
Это нужно сделать только один раз, дальше мы будем пользоваться уже сохраненным файлом модели. Когда обучение закончено, все готово, можно распознавать текст.
Распознавание
Для распознавания мы загружаем модель и вызываем функцию predict_classes.
Как оказалось, изображения в датасете изначально были повернуты, так что нам приходится повернуть картинку перед распознаванием.
Окончательная функция, которая на входе получает файл с изображением, а на выходе дает строку, занимает всего 10 строк кода:
Здесь мы используем сохраненную ранее ширину символа, чтобы добавлять пробелы, если промежуток между буквами более 1/4 символа.
Результат:
Забавная особенность — нейронная сеть «перепутала» букву «О» и цифру «0», что впрочем, неудивительно т.к. исходный набор EMNIST содержит рукописные буквы и цифры, которые не совсем похожи на печатные. В идеале, для распознавания экранных текстов нужно подготовить отдельный набор на базе экранных шрифтов, и уже на нем обучать нейросеть.
Заключение
Как можно видеть, не боги горшки обжигают, и то что казалось когда-то «магией», с помощью современных библиотек делается вполне несложно.
Поскольку Python является кроссплатформенным, работать код будет везде, на Windows, Linux и OSX. Вроде Keras портирован и на iOS/Android, так что теоретически, обученную модель можно использовать и на мобильных устройствах.
Для желающих поэкспериментировать самостоятельно, исходный код под спойлером.
Сверточная нейронная сеть на Python и Keras
Наконец то мы продолжим писать нейронные сети на Питоне. Сегодня мы познакомимся с сверточными сетями. Будем опять распознавать рукописные цифры из базы MNIST. В сверточные сети так же входит полносвязная сеть, например персептрон. По этому читаем первую статью.
Немного теории.
Свёрточная нейронная сеть (англ.convolutional neural network, CNN) — специальная архитектура искусственных нейронных сетей, предложенная Яном Лекуном в 1988 году и нацеленная на эффективное распознавание образов, Использует некоторые особенности зрительной коры, в которой были открыты так называемые простые клетки, реагирующие на прямые линии под разными углами, и сложные клетки, реакция которых связана с активацией определённого набора простых клеток.
Автор: Michael Plotke
Автор: Aphex34
Keras. Создаем сеть.
Keras — открытая нейросетевая библиотека, написанная на языке Python. Она представляет собой надстройку над фреймворками TensorFlow, упрощая работу с последним.
TensorFlow — открытая программная библиотека для машинного обучения, разработанная компанией Google для решения задач построения и тренировки нейронной сети с целью автоматического нахождения и классификации образов, достигая качества человеческого восприятия.
База MNIST уже есть в данных нашей библиотеки, загружаем базу:
Функция reshape() изменяет форму массива без изменения его данных.
Тестовые данные нам тоже надо преобразовать.
Построение модели сети.
Теперь у нас все готово к построению нашей нейро-сети.
Flatten() – слой, преобразующий 2D-данные в 1D-данные.
Далее, нам нужно скомпилировать нашу модель. Компиляция модели использует три параметра: оптимизатор, потери и метрики.
Оптимизатор весов optimizer=’adam’ (Адам: метод стохастической оптимизации). Функция потерь : loss=’categorical_crossentropy’ категориальная перекрестная энтропия (categorical crossentropy CCE). Последний параметр я не очень понял что такое :
Теперь запускаем обучение сети :
Визуализация, эксперименты, сохранение.
Давайте построим графики обучения для наглядности. Благо метод fit() возвращает историю обучения.
Добавим слой Пулинг по Максимуму, и запустим на 10 эпох. Так же поменяем функцию ошибки и оптимизации.
Сохранение / загрузка целых моделей (архитектура + веса + состояние оптимизатора)
Вы можете использовать model.save(filepath) для сохранения модели Keras в один файл HDF5, который будет содержать:
Использование GPU.
Если вы работаете на TensorFlow или CNTK backends, ваш код автоматически запускается на GPU, если обнаружен какой-либо доступный GPU.
Я думаю у вас еще много вопросов, но к сожаления разобраться со всем в одной статье очень трудно. Изучайте в месте со мной официальную документацию и экспериментируйте ))
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Русские Блоги
Начало работы с Tensorflow: распознавание рукописных цифр MNIST
Сказать вперед
Что такое Tensorflow
Граф потока данных использует ориентированный граф «узлов» и «линий» для описания математических вычислений. «Узел» обычно используется для обозначения прикладной математической операции, но он также может указывать начальную точку ввода данных / конечную точку вывода или конечную точку чтения / записи постоянных переменных. «Линия» представляет отношения ввода / вывода между «узлами». Эти «строки» данных можно транспортировать с помощью многомерного массива данных «динамически регулируемого размера», то есть «тензора». Интуитивно понятное изображение тензора, проходящего через график, является причиной того, почему этот инструмент назван «Tensorflow», Tensor (тензор) и Flow (поток).
Вышеупомянутая выдержка из официального сайта Tensorflow, и я должен представить ее очень уместно. Чтобы понять приведенный выше текст конкретно, вы можете увидеть картинку ниже.
Все вычисления, выполняемые в Tensorflow, можно выразить в виде графа потока данных, подобного этому. Tensorflow определяет вычисление в графике вычислений и отправляет график вычислений в сеанс для выполнения. Tensorflow делит вычисление на эти два шага, цель состоит в том, чтобы обеспечить как эффективность разработки, так и эффективность вычислений.
TensorFlow выполняет процесс вычислений полностью вне Python.
Tensorflow использует эффективный бэкэнд C ++ для выполнения вычислений и подключается через сеанс.
Сначала создайте график, а затем запустите его в сеансе.
Набор данных MNIST
Есть Hello World для языка программирования и MNIST для машинного обучения.
Набор данных MNIST включает обучающий набор (60 000 листов) и набор тестов (10 000 листов).
Обзор используемых моделей
Модель нейронной сети, использованная на этот раз, кратко представлена графиком
Как показано на рисунке, на этот раз используемая модель представляет собой регрессионную модель softmax в нейронной сети BP. Модель имеет входной слой (принимающий входные данные функции) и выходной слой (выходной слой использует Функция активации softmax).
Чтобы узнать о принципе расчета функции softmax, вы можете прочитать этот блог:Понять функцию softmax за одну минуту (супер просто)
Проще говоря, функция softmax должна вводить результаты прогнозирования выборки, принадлежащей каждой категории (пока это просто серия значений регрессии, не преобразованных в вероятности), в функцию softmax, выполнять обработку неотрицательности и нормализации и, наконец, получать значение 0-1. Вероятность классификации в пределах.
Начальный код
Логика кода делится на два аспекта, а именно:Определить график расчета с участием Выполнить сеанс
Определить график расчета
помещается в каталог MNIST_data в каталоге проекта.
Затем код использует библиотеку input_data, которая поставляется с тензорным потоком для чтения данных в
Посмотрим, как выглядят эти картинки
В таком виде это рукописное цифровое изображение размером 28 * 28 пикселей.
Определите заполнители для ввода и вывода. Вводимые функции и фактические значения меток, соответствующие этим функциям, здесь явно не указаны.
Произвольно инициализировать параметры и пороги нейронной сети
Определите функцию гипотезы
Определить функцию потерь
Выберите оптимизатор и определите обучающий узел
Оцените точность модели на обучающей выборке.
Эта строка кода даст нам набор логических значений. Чтобы определить долю правильных элементов прогноза, мы можем преобразовать логическое значение в число с плавающей запятой, а затем взять среднее значение. Например, [True, False, True, True] Станет [1,0,1,1]
Выполнить сеанс
В сеансе выполняются операции инициализации переменных. Этот шаг необходимо выполнить, если на графике вычислений есть переменные.
Начать обучение модели
Оцените точность модели на тестовом наборе
Результат выполнения кода
Итоговая точность тестирования модели составляет 0,9229, что неплохо, потому что мы просто использовали относительно простую модель.
Интеллектуальная рекомендация
Сетевой режим Docker и принцип доступа к сети
Контрольный список для использования OkHttp3
Цитата Основной класс OkHttpClient OkHttpClient представляет клиентский класс HTTP-запросов. В большинстве приложений мы должны выполнить new OkHttpClient () только один раз и сохранить его как глобал.
Приложение для синхронизации CyclicBarrier
Вспомогательный класс синхронизации, который позволяет группе потоков ожидать друг друга, пока они не достигнут общей барьерной точки. В программе, включающей набор потоков фиксированного размера, эти.
Двухдневный тур выходного дня Сичан
Новичок live555 2 (RTP и различные сетевые протоколы)
Я открыл сервер live5 на другом компьютере и открыл vlc для приема данных. Я обнаружил, что иногда данные передаются через tcp, а иногда и через UDP. Мне всегда было интересно, написано ли оно мертвым.