Рубрики
Без рубрики

Как построить простую систему распознавания изображений с Tensorflow (часть 1)

Автор оригинала: FreeCodeCapm Team.

Вольфганг Бейер

Это не общее введение в искусственный интеллект, машинное обучение или глубокое обучение. Уже много замечательных статей, охватывающих эти темы (например здесь или здесь ).

И это не обсуждение того, будет ли AI EndLave Humankind или просто украсть все наши работу. Вы можете найти множество спекуляций и некоторых преждевременных страховников в другом месте.

Вместо этого этот пост – это подробное описание того, как начать работу в машинном обучении, создавая систему, которая является (несколько), способная распознавать то, что он видит на изображении.

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

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

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

Почему распознавание изображения?

Распознавание изображения – это отличная задача для разработки и тестирования подходов на изучение машины. Видение спорно наш самый сильный смысл и приходит естественным образом к нам людям. Но как мы на самом деле делаем это? Как мозг переводит изображение на нашу сетчатку в ментальную модель нашего окружения? Я не думаю, что кто-то точно знает.

Дело в том, что нам, кажется, легко сделать – настолько легко, что нам даже не нужно вкладывать какие-то сознательные усилия, но сложно для компьютеров (на самом деле, это может быть не так просто для нас, возможно, мы Просто не осознавая, сколько работы это. Более половины нашего мозга, кажется, прямо или косвенно участвуют в видении).

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

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

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

Классификация изображений и набор данных CIFAR-10

Мы постараемся решить проблему, которая так же простой и маленькая, насколько это возможно, еще сложно, чтобы научить нас ценные уроки. Все, что мы хотим, чтобы компьютер сделал, это следующее: когда представлено изображением (со специфическими размерами изображения), наша система должна проанализировать ее и назначить его одному метку. Он может выбрать из фиксированного количества ярлыков, каждый из которых является категорию, описывающую содержимое изображения. Наша цель – для нашей модели, чтобы выбрать правильную категорию как можно чаще. Эта задача называется классификацией изображения.

Мы будем использовать стандартизированный набор набора данных CIFAR-10 Отказ CIFAR-10 состоит из 60 000 изображений. Есть 10 различных категорий и 6000 изображений в категории. Каждое изображение имеет размер всего 32 на 32 пикселя. Небольшой размер делает его иногда трудным для того, чтобы США люди могли распознать правильную категорию, но упрощает вещи для нашей компьютерной модели и уменьшает вычислительную нагрузку, необходимую для анализа изображений.

То, как мы вводим эти изображения в нашу модель, кормили модель целую кучу чисел. Каждый пиксель описывается тремя номерами плавающих точек, представляющих красные, зеленые и синие значения для этого пикселя. Это приводит к 32 x 32 x, 072 значения для каждого изображения.

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

Кроме того, стандартизированные наборы данных изображений приводят к созданию компьютерного зрения Высокие списки оценок и соревнования. Самый известный конкурс, вероятно, Значение-нетто соревнования , в котором существует 1000 различных категорий для обнаружения. Победитель 2012 года был алгоритмом, разработанным Алексеем Крижевским, Ильей Суцки и Джеффри Хинтоном из Университета Торонто ( Технический документ ), который доминировал на конкурсе и выиграл огромный край. Это был первый раз, когда выигрышный подход использовал сверточную нейронную сеть, которая оказала большое влияние на исследовательское сообщество. Световозные нейронные сети – это искусственные нейронные сети, свободно смоделированные после того, как зрительная кора найдена у животных. Эта техника находилась на некоторое время, но в то время, когда большинство людей еще не видели его потенциал, чтобы быть полезным. Это изменилось после соревнования с 2012 года 2012 года. Внезапно произошло большой интерес к нейронным сетям и глубокому обучению (глубокое обучение – это просто термин, используемый для решения проблем изучения машины с многослойными нейронными сетями). Это событие играет большую роль в начале глубокого обучения бума последних нескольких лет.

Контролируемое обучение

Как мы можем использовать набор данных изображения, чтобы получить компьютер, чтобы узнать самостоятельно? Несмотря на то, что компьютер сама по себе делает учащиеся, нам все еще нужно сказать, что учиться и как это сделать. То, как мы делаем это, указав общий процесс того, как компьютер должен оценивать изображения.

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

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

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

Tensorflow

Tensorflow Это библиотека программного обеспечения с открытым исходным кодом для машинного обучения, которая была выпущена Google в 2015 году и быстро стала одним из самых популярных библиотек машинного обучения, используемых исследователями и практиками по всему миру. Мы используем его, чтобы сделать численную тяжелую подъем для нашей модели классификации изображений.

Создание модели, классификатор Softmax

Полный код для этой модели Доступно на GitHub Отказ Для того, чтобы использовать его, вам необходимо установить следующее:

Хорошо, теперь мы наконец готовы пойти. Давайте посмотрим на основной файл нашего эксперимента, Softmax.py и анализировать его линию по линии:

Будущие заявления должны присутствовать во всех файлах Tensorflow Python для обеспечения совместимости с Python 2 и 3 в соответствии с Руководство по стилю Tensorflow Отказ

Затем мы импортируем Tensorflow, Numpy для численных расчетов и модуль времени. data_helpers.py Содержит функции, которые помогают с загрузкой и подготовкой набора данных.

Мы запускаем таймер для измерения времени выполнения и определить некоторые параметры. Я расскажу о них позже, когда мы на самом деле используем их. Затем мы загружаем набор данных CIFAR-10. Поскольку чтение данных не является частью ядра того, что мы делаем, я ставлю эти функции в отдельный data_helpers.py Файл, в котором в основном просто читает файлы, содержащие набор данных и помещают данные в структуру данных, которая легко обрабатывать для нас.

Однако одна вещь важно упомянуть. load_data () Разделяет 60000 изображений на две части. Большая часть содержит 50000 изображений. Этот учебный набор – это то, что мы используем для обучения нашей модели. Другие 10000 изображений называются тестовым набором. Наша модель никогда не увидит тех, пока тренировка не будет завершена. Только тогда, когда параметры модели больше не могут быть изменены, мы используем тестовый набор в качестве входа в нашу модель, и измерить производительность модели на наборе теста.

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

Эта концепция модели изучает специфические особенности учебных данных и, возможно, пренебрегая общими функциями, которые мы предпочли бы для того, чтобы учиться, называется переоценкой. Преодоление и как избежать его большой проблемы в машинном обучении. Более подробную информацию о переоценке и почему, как правило, рекомендуется разделить данные не только на 2, но можно найти 3 различных набора данных в Это видео ( Youtube Зеркало ) (Видео является частью отличного бесплатного Free Machine Endrew NG на Coursera ).

Чтобы вернуться к нашему коду, load_data () Возвращает словарь, содержащий

  • images_train : Набор данных в качестве массива 50 000 на 3 072 пикселях x 32 пикселей x 3 цветных канала) значения.
  • Этикетки поезда : 50000 ярлыков для учебного набора (каждый номер от 0 до 9, представляющий какое из 10 классов.
  • images_test : тестовый набор (10000 на 3 072)
  • label_test : 10 000 ярлыков для тестового набора
  • Классы : 10 текстовых меток для перевода значения численного класса в слово (0 для «плоскости», 1 для «автомобиля» и т. Д.)

Теперь мы можем начать строить нашу модель. Фактические численные вычисления обрабатываются Tensorflow, который использует быструю и эффективную репутацию C ++, чтобы сделать это. Tensorflow хочет избежать неоднократно переключения между Python и C ++, потому что это замедляет наши расчеты.

Поэтому общий рабочий процесс сначала определяет все расчеты, которые мы хотим выполнить, создавая так называемый график Tensorflow. Во время этого этапа никаких расчетов фактически не выполняется, мы просто устанавливаем сцену. Только после этого мы запускаем расчеты, предоставляя входные данные и запись результатов.

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

Для нашей модели мы сначала определяем заполнителю для данных изображения, что состоит из значений с плавающей точкой ( TF.float32 ). Форма Аргумент определяет входные размеры. Мы предоставим несколько изображений одновременно (мы поговорим о тех партиях позже ), но мы хотим оставаться гибким о том, сколько изображений мы фактически предоставляем. Первое измерение Форма поэтому Нет , что означает, что размерность может быть любой длины. Второе измерение составляет 3 072, количество значений с плавающей запятой на изображение.

Заполнитель для информации о классе этикетки содержит целочисленные значения ( tf.int64 ), одно значение в диапазоне от 0 до 9 на изображение. Поскольку мы не указываем, сколько изображений мы будем вводить, Форма Аргумент – это [Нет] Отказ

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

Наш вход состоит из номеров 3 072 с плавающей запятой, а нужный выход – один из 10 различных целочисленных значений. Как мы получаем от 3,072 значений одному? Давайте начнем сзади. Вместо единого целочисленного значения от 0 до 9, мы также могли бы посмотреть на 10 оценок – один для каждого класса – а затем выберите класс с наивысшим баллом. Поэтому наш оригинальный вопрос теперь включается: как мы получаем от 3 072 значений до 10?

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

Скажем, первый пиксель красный. Если изображения автомобилей часто имеют красный первый пиксель, мы хотим увеличить счет для автомобиля. Мы достигаем этого, умногая красное значение красного цвета Pixel с положительным числом и добавлением, что в счет автомобиля. Соответственно, если конные изображения никогда не или редко имеют красный пиксель в положении 1, мы хотим, чтобы конный сделл оставаться низким или уменьшением. Это означает умножение с небольшим или отрицательным числом и добавление результата к конвейеству.

Для каждого из 10 классов мы повторяем этот шаг для каждого пикселя и суммируйте все 3 072 значений, чтобы получить единый общий балл, сумма наших 3,072 значений пикселей, взвешенных тем, что 3,072 веса параметров для этого класса. В конце у нас есть 10 баллов, один для каждого класса. Тогда мы просто посмотрим на какой балл самый высокий, и это наша классическая этикетка.

Обозначение для умножения значений пикселей с значениями веса и суммируя результаты могут быть значительно упрощены путем использования матричной записи. Наше изображение представлено 3 072-мерным вектором. Если мы умножим этот вектор с помощью 3,072 х 10 матрицы весов, результат представляет собой 10-мерный вектор, содержащий ровно взвешенные суммы, которые нас интересуют.

Фактические значения в матрице 3 072 x 10 являются нашими параметрами модели. Если они случайный/мусор, наш выход будет случайным/мусором. Вот где вступает в игру тренировок. Посмотрев на данные тренировки, мы хотим, чтобы модель выяснила значения параметров сама по себе.

Все, что мы говорим Tensorflow в двух строках кода выше, состоит в том, что существует 3,072 х 10 матрицы весовых параметров, которые все установлены в 0 в начале. Кроме того, мы определяем второй параметр, 10-мерный вектор, содержащий смещение. Умение не взаимодействует напрямую с данными изображения и добавляется к взвешенным суммам. Предвзятость можно рассматривать как своего рода отправной точкой для наших оценок.

Подумайте о изображении, который полностью черный. Все его значения пикселей будут 0, поэтому все оценки класса тоже будут 0, независимо от того, как Вес Матрица выглядит как. Наличие предубежных предусмотрений позволяет начать с ненулевых баллов класса.

Это где прогноз происходит. Мы организовали размеры наших векторов и матриц таким образом, чтобы мы могли оценить несколько изображений на одном шаге. Результатом этой операции является 10-мерным вектором для каждого входного изображения.

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

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

Оценки, рассчитанные на предыдущем шаге, хранятся в Логиты Переменная содержит произвольные реальные числа. Мы можем преобразовать эти значения в вероятности (реальные значения от 0 до 1, какая сумма до 1), применяя Функция Softmax , который в основном выжимает свой ввод в выход с желаемыми атрибутами. Относительный порядок его входов остается прежним, поэтому класс с наивысшим баллом остается классом с наибольшей вероятностью. Затем распределение вероятностей функции SoftMax по сравнению с истинным распределением вероятностей, который имеет вероятность 1 для правильного класса и 0 для всех других классов.

Мы используем меру под названием Кросс-энтропия Для сравнения двух распределений (более техническое объяснение можно найти здесь ). Чем меньше перекрестная энтропия, тем меньше разница между предсказанным распределением вероятностей и правильной распределением вероятностей. Это значение представляет потери в нашей модели.

К счастью, Tensorflow обрабатывает все детали для нас, обеспечивая функцию, которая имеет именно то, что мы хотим. Мы сравниваем Логиты прогнозы модели, с label_sjacholder правильные этикетки класса. Выход sparse_softmax_cross_entropy_with_logits () Это значение потерь для каждого входного изображения. Затем мы рассчитываем среднее значение потери на входные изображения.

Но как мы можем изменить наши значения параметра, чтобы минимизировать потери? Это то, где Tensorflow работает своей магией. Через технику под названием Auto-Difliation он может рассчитать градиент потери относительно значений параметров. Это означает, что он знает влияние каждого параметра на общую потерю, и уменьшение или увеличение его на небольшом количестве снизит потери. Затем он корректирует все значения параметра соответственно, что должно улучшить точность модели. После того, как этот параметр регулировки шага процессы перезапускается, а следующая группа изображений подается в модель.

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

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

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

Эти две линии измеряют точность модели. argmax Логиты По размеру 1 возвращает индексы класса с наивысшей оценкой, которые являются предсказанными этикетками класса. Этикетки затем сравниваются с правильными этикетками класса по tf.equal () , который возвращает вектор логических ценностей. Логины бросаются в значения поплавка (каждый из которых составляет 0, либо 1), средняя доля правильно прогнозируемых изображений.

Мы наконец сделаем определение графика Tensorflow и готовы к его запуску. График запускается на сеансе, который мы можем получить доступ через Секс Переменная. Первое, что мы делаем после запуска сеанса, инициализации переменных, которые мы создали ранее. В переменных определениях мы указали начальные значения, которые сейчас назначаются переменным.

Затем мы начинаем процесс обучения итеративного обучения, который должен быть повторен max_steps раз.

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

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

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

Здесь первая строка кода выбирает batch_size Случайные показатели между 0 и размер набора тренировок. Затем партии построены путем выбора изображений и наклеек на этих показателях.

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

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

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

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

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

Полученные результаты

Давайте запустим модель с помощью команды « Python Softmax.py ». Вот как мой выход выглядит:

Step   0: training accuracy 0.14 Step 100: training accuracy 0.32 Step 200: training accuracy 0.3 Step 300: training accuracy 0.23 Step 400: training accuracy 0.26 Step 500: training accuracy 0.31 Step 600: training accuracy 0.44 Step 700: training accuracy 0.33 Step 800: training accuracy 0.23 Step 900: training accuracy 0.31 Test accuracy 0.3066 Total time: 12.42s

Что это значит? Точность оценки обученной модели на тестовом наборе составляет около 31%. Если вы сами запускаете код, ваш результат, вероятно, будет около 25-30%. Таким образом, наша модель способна выбрать правильную метку для изображения, которое он никогда не видел до 25-30% времени. Это неплохо!

Существует 10 различных ярлыков, поэтому случайное угадание приведет к точности 10%. Наш очень простой метод уже лучше, чем угадать случайным образом. Если вы думаете, что 25% все еще звучат довольно низко, не забывайте, что модель все еще довольно тупой. Он не имеет представления о фактических функциях изображений, таких как линии или даже формы. Он выглядит строго по цвету каждого пикселя индивидуально, полностью независимым от других пикселей. Изображение, смещенное одним пикселем, будет представлять собой совершенно другой ввод в эту модель. Учитывая это, 25% больше не выглядят слишком потерты.

Что произойдет, если мы обучаем для большего количества итераций? Это, вероятно, не улучшит точность модели. Если вы посмотрите на результаты, вы можете увидеть, что точность обучения не устойчиво не увеличивается, но вместо этого колеблется от 0,23 до 0,44. Кажется, это случай, когда мы достигли предела этой модели, и увидясь на большее количество учебных данных, не помогло бы. Эта модель не может доставить лучшие результаты. На самом деле, вместо подготовки к 1000 итерациям, мы бы получили аналогичную точность после значительно меньшее количество итераций.

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

Этот пост оказался довольно давно. Я хотел бы поблагодарить вас за чтение всего (или для пропуска права на дно)! Я надеюсь, что вы нашли что-то интересное для вас, будь то, как работает классификатор машины, или как строить и запустить простой график с Tensorflow. Конечно, еще много материалов, который я хотел бы добавить. До сих пор мы только говорили о классификаторе SoftMax, который даже не использует никаких нервных сетей.

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

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