1. Обзор
В этой лабораторной работе вы узнаете, как собрать сверточный слой в модель нейронной сети, которая может распознавать цветы. На этот раз вы сами построите модель с нуля и воспользуетесь мощью ТПУ, чтобы за секунды обучить ее и отработать проект.
Эта лабораторная работа включает необходимые теоретические объяснения сверточных нейронных сетей и является хорошей отправной точкой для разработчиков, изучающих глубокое обучение.
Эта лабораторная работа является третьей частью серии «Керас в ТПУ». Вы можете делать их в следующем порядке или самостоятельно.
- Конвейеры данных со скоростью TPU: tf.data.Dataset и TFRecords
- Ваша первая модель Keras с трансферным обучением
- [ЭТА ЛАБОРАТОРНАЯ ЛАБОРАТОРИЯ] Сверточные нейронные сети с Keras и TPU
- Современные сети, сжимающие сети, Xception, с Keras и TPU.
Что вы узнаете
- Чтобы построить классификатор сверточных изображений с использованием модели Keras Sequential.
- Чтобы обучить свою модель Keras на TPU
- Для точной настройки вашей модели с помощью хорошего выбора сверточных слоев.
Обратная связь
Если вы заметили что-то неладное в этой лаборатории кода, сообщите нам. Обратная связь может быть предоставлена через вопросы GitHub [ ссылка обратной связи ].
2. Быстрый старт Google Colaboratory
Эта лабораторная работа использует Google Collaboratory и не требует никакой настройки с вашей стороны. Colaboratory — это онлайн-платформа для записных книжек для образовательных целей. Он предлагает бесплатное обучение процессорам, графическим процессорам и TPU.
Вы можете открыть этот образец блокнота и просмотреть пару ячеек, чтобы ознакомиться с Colaboratory.
Выберите серверную часть TPU
В меню Colab выберите «Время выполнения» > «Изменить тип среды выполнения» , а затем выберите «TPU». В этой лаборатории по кодированию вы будете использовать мощный TPU (тензорный процессор), поддерживающий аппаратное ускорение обучения. Подключение к среде выполнения произойдет автоматически при первом запуске, или вы можете использовать кнопку «Подключиться» в правом верхнем углу.
Исполнение ноутбука
Выполняйте ячейки по одной, щелкая ячейку и используя Shift-ENTER. Вы также можете запустить весь блокнот, выбрав «Среда выполнения» > «Выполнить все».
Оглавление
Все тетради имеют оглавление. Открыть его можно с помощью черной стрелки слева.
Скрытые ячейки
В некоторых ячейках будет отображаться только заголовок. Это функция блокнота, специфичная для Colab. Вы можете дважды щелкнуть по ним, чтобы увидеть код внутри, но обычно это не очень интересно. Обычно функции поддержки или визуализации. Вам все равно нужно запустить эти ячейки, чтобы определить функции внутри.
Аутентификация
Colab может получить доступ к вашим частным корзинам облачного хранилища Google при условии, что вы пройдете аутентификацию с использованием авторизованной учетной записи. Приведенный выше фрагмент кода запустит процесс аутентификации.
3. [ИНФОРМАЦИЯ] Что такое тензорные процессоры (TPU)?
В двух словах
Код для обучения модели на TPU в Keras (и использования графического процессора или процессора, если TPU недоступен):
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
Сегодня мы будем использовать TPU для создания и оптимизации классификатора цветов на интерактивной скорости (минуты на тренировочный прогон).
Почему ТПУ?
Современные графические процессоры организованы вокруг программируемых «ядер» — очень гибкой архитектуры, которая позволяет им решать различные задачи, такие как 3D-рендеринг, глубокое обучение, физическое моделирование и т. д. С другой стороны, TPU сочетают в себе классический векторный процессор со специализированным процессором. модуль матричного умножения и преуспейте в любой задаче, где доминируют большие матричные умножения, например, в нейронных сетях.
Иллюстрация: плотный слой нейронной сети в виде матричного умножения с пакетом из восьми изображений, обрабатываемых нейронной сетью одновременно. Пожалуйста, выполните умножение одной строки на столбец, чтобы убедиться, что оно действительно выполняет взвешенную сумму всех значений пикселей изображения. Сверточные слои также можно представить как умножения матриц, хотя это немного сложнее ( объяснение здесь, в разделе 1 ).
Аппаратное обеспечение
МХУ и ВПУ
Ядро TPU v2 состоит из блока умножения матриц (MXU), который выполняет умножение матриц, и блока векторной обработки (VPU) для всех других задач, таких как активации, softmax и т. д. VPU обрабатывает вычисления float32 и int32. С другой стороны, MXU работает в формате с плавающей запятой смешанной точности (16–32 бита).
С плавающей запятой смешанной точности и bfloat16
MXU вычисляет умножение матриц, используя входные данные bfloat16 и выходные данные float32. Промежуточные накопления выполняются с точностью float32.
Обучение нейронной сети обычно устойчиво к шуму, вносимому пониженной точностью с плавающей запятой. Бывают случаи, когда шум даже помогает оптимизатору сходиться. 16-битная точность с плавающей запятой традиционно использовалась для ускорения вычислений, но форматы float16 и float32 имеют очень разные диапазоны. Уменьшение точности с float32 до float16 обычно приводит к переполнению или потере значения. Решения существуют, но для работы float16 обычно требуется дополнительная работа.
Именно поэтому Google представила формат bfloat16 в TPU. bfloat16 — это усеченное число float32 с точно такими же битами экспоненты и диапазоном, что и у float32. Это, в сочетании с тем фактом, что TPU выполняют умножение матриц со смешанной точностью с использованием входных данных bfloat16 и выходных данных float32, означает, что, как правило, никаких изменений кода не требуется, чтобы получить выгоду от повышения производительности за счет пониженной точности.
Систолический массив
MXU реализует умножение матриц аппаратно, используя так называемую архитектуру «систолического массива», в которой элементы данных проходят через массив аппаратных вычислительных блоков. (В медицине термин «систолический» относится к сокращениям сердца и кровотоку, здесь — к потоку данных.)
Основным элементом матричного умножения является скалярное произведение строки одной матрицы и столбца другой матрицы (см. иллюстрацию вверху этого раздела). Для матричного умножения Y=X*W одним элементом результата будет:
Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]
На графическом процессоре можно было бы запрограммировать это скалярное произведение в «ядро» графического процессора, а затем выполнить его на стольких «ядрах», сколько доступно параллельно, чтобы попытаться вычислить каждое значение результирующей матрицы одновременно. Если результирующая матрица имеет размер 128x128, для этого потребуется наличие 128x128 = 16 КБ «ядер», что обычно невозможно. Самые большие графические процессоры имеют около 4000 ядер. С другой стороны, TPU использует минимум аппаратного обеспечения для вычислительных блоков в MXU: просто bfloat16 x bfloat16 => float32
умножительные аккумуляторы, и ничего больше. Они настолько малы, что TPU может реализовать 16 КБ из них в MXU 128x128 и обработать умножение матриц за один раз.
Иллюстрация: систолическая диаграмма MXU. Вычислительные элементы представляют собой многократные аккумуляторы. В массив загружаются значения одной матрицы (красные точки). Значения другой матрицы проходят через массив (серые точки). Вертикальные линии распространяют значения вверх. Горизонтальные линии распространяют частичные суммы. Пользователю остается в качестве упражнения проверить, что по мере прохождения данных через массив вы получаете результат умножения матрицы, выходящий из правой части.
В дополнение к этому, пока скалярные произведения вычисляются в MXU, промежуточные суммы просто передаются между соседними вычислительными блоками. Их не нужно сохранять и извлекать из памяти или даже из регистрового файла. Конечным результатом является то, что архитектура систолического массива TPU имеет значительное преимущество в плотности и мощности, а также немалое преимущество в скорости по сравнению с графическим процессором при вычислении умножения матриц.
Облачный ТПУ
Когда вы запрашиваете один « Cloud TPU v2» на Google Cloud Platform, вы получаете виртуальную машину (ВМ) с платой TPU, подключенной к PCI. Плата TPU имеет четыре двухъядерных чипа TPU. Каждое ядро TPU оснащено VPU (блок векторной обработки) и MXU 128x128 (блок умножения MatriX). Этот «Облачный TPU» затем обычно подключается через сеть к виртуальной машине, которая его запросила. Итак, полная картина выглядит так:
Иллюстрация: ваша виртуальная машина с сетевым ускорителем Cloud TPU. Сам «Облачный TPU» состоит из виртуальной машины с подключенной к PCI платой TPU с четырьмя двухъядерными чипами TPU.
капсулы ТПУ
В центрах обработки данных Google TPU подключены к межсоединению высокопроизводительных вычислений (HPC), благодаря чему они могут выглядеть как один очень большой ускоритель. Google называет их модулями, и они могут включать в себя до 512 ядер TPU v2 или 2048 ядер TPU v3.
Иллюстрация: модуль TPU v3. Платы и стойки TPU подключаются через межсоединение HPC.
Во время обучения градиенты обмениваются между ядрами TPU с использованием алгоритма all-reduce ( хорошее объяснение all-reduce здесь ). Обучаемая модель может воспользоваться преимуществами аппаратного обеспечения при обучении на больших размерах пакетов.
Иллюстрация: синхронизация градиентов во время обучения с использованием алгоритма полного сокращения в двухмерной тороидальной сети высокопроизводительных вычислений Google TPU.
Программное обеспечение
Обучение в больших объемах
Идеальный размер пакета для TPU — 128 элементов данных на ядро TPU, но оборудование уже может демонстрировать хорошее использование 8 элементов данных на ядро TPU. Помните, что один Cloud TPU имеет 8 ядер.
В этой лаборатории кода мы будем использовать Keras API. В Keras указанный вами пакет является глобальным размером пакета для всего TPU. Ваши пакеты будут автоматически разделены на 8 и запущены на 8 ядрах TPU.
Дополнительные советы по производительности см. в Руководстве по производительности TPU . При очень больших размерах партий в некоторых моделях может потребоваться особая осторожность, более подробную информацию см. в разделе LARSOptimizer .
Под капотом: XLA.
Программы Tensorflow определяют графы вычислений. TPU не запускает код Python напрямую, он запускает граф вычислений, определенный вашей программой Tensorflow. Под капотом компилятор под названием XLA (ускоренный компилятор линейной алгебры) преобразует граф вычислительных узлов Tensorflow в машинный код TPU. Этот компилятор также выполняет множество расширенных оптимизаций вашего кода и структуры памяти. Компиляция происходит автоматически по мере отправки работы в TPU. Вам не обязательно явно включать XLA в цепочку сборки.
Иллюстрация: для работы на TPU граф вычислений, определенный вашей программой Tensorflow, сначала преобразуется в представление XLA (ускоренный компилятор линейной алгебры), а затем компилируется XLA в машинный код TPU.
Использование TPU в Keras
TPU поддерживаются через Keras API, начиная с Tensorflow 2.1. Поддержка Keras работает на TPU и модулях TPU. Вот пример, который работает на TPU, графических процессорах и процессоре:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
В этом фрагменте кода:
-
TPUClusterResolver().connect()
находит TPU в сети. Он работает без параметров в большинстве облачных систем Google (задания платформы AI, Colaboratory, Kubeflow, виртуальные машины глубокого обучения, созданные с помощью утилиты «ctpu up»). Эти системы знают, где находится их TPU, благодаря переменной среды TPU_NAME. Если вы создаете TPU вручную, либо установите окружение TPU_NAME. вар. на виртуальной машине, из которой вы его используете, или вызовитеTPUClusterResolver
с явными параметрами:TPUClusterResolver(tp_uname, zone, project)
-
TPUStrategy
— это часть, которая реализует распределение и алгоритм синхронизации градиента «все-сокращение». - Стратегия применяется через область видимости. Модель должна быть определена в области действия стратегии().
- Функция
tpu_model.fit
ожидает объект tf.data.Dataset в качестве входных данных для обучения TPU.
Распространенные задачи портирования TPU
- Хотя существует множество способов загрузки данных в модель Tensorflow, для TPU требуется использование API
tf.data.Dataset
. - TPU очень быстрые, и прием данных часто становится узким местом при работе на них. В Руководстве по производительности TPU есть инструменты, которые можно использовать для обнаружения узких мест в данных, а также другие советы по производительности.
- Числа int8 или int16 обрабатываются как int32. TPU не имеет целочисленного оборудования, работающего с разрядностью менее 32 бит.
- Некоторые операции Tensorflow не поддерживаются. Список здесь . Хорошей новостью является то, что это ограничение применимо только к обучающему коду, то есть к прямому и обратному проходу через вашу модель. Вы по-прежнему можете использовать все операции Tensorflow в своем конвейере ввода данных, поскольку они будут выполняться на ЦП.
-
tf.py_func
не поддерживается в TPU.
4. [ИНФО] Классификатор нейронной сети 101
В двух словах
Если все термины, выделенные жирным шрифтом в следующем абзаце, вам уже известны, можно переходить к следующему упражнению. Если вы только начинаете глубокое обучение, добро пожаловать и читайте дальше.
Для моделей, построенных как последовательность слоев, Keras предлагает Sequential API. Например, классификатор изображений, использующий три плотных слоя, можно записать в Keras как:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
tf.keras.layers.Dense(500, activation="relu"),
tf.keras.layers.Dense(50, activation="relu"),
tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
Плотная нейронная сеть
Это простейшая нейронная сеть для классификации изображений. Он состоит из «нейронов», расположенных слоями. Первый уровень обрабатывает входные данные и передает их выходные данные на другие уровни. Он называется «плотным», потому что каждый нейрон связан со всеми нейронами предыдущего слоя.
Вы можете передать изображение в такую сеть, объединив значения RGB всех его пикселей в длинный вектор и используя его в качестве входных данных. Это не лучший метод распознавания изображений, но позже мы улучшим его.
Нейроны, активации, RELU
«Нейрон» вычисляет взвешенную сумму всех своих входных данных, добавляет значение, называемое «смещением», и передает результат через так называемую «функцию активации». Веса и смещение сначала неизвестны. Они будут инициализированы случайным образом и «обучены» путем обучения нейронной сети на большом количестве известных данных.
Самая популярная функция активации называется RELU для выпрямленных линейных единиц. Это очень простая функция, как вы можете видеть на графике выше.
Активация Софтмакс
Сеть выше заканчивается слоем из 5 нейронов, поскольку мы классифицируем цветы по 5 категориям (роза, тюльпан, одуванчик, ромашка, подсолнух). Нейроны в промежуточных слоях активируются с помощью классической функции активации RELU. Однако на последнем слое мы хотим вычислить числа от 0 до 1, представляющие вероятность того, что этот цветок будет розой, тюльпаном и так далее. Для этого мы будем использовать функцию активации под названием «softmax».
Применение softmax к вектору осуществляется путем взятия экспоненты каждого элемента и последующей нормализации вектора, обычно с использованием нормы L1 (суммы абсолютных значений), так что сумма значений равна 1 и может интерпретироваться как вероятности.
Перекрестная энтропийная потеря
Теперь, когда наша нейронная сеть выдает прогнозы на основе входных изображений, нам нужно измерить, насколько они хороши, то есть расстояние между тем, что нам сообщает сеть, и правильными ответами, часто называемыми «метками». Помните, что у нас есть правильные метки для всех изображений в наборе данных.
Подойдет любое расстояние, но для задач классификации наиболее эффективным является так называемое «перекрестное энтропийное расстояние». Мы назовем это нашей функцией ошибки или «потери»:
Градиентный спуск
«Обучение» нейронной сети на самом деле означает использование обучающих изображений и меток для корректировки весов и смещений, чтобы минимизировать функцию перекрестных энтропийных потерь. Вот как это работает.
Перекрестная энтропия — это функция весов, смещений, пикселей обучающего изображения и его известного класса.
Если мы вычислим частные производные перекрестной энтропии относительно всех весов и всех смещений, мы получим «градиент», рассчитанный для данного изображения, метки и текущего значения весов и смещений. Помните, что у нас могут быть миллионы весов и смещений, поэтому вычисление градиента кажется большой работой. К счастью, Tensorflow делает это за нас. Математическое свойство градиента заключается в том, что он направлен «вверх». Поскольку мы хотим пойти туда, где перекрестная энтропия низкая, мы идем в противоположном направлении. Мы обновляем веса и смещения на долю градиента. Затем мы делаем то же самое снова и снова, используя следующие партии обучающих изображений и меток в цикле обучения. Будем надеяться, что это приведет к тому, что перекрестная энтропия будет минимальной, хотя ничто не гарантирует, что этот минимум уникален.
Мини-пакетирование и импульс
Вы можете вычислить градиент только на одном примере изображения и немедленно обновить веса и смещения, но если сделать это, например, на пакете из 128 изображений, вы получите градиент, который лучше отражает ограничения, налагаемые различными примерами изображений, и, следовательно, с большой вероятностью сходится. к решению быстрее. Размер мини-партии является регулируемым параметром.
Этот метод, иногда называемый «стохастическим градиентным спуском», имеет еще одно, более прагматичное преимущество: работа с пакетами также означает работу с более крупными матрицами, и их обычно легче оптимизировать на графических процессорах и TPU.
Однако сходимость все еще может быть немного хаотичной и может даже прекратиться, если вектор градиента будет равен нулю. Означает ли это, что мы нашли минимум? Не всегда. Компонент градиента может быть равен нулю в минимуме или максимуме. Для вектора градиента с миллионами элементов, если все они нули, вероятность того, что каждый ноль соответствует минимальной точке и ни один из них не соответствует максимальной точке, довольно мала. В пространстве многих измерений седловые точки встречаются довольно часто, и мы не хотим на них останавливаться.
Иллюстрация: седловая точка. Градиент равен 0, но не является минимальным во всех направлениях. (Атрибуция изображения Wikimedia: Никогуаро — собственная работа, CC BY 3.0 )
Решение состоит в том, чтобы добавить некоторый импульс алгоритму оптимизации, чтобы он мог проходить мимо седловых точек без остановки.
Глоссарий
пакет или мини-пакет : обучение всегда выполняется на пакетах обучающих данных и меток. Это помогает алгоритму сходиться. «Пакетное» измерение обычно является первым измерением тензоров данных. Например, тензор формы [100, 192, 192, 3] содержит 100 изображений размером 192x192 пикселей с тремя значениями на пиксель (RGB).
перекрестная энтропийная потеря : специальная функция потерь, часто используемая в классификаторах.
плотный слой : слой нейронов, где каждый нейрон связан со всеми нейронами предыдущего слоя.
функции : входы нейронной сети иногда называют «функциями». Искусство определения того, какие части набора данных (или комбинации частей) нужно передать в нейронную сеть для получения хороших прогнозов, называется «инжинирингом функций».
метки : другое название «классов» или правильных ответов в задаче контролируемой классификации.
скорость обучения : доля градиента, с помощью которой веса и смещения обновляются на каждой итерации цикла обучения.
логиты : выходные данные слоя нейронов до применения функции активации называются «логитами». Этот термин происходит от «логистической функции», также известной как «сигмовидная функция», которая раньше была самой популярной функцией активации. «Выходы нейронов перед логистической функцией» были сокращены до «логитов».
loss : функция ошибок, сравнивающая выходные данные нейронной сети с правильными ответами.
нейрон : вычисляет взвешенную сумму своих входных данных, добавляет смещение и передает результат через функцию активации.
горячее кодирование : класс 3 из 5 кодируется как вектор из 5 элементов, все нули, кроме третьего, который равен 1.
relu : выпрямленная линейная единица. Популярная функция активации нейронов.
sigmoid : еще одна функция активации, которая раньше была популярна и до сих пор полезна в особых случаях.
softmax : специальная функция активации, которая действует на вектор, увеличивает разницу между самым большим компонентом и всеми остальными, а также нормализует вектор, чтобы его сумма была равна 1, чтобы его можно было интерпретировать как вектор вероятностей. Используется как последний шаг в классификаторах.
тензор : «Тензор» похож на матрицу, но с произвольным количеством измерений. Одномерный тензор — это вектор. Двумерный тензор является матрицей. И тогда у вас могут быть тензоры с 3, 4, 5 или более измерениями.
5. [НОВАЯ ИНФОРМАЦИЯ] Сверточные нейронные сети
В двух словах
Если все термины, выделенные жирным шрифтом в следующем абзаце, вам уже известны, можно переходить к следующему упражнению. Если вы только начинаете работать со сверточными нейронными сетями, читайте дальше.
Иллюстрация: фильтрация изображения с помощью двух последовательных фильтров, состоящих из 4x4x3=48 обучаемых весов каждый.
Вот как выглядит простая сверточная нейронная сеть в Keras:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
Сверточные нейронные сети 101
В слое сверточной сети один «нейрон» выполняет взвешенную сумму пикселей чуть выше него только по небольшой области изображения. Он добавляет смещение и передает сумму через функцию активации, как это сделал бы нейрон в обычном плотном слое. Затем эта операция повторяется по всему изображению с использованием тех же весов. Помните, что в плотных слоях каждый нейрон имел свой вес. Здесь один «участок» весов скользит по изображению в обоих направлениях («свертка»). Выходные данные имеют столько значений, сколько пикселей в изображении (однако по краям необходимо некоторое заполнение). Это операция фильтрации с использованием фильтра 4x4x3=48 весов.
Однако 48 гирь будет недостаточно. Чтобы добавить больше степеней свободы, мы повторяем ту же операцию с новым набором весов. Это создает новый набор выходных сигналов фильтра. Назовем его «каналом» выходов по аналогии с каналами R,G,B во входном изображении.
Два (или более) набора весов можно суммировать в один тензор, добавив новое измерение. Это дает нам общую форму тензора весов для сверточного слоя. Поскольку количество входных и выходных каналов является параметром, мы можем начать складывать и объединять сверточные слои в цепочку.
Иллюстрация: сверточная нейронная сеть преобразует «кубы» данных в другие «кубы» данных.
Шагающие свертки, максимальное объединение
Выполняя свертки с шагом 2 или 3, мы также можем сжать полученный куб данных в его горизонтальных измерениях. Есть два распространенных способа сделать это:
- Шаговая свертка: скользящий фильтр, как указано выше, но с шагом> 1.
- Максимальное объединение: скользящее окно, применяющее операцию MAX (обычно для патчей 2x2, повторяющееся каждые 2 пикселя).
Иллюстрация: сдвиг окна вычислений на 3 пикселя приводит к меньшему количеству выходных значений. Пошаговые свертки или максимальное объединение (максимум в окне 2x2, сдвигающемся с шагом 2) — это способ сжатия куба данных в горизонтальных измерениях.
Сверточный классификатор
Наконец, мы прикрепляем классификационную головку, выравнивая последний куб данных и пропуская его через плотный слой, активированный softmax. Типичный сверточный классификатор может выглядеть так:
Иллюстрация: классификатор изображений, использующий сверточные и softmax-слои. Он использует фильтры 3x3 и 1x1. Слои maxpool принимают максимум групп точек данных 2x2. Головка классификации реализована плотным слоем с активацией softmax.
В Керасе
Проиллюстрированный выше сверточный стек можно записать на Keras следующим образом:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
6. Ваша собственная сеть
Практический
Давайте построим и обучим сверточную нейронную сеть с нуля. Использование TPU позволит нам выполнять итерации очень быстро. Откройте следующую записную книжку, заполните ячейки (Shift-ENTER) и следуйте инструкциям везде, где вы видите надпись «ТРЕБУЕТСЯ РАБОТА».
Keras_Flowers_TPU (playground).ipynb
Цель состоит в том, чтобы превзойти точность модели трансферного обучения на уровне 75%. У этой модели было преимущество: она была предварительно обучена на наборе данных из миллионов изображений, тогда как у нас здесь только 3670 изображений. Можете ли вы хотя бы соответствовать этому?
Дополнительная информация
Сколько слоев, какой размер?
Выбор размеров слоев — это скорее искусство, чем наука. Вы должны найти правильный баланс между слишком малым и слишком большим количеством параметров (весов и отклонений). Если весов слишком мало, нейронная сеть не сможет представить всю сложность форм цветов. Если их слишком много, он может быть склонен к «переоснащению», то есть специализироваться на обучающих изображениях и не иметь возможности обобщать. Модель с большим количеством параметров также будет медленно обучаться. В Keras функция model.summary()
отображает структуру и количество параметров вашей модели:
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 192, 192, 16) 448
_________________________________________________________________
conv2d_1 (Conv2D) (None, 192, 192, 30) 4350
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 96, 96, 60) 16260
_________________________________________________________________
...
_________________________________________________________________
global_average_pooling2d (Gl (None, 130) 0
_________________________________________________________________
dense (Dense) (None, 90) 11790
_________________________________________________________________
dense_1 (Dense) (None, 5) 455
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________
Несколько советов:
- Наличие нескольких слоев делает «глубокие» нейронные сети эффективными. Для этой простой задачи распознавания цветов имеет смысл использовать от 5 до 10 слоев.
- Используйте небольшие фильтры. Обычно фильтры 3х3 хороши везде.
- Фильтры 1x1 тоже можно использовать, они дешевы. На самом деле они ничего не «фильтруют», а вычисляют линейные комбинации каналов. Чередуйте их с настоящими фильтрами. (Подробнее о «свертках 1x1» в следующем разделе.)
- Для решения подобной проблемы классификации часто понижайте дискретизацию с помощью слоев с максимальным объединением (или сверток с шагом> 1). Вас не волнует, где находится цветок, важно лишь то, что это роза или одуванчик, поэтому потеря информации x и y не важна, а фильтрация меньших областей обходится дешевле.
- Количество фильтров обычно становится равным количеству классов в конце сети (почему? см. трюк с «глобальным средним пулом» ниже). Если вы классифицируете данные на сотни классов, постепенно увеличивайте количество фильтров на последовательных слоях. Для набора цветочных данных с 5 классами фильтрации только с помощью 5 фильтров будет недостаточно. Вы можете использовать одно и то же количество фильтров в большинстве слоев, например 32, и уменьшить его ближе к концу.
- Конечный плотный слой(и) стоит дорого. Он/они могут иметь больший вес, чем все сверточные слои вместе взятые. Например, даже при очень разумном выходе из последнего куба данных размером 24x24x10 точек данных плотный слой из 100 нейронов будет стоить 24x24x10x100 = 576 000 весов !!! Постарайтесь быть вдумчивыми или попробуйте объединить глобальные средние значения (см. ниже).
Глобальный средний пул
Вместо использования дорогостоящего плотного слоя в конце сверточной нейронной сети вы можете разделить «куб» входящих данных на столько частей, сколько у вас есть классов, усреднить их значения и передать их через функцию активации softmax. Этот способ построения головы классификации стоит 0 весов. В Keras синтаксис — tf.keras.layers.GlobalAveragePooling2D().
Решение
Вот блокнот с решением. Вы можете использовать его, если застряли.
Keras_Flowers_TPU (solution).ipynb
Что мы рассмотрели
- 🤔 Поигрался со сверточными слоями
- 🤓 Экспериментировал с максимальным объединением, шагами, средним глобальным объединением,...
- 😀 быстро повторил реальную модель в ТПУ
Пожалуйста, найдите время и прокрутите этот контрольный список в уме.
7. Поздравляем!
Вы создали свою первую современную сверточную нейронную сеть и обучили ее с точностью 80%+, повторяя ее архитектуру за считанные минуты благодаря TPU. Пожалуйста, перейдите в следующую лабораторию, чтобы узнать о современных сверточных архитектурах:
- Конвейеры данных со скоростью TPU: tf.data.Dataset и TFRecords
- Ваша первая модель Keras с трансферным обучением
- [ЭТА ЛАБОРАТОРНАЯ ЛАБОРАТОРИЯ] Сверточные нейронные сети с Keras и TPU
- Современные сети, сжимающие сети, Xception, с Keras и TPU.
ТПУ на практике
TPU и графические процессоры доступны на платформе Cloud AI :
- На виртуальных машинах глубокого обучения
- В ноутбуках на платформе AI
- В тренировке на платформе искусственного интеллекта
Наконец, мы любим обратную связь. Пожалуйста, скажите нам, если вы видите что -то не так, как в этой лаборатории или вы думаете, что это должно быть улучшено. Обратная связь может быть предоставлена с помощью проблем GitHub [ ссылка на обратную связь ].
|