Погружение в свёрточные нейронные сети. Часть 5 / 10 — 18 |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-07-08 22:49 Полный курс на русском языке можно найти по этой ссылке. Оригинальный курс на английском доступен по этой ссылке. Выход новых лекций запланирован каждые 2-3 дня.Содержание
Softmax и Sigmoid В прошлом практическом CoLab мы использовали следующую архитектуру свёрточной нейронной сети:
Обратите внимание, что наш последний слой (наш классификатор) состоит из полносвязного слоя с двумя выходными нейронами и функцией активации
Другой популярный подход к решению задач бинарной классификации — использование классификатора, который состоит из полносвязного слоя с 1 выходным нейроном и функцией активации
Оба эти варианта будут хорошо работать в задаче бинарной классификации. Однако, что стоит иметь ввиду, если вы решите воспользоваться функцией активации
Валидация На прошлых занятиях мы изучали точность работы наших свёрточных нейронных сетей используя метрику Для избежания подобной проблемы мы, достаточно часто, используем набор данных для валидации: Во время тренировки наша свёрточная нейронная сеть "видит" только тренировочный набор данных и принимает решения, каким образом изменить значения внутренних параметров — весов и смещений. После каждой обучающей итерации мы проверяем состояние модели, вычисляя значение функции потерь на обучающем наборе данных и на валидационном наборе данных. Стоит отметить и обратить особое внимание на то, что данные из валидационного набора нигде не используются моделью для корректировки значений внутренних параметров. Проверка точности работы модели над валидационным набором данных всего лишь сообщает нам насколько хорошо наша модель работает над этим самым набором данных. Таким образом результаты работы модели на валидационном наборе данных сообщают нам насколько хорошо наша модель научилась обобщать полученные данные и применять это обобщение на новом наборе данных. Идея заключается в том, что раз мы не используем валидационный набор данных при обучении модели, то тестирование работы модели на валидационном наборе позволит нам понять переобучилась ли модель или нет. Давайте рассмотрим пример. В CoLab, который мы выполнили несколькими пунктами выше, мы тренировали нашу нейронную сеть в течение 15 итераций.
Если мы посмотрим на точность предсказаний на тренировочном и валидационном наборах данных на пятнадцатой обучающей итерации, то можно заметить, что мы добились высокой точности на тренировочном наборе данных и значительно низкого показателя на валидационном наборе данных — Это очевидный признак переобучения. Нейронная сеть запомнила тренировочный набор данных, поэтому с невероятной точностью работает по входным данным из него. Однако, как только дело переходит к проверке точности на валидационном наборе данных, которого модель не "видела", то результаты значительно снижаются. Один из способов избежать переобучения является пристальное изучение графика значений функции потерь на тренировочном и валидационном наборах данных на протяжении всех обучающих итераций: В CoLab мы строили подобный график и получили нечто похожее на приведённый выше график зависимости функции потерь от обучающей итерации. Можно заметить, что после определённой обучающей итерации значение функции потерь на валидационном наборе данных начинает возрастать, в то время как значение функции потерь на тренировочном наборе данных продолжает снижаться. В конце 15 обучающей итерации мы замечаем, что значение функции потерь на валидационном наборе данных крайне высоко, а значение функции потерь на обучающем наборе данных крайне мало. Собственно, это и есть тот самый индикатор переобученности нейронной сети. Внимательно глядя на график можно понять, что буквально через несколько обучающих итераций наша нейронная сеть начинает просто-напросто запоминать тренировочные данные, а значит способность модели обобщать снижается, что ведёт к ухудшению точности на валидационном наборе данных. Как вы уже наверняка поняли, валидационный набор данных позволяет нам определить количество обучающих итераций, которые необходимо провести, чтобы наша свёрточная нейронная сеть была точной и, в то же время, не переобучилась. Подобный подход может быть крайне полезен в том случае, если у нас есть выбор из нескольких архитектур свёрточных нейронных сетей: Например, если вы принимаете решение о количестве слоёв в свёрточной нейронной сети, вы можете создать несколько архитектур нейронных сетей, а затем сравнить их точность используя набор данных для валидации. Архитектура нейронной сети, которая позволяет добиться минимального значения функции потерь и будет лучшей для решения поставленной вами задачи. Следующий вопрос, который может у вас возникнуть — зачем создавать валидационный набор данных, если у нас уже есть тестовый набор данных? Можем ли мы использовать тестовый набор данных и для валидации? Проблема заключается в том, что несмотря на то, что мы не используем валидационный набор данных в процессе обучения модели, мы используем результаты работы над тестовым набором данных для повышения точности работы модели, а это значит что тестовый набор данных влияет на веса и смещения в нейронной сети. Именно по этой причина нам нужен валидационный набор данных, который наша модель ещё никогда не видела для точной проверки эффективности её работы. Только что мы разобрались с тем, каким образом валидационный набор данных может помочь нам избежать переобучения. В следующих частях мы поговорим о расширении данных (т.н. augmentation) и об отключениях (т.н. dropout) нейронов — двух популярных техниках, который так же могут нам помочь избежать переобучения. Расширение изображений (т.н. augmentation) Тренируя нейронные сети определять объекты определенного класса мы хотим, чтобы наша нейронная сеть находила эти объекты вне зависимости от их местоположения и размера на изображении. Например, представим, что мы хотим обучить нашу нейронную сеть распознавать собак на изображениях: Таким образом мы хотим, чтобы наша нейронная сеть определяла наличие собаки на изображении вне зависимости от того, какого размера собака и в какой части изображения она находится, часть ли собаки видна или вся собака. Мы хотим сделать так, чтобы наша нейронная сеть могла обработать все эти варианты во время тренировки. Если вам достаточно сильно повезло и у вас имеется большой набор обучающих данных, то можно с уверенностью сказать, что вам повезло и ваша нейронная сеть с малой вероятностью переобучится. Однако, что достаточно часто бывает, нам предстоит работать с ограниченным набором изображений (тренировочных данных), что, в свою очередь, приведёт нашу свёрточную нейронную сеть с большой вероятностью к переобучению и снизит её способность обобщать и выдавать нужный результат на данных, которая она не "видела" ранее. Эту проблему можно решить воспользовавшись техникой называемой "расширением" (image augmentation). Расширение изображений (данных) работает путём создания (генерации) новых изображений для обучения посредством применения произвольных преобразований исходного набора изображений из обучающей выборки. Например, мы можем взять одно из исходных изображений из нашего обучающего набора данных и применить к нему несколько произвольных преобразований — перевернуть на Х градусов, отзеркалить по горизонтали и произвести произвольное увеличение. Добавляя сгенерированные изображения в наш обучающий набор данных мы, тем самым, убеждаемся в том, что наша нейронная сеть "увидит" достаточное количество различных примеров для обучения. В результате подобных действий наша свёрточная нейронная сеть будет лучше обобщать и работать на тех данных, которых она ещё не видела и нам удастся избежать переобучения. В следующей части мы узнаем, что такое dropout (отключение) — другая техника для предотвращения переобучения модели. Исключение (dropout) В этой части мы изучим новую технику — отключение (dropout), которая так же поможет нам избежать переобучения модели. Как мы уже знаем из ранних частей нейронная сеть оптимизирует внутренние параметры (веса и смещения) для минимизации функции потерь. Одна из проблем с которой можно столкнуться во время обучения нейронной сети — огромные значения в одной части нейронной сети и маленькие значение в другой части нейронной сети. В результате получается, что нейроны с большими весами играют большую роль в процессе обучения, а нейроны с меньшими весами перестают быть значимыми и всё меньше подвергаются изменениям. Один из способов избежать подобного — использовать произвольное отключение нейронов (dropout). Отключение (dropout) — процесс выборочного отключения нейронов в процессе обучения. Выборочное отключение одних нейронов в процессе обучения позволяет активно задействовать другие нейроны в обучении. В процессе обучающих итераций мы произвольным образом отключаем некоторые нейроны. Давайте рассмотрим на примере. Представим себе, что на первой обучающей итерации мы отключаем выделенные черным два нейрона: Процессы прямого распространения и обратного распространения происходят без использования выделенных двух нейронов. На второй обучающей итерации мы решаем не задействовать следующие три нейрона — отключаем их: Как и в предыдущем случае, в процессах прямого и обратного распространения мы не задействуем эти три нейрона. На последней, третьей обучающей итерации, мы решаем не задействовать эти два нейрона: И в этом случае в процессах прямого и обратного распространения мы не используем отключенные нейроны. И так далее. Тренируя нашу нейронную сеть таким образом мы можем избежать переобучения. Можно сказать, что наша нейронная сеть становится более устойчивой, потому что при таком подходе она не может полагаться абсолютно на все нейроны для решения поставленной задачи. Таким образом другие нейроны начинают принимать более активное участие в формировании требуемого выходного значения и так же начинают справляться с задачей. На практике такой подход требует указания вероятности исключения каждого из нейронов на любой обучающей итерации. Обратите внимание, что указывая вероятность мы можем оказаться в ситуации, когда некоторые нейроны будут отключаться чаще остальных, а некоторые могут не быть отключенными вообще. Однако, это не является проблемой, потому что данный процесс выполняется множество раз и в среднем каждый нейрон с одинаковой вероятностью может быть отключен. Теперь давайте применим полученные теоретические знания на практике и доработаем наш классификатор изображений кошек и собак. CoLab: собаки и кошки. Повторение CoLab на английском языке доступен по этой ссылке. CoLab на русском языке доступен по этой ссылке. Кошки VS Собаки: классификация изображений с расширением В этой обучающей части мы обсудим то, каким образом можно классифицировать изображения кошек и собак. Мы разработаем классификатор изображений с использованием Идеи, которые будут затронуты в этой части: Мы получим практический опыт разработки классификатора и разовьём интуитивное понимание следующих концепций:
Мы будем следовать основному подходу при разработке моделей машинного обучения:
Перед тем как мы начнем... Перед тем как запускать код в редакторе, рекомедуем сбросить все настройки в Runtime -> Reset all в верхнем меню. Подобное действие позволит избежать проблем с нехваткой памяти, если параллельно вы работали или работаете с несколькими редакторами. Импортирование пакетов Давайте начнём с импорта нужных пакетов:
Импортируем
Загрузка данных Разработку нашего классификатора мы начинаем с загрузки набора данных. Набор данных, который мы используем представляет собой отфильтрованную версию набора данных Собаки vs Кошки с сервиса Kaggle (в конце концов именно этот набор данных предоставляется Microsoft Research). В прошлом CoLab мы с вами использовали набор данных из самого TensorFlow Dataset модуля, который оказывается крайне удобным для работы и тестирования. В этом CoLab однако, мы воспользуемся классом
Набор данных, который мы загрузили, имеет следующую структуру:
Чтобы получить полный список директор можно воспользоваться следующей командой:
Вывод (при запуске из CoLab):
Теперь присвоим переменным корректные пути к директориям с наборами данных для тренировки и валидации:
Разбираемся с данными и их структурой Давайте посмотрим сколько же у нас изображений кошек и собак в тестовом и валидационном наборах данных (директориях).
Вывод:
Установка параметров модели Для удобства мы вынесем установку переменных, которые нам понадобятся для дальнейшей обработки данных и тренировки модели, в отдельное объявление:
Расширение данных Переобучение обычно происходит в тех случаях, когда в нашем наборе данных мало обучающих примеров. Один из способов устранить нехватку данных — их расширение до нужного количества экземпляров и нужной вариативностью. Расширение данных представляет собой процесс генерации данных из существующих экземпляров путём применения различных трансформаций к исходному набору данных. Целью такого метода является увеличение количества уникальных входных экземпляров, которые модель больше никогда не увидит, что, в свою очередь, позволит модели лучше обобщать входные данные и показывать большую точность на валидационном наборе данных. С использованием Для начала давайте напишем функцию, которая будет отображать изображения полученные в результате случайных преобразований. Затем мы подробнее разберём используемые преобразования в процессе расширения исходного набора данных.
Переворачивание изображения по горизонтали Начать мы можем с простого преобразования — горизонтального переворачивания изображения. Посмотрим, каким образом данное преобразование будет выглядеть применённое на наших исходных изображениях. Чтобы добиться подобной трансформации необходимо передать параметр
Вывод:
Чтобы увидеть преобразование в действии давайте возьмём одно из наших изображений из обучающего набора данных и повторим его пять раз. Преобразование будет произвольным образом применено (или не будет) к каждой копии.
Вывод (2 из 5 изображений): Поворот изображений Преобразование в виде поворота произвольным образом повернёт изображение на определённое количество градусов. В нашем примере значение угла поворота равно 45.
Вывод:
Чтобы увидеть преобразование мы поступим таким же образом — возьмём одно произвольное изображение из входного набора данных и 5 раз его повторим. Преобразование будет произвольным образом применено (или не применено) к каждой копии.
Вывод (2 изображения из 5): Применение увеличения Мы так же можем применить преобразование увеличения к нашему входному набору данных — увеличить произвольно до х50%.
Вывод:
Поступим так же, как поступали в прошлый раз — 5 раз повторим одно из входных изображений. Преобразование будет (или не будет) случайным образом применено к каждой копии изображения.
Вывод (2 из 5 изображений): Объединяем всё вместе Мы можем применить все приведённые выше преобразования, и даже больше, одной строкой кода, лишь передавая нужные аргументы с нужными значениями конструктору класса Пора объединить все использованные ранее преобразования — изменение размеров изображения, поворот на 45 градусов, смещение по ширине, смещение по высоте, горизонтальный переворот и увеличение.
Вывод:
Давайте визуализируем то, каким образом будут выглядеть изображения к которым будут применены произвольные преобразования.
Вывод (2 изображения из 5): Создаём валидационный набор данных В основном, расширение данных применяется на обучающем наборе данных, чтобы они представляли собой репрезентативную выборку того, каким образом будут выглядеть настоящие входные данные с которыми предстоит работать модели. Поэтому к валидационному набору данных мы никаких преобразований, кроме изменения размера, не применяем.
Создание модели Описываем модель Модель состоит из 4 блоков свёртки после каждого из которых следует блок со слоем подвыборки. Перед последним полносвязным слоем мы так же применяем исключение со значением вероятности 0.5. Это означает, что 50% значений поступающих на вход этому слою будут сброшены до 0. Это позволит избежать переобучения. Далее у нас идёт полносвязный слой с 512 нейронами и функцией активации
Компилирование модели Как и ранее мы воспользуемся оптимизатором
Представление модели Давайте взглянем на структуру нашей модели по уровням используя метод summary:
Вывод:
Тренировка модели Настала пора тренировки модели! Так как обучающие блоки будут поступать из генератора (
Визуализация результатов тренировки Теперь мы визуализируем результаты тренировки нашей модели:
Вывод: Другие техники для предотвращения переобучения На этом занятии мы познакомились с тремя техниками, которые позволят избежать переобучения:
Мы рассмотрели некоторые наиболее популярные техники борьбы с переобучением, однако это далеко не всё. Больше про существующие методы борьбы с переобучением можно узнать из этой статьи. Упражнение: классификация изображений цветов Оригинальный CoLab на английском языке доступен по этой ссылке. CoLab на русском языке доступен по этой ссылке. Теперь настала пора вам применить все полученные знания и построить свёрточную нейронную сеть для классификации цветов. Мы специально создали почти пустой CoLab для создания свёрточной нейронной сети и её тренировки. В этом CoLab мы загрузим набор данных изображениц цветов и разделим его на обучающий набор данных и валидационный. В отдельном CoLab мы так же предоставим решение этого упражнения, что бы вы могли свериться с ним и сравнить собственные результаты с нашими. Мы настоятельно рекомендуем писать весь код самому и не копировать готовые решения из предыдущих CoLab. В конце CoLab мы хотим предложить вам поиграться со значениями параметров, гиперпараметров и поэкспериментировать с различными архитектурами моделей, чтобы определить какая же из них даст нибольшую точность. Наслаждайтесь! # Классификация изображений с использованием tf.keras В этом CoLab вы будете классифицировать изображения цветов. Вы будете разрабатывать классификатор изображений с использованием Импортирование пакетов Давайте начнем с импортирования необходимых пакетов.
TODO: импортируем TensorFlow и Keras-слои В приведённой ниже области для исходного кода импортируйте TensorFlow как
Загрузка данных Начать разработку нашего классификатора изображений нужно с загрузки набора данных с которым мы будем работать — цветочный набор данных. Первым делом необходимо загрузить архив с набором данных и сохранить его во временной директории. Загруженный архив необходимо разархивировать.
Набор данных, который мы загрузили архивом, содержит 5 типов цветов:
Создадим метки для каждого из этих пяти классов:
Набор данных, который мы загрузили, имеет следующую структуру:
Как вы уже обратили внимание в структуре загруженного набора данных отсутствуют директории с обучающим набором данных и валидационным. Таким образом создание этих двух наборов данных будет лежать на наших плечах. Давайте напишем код, который будет это делать. Код ниже создаёт 2 директории
Так как мы не удаляем исходные директории, то они останутся у нас, но будут пустыми. Код ниже так же выведет на экран количество изображений по каждому типу цветка.
Для удобства вынесем ссылки на директории каждого набора данных в отдельные переменные:
Расширение данных Переобучение, в основном, происходит тогда, когда у нас маленький обучающий набор данных. Один из способов устранить эту проблему — расширение данных (т.н. augmentation) до нужного количества обучающих примеров. Расширение данных представляет собой процесс применения произвольных трансформации к исходным данным и добавление полученных изменённых данных в первоначальный обучающий набор. Цель заключается в том, чтобы сгенерировать реалистичные изображения, которые модель больше никогда не увидит в последующем — ни в валидационном наборе данных, ни в тестовом. Такой подход позволяет модели лучше обобщать и извлекать различные признаки. В tf.keras мы можем это реализовать с использованием класса, который раньше нами применялся для генерации обучающего набора данных кошек и собак — ImageDataGenerator. Мы просто передаём конструктору класса набор различных значений нужных нам параметров и обо всём остальном он позаботится сам. Экспериментируйте с различными преобразованиями изображений В этой части вы получите практический опыт применения некоторых базовых преобразования изображений. Перед тем как мы будем применять преобразования давайте объявим две переменные — одна будет содержать значение количества обучающих блоков (изображений) за одну итерацию TODO: установите количество обучающих блоков и размер изображений В ячейке ниже укажите значение 100 для переменной
TODO: примените произвольный горизонтальный переворот изображения В ячейке ниже воспользуйтесь классом
Давайте возьмём одно произвольное изображение и отобразим его 5 раз применив случайным образом наше преобразование:
TODO: примените произвольный переворот изображения В ячейке ниже, воспользовавшись классом
Давайте возьмём одно произвольное изображение и отобразим его 5 раз применив случайным образом наше преобразование:
TODO: примените произвольное увеличение изображения В ячейке ниже, воспользовавшись классом ImageDataGenerator сперва нормализуйте цветное изображение и примените произвольное увеличение до 50%. После этого воспользуйтесь методом .flow_from_directory для применения полученного преобразования к изображениям из обучающего набора данных. Убедитесь, что указали корректно размер обучающего блока, путь к директории с обучающим набором данных, целевой размер изображений и не забудьте затем перемешать все изображения.
Давайте возьмём одно произвольное изображение и отобразим его 5 раз применив случайным образом наше преобразование:
TODO: объединяем все изменения В ячейке ниже укажите код, который использует
Затем воспользуйтесь методом
Давайте возьмём одно произвольное изображение и отобразим его 5 раз применив случайным образом наши преобразования:
TODO: создайте генератор изображений для валидационного набора данных В основном расширение данных применяется к обучающему набору данных. Поэтому, в ячейке ниже, воспользуйтесь классом
TODO: Создайте свёрточную нейронную сеть В ячейке ниже создайте свёрточную нейронную сеть, которая будет состоять из 3 свёрточных пар — слой свёртки и слой подвыборки по максимальному значению. Первый свёрточный слой должен иметь 16 фильтров, второй — 32 фильтра, третий — 64 фильтра. Все фильтры должны быть размером 3х3. Размер окна подвыборки на всех слоях должен быть размером 2х2. После всех трёх свёрточных пар должен идти слой
TODO: скомпилируйте модель В ячейке ниже напишите код, который будет компилировать модель с использованием оптимизатора
TODO: обучите модель В ячейке ниже напишите код, который запустит обучение модели с использованием функции fit_generator вместо обычной функции fit, которую мы ранее использовали. Мы используем функцию fit_generator потому что прибегаем к использованию класса ImageDataGenerator для генерации новых обучающих и валидационных данных для нашей модели. Обучите модель на 80 итерациях и убедитесь, что используете подходящие параметры в fit_generator-функции.
TODO: постройте графики точности / потерь для обучающего и валидационного наборов данных В ячейке ниже напишите код, который построит графики точности и потерь для обучающего и валидационного наборов данных:
TODO: поэкспериментируйте с различными параметрами Дойдя до этого момента вы создали свёрточную нейронную сеть с тремя свёрточными блоками (слой свёртки + слой подвыборки) и последующим полносвязным слоем состоящим из 512 нейронов. В ячейке ниже напишите код для создания новой свёрточной сети с другой архитектурой. Не бойтесь экспериментировать со значениями параметров. Например, вы можете добавить больше свёрточных или полносвязных слоёв с различным количеством нейронов, изменить параметры слоя отключения нейронов и т.п. Вы так же можете поэкспериментировать с большим количеством преобразований, используя тот самый класс ImageDataGenerator — изменять произвольным образом яркость изображения или смещения по осям. Поэкспериментируйте с как можно большим количеством изменений, чтобы у вас была возможность сравнить точность работы модели по различным комбинациям параметров. Изменения каких параметров дают наибольший результат? Итоги В этой части мы рассмотрели как свёрточные нейронные сети работают с цветными изображениями и каким образом можно избежать их переобучения. Основные моменты из прошедшей главы относительно свёрточных нейронных сетей при работе с RGB-изображениями различного размера:
Методы для избежания переобучения:
Мы так же разработали и обучили свёрточную нейронную сеть классифицировать изображения кошек и собак без использования расширений изображений и отключения нейронов в сети. Как вы уже смогли убедиться на примере, расширение изображений и произвольные отключения нейронов в процессе обучения позволили нашей модели увеличить точность на валидационном наборе данных и избежать переобучения. А в качестве упражнения у вас была возможность применить полученные знания для создания свёрточной нейронной сети для классификации изображений цветов. … и стандартные call-to-action — подписывайся, ставь плюс и делай share :) Источник: habr.com Комментарии: |
|