1. Обзор
В этой лабораторной работе вы научитесь собирать сверточный слой в модель нейронной сети, способную распознавать цветы. На этот раз вы создадите модель самостоятельно с нуля и, используя возможности TPU, обучите ее за считанные секунды и будете постоянно совершенствовать ее конструкцию.
Данная лабораторная работа включает необходимые теоретические объяснения сверточных нейронных сетей и является хорошей отправной точкой для разработчиков, изучающих глубокое обучение.
Эта лабораторная работа является третьей частью серии "Keras на TPU". Вы можете выполнять их в указанном порядке или по отдельности.
- Конвейеры обработки данных со скоростью TPU: tf.data.Dataset и TFRecords
- Ваша первая модель Keras с использованием трансферного обучения.
- [ЭТА ЛАБОРАТОРИЯ] Сверточные нейронные сети с использованием Keras и TPU.
- Современные сверточные сети, SqueezeNet, Xception, Keras и TPU.

Что вы узнаете
- Для создания сверточного классификатора изображений с использованием модели Keras Sequential.
- Для обучения вашей модели Keras на TPU
- Для тонкой настройки вашей модели необходимо правильно подобрать сверточные слои.
Обратная связь
Если вы заметите какие-либо ошибки в этом примере кода, пожалуйста, сообщите нам. Обратная связь может быть предоставлена через систему отслеживания проблем GitHub [ ссылка для обратной связи ].
2. Быстрый старт в Google Colaboratory
В этой лабораторной работе используется Google Collaboratory, и вам не потребуется ничего настраивать. Collaboratory — это онлайн-платформа для создания блокнотов в образовательных целях. Она предлагает бесплатное обучение работе с процессорами CPU, GPU и TPU.

Вы можете открыть этот пример блокнота и просмотреть несколько ячеек, чтобы ознакомиться с Colaboratory.
Выберите бэкэнд TPU.

В меню Colab выберите Runtime > Change runtime type , а затем выберите TPU. В этой лабораторной работе вы будете использовать мощный TPU (Tensor Processing Unit), поддерживающий аппаратное ускорение обучения. Подключение к среде выполнения произойдет автоматически при первом запуске, или вы можете использовать кнопку «Подключиться» в правом верхнем углу.
Выполнение блокнота

Выполняйте ячейки по одной, щелкнув по ячейке и нажав Shift-ENTER. Вы также можете запустить весь блокнот, выбрав Runtime > Run all.
Оглавление

Во всех блокнотах есть оглавление. Открыть его можно с помощью черной стрелки слева.
Скрытые клетки

В некоторых ячейках отображается только заголовок. Это особенность блокнотов Colab. Вы можете дважды щелкнуть по ним, чтобы увидеть код внутри, но обычно он не очень интересен. Как правило, это вспомогательные или визуализационные функции. Вам все равно нужно запустить эти ячейки, чтобы функции внутри них были определены.
Аутентификация

Colab может получить доступ к вашим частным хранилищам Google Cloud Storage при условии аутентификации с помощью авторизованной учетной записи. Приведенный выше фрагмент кода запустит процесс аутентификации.
3. [ИНФО] Что такое тензорные процессоры (TPU)?
В двух словах

Код для обучения модели на TPU в Keras (с возможностью переключения на GPU или CPU, если 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 ).
Аппаратное обеспечение
MXU и VPU
Ядро 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]
На графическом процессоре (GPU) скалярное произведение запрограммировано в «ядро» GPU, а затем выполняется параллельно на максимально возможном количестве «ядер», чтобы попытаться вычислить каждое значение результирующей матрицы одновременно. Если результирующая матрица имеет размер 128x128, потребуется 128x128=16K «ядер», что обычно невозможно. Самые большие графические процессоры имеют около 4000 ядер. TPU, с другой стороны, использует минимальное количество аппаратных средств для вычислительных блоков в MXU: только умножители-аккумуляторы bfloat16 x bfloat16 => float32 , ничего больше. Они настолько малы, что TPU может реализовать 16K таких умножителей в MXU размером 128x128 и обработать это матричное умножение за один раз.

Иллюстрация: систолический массив MXU. Вычислительные элементы представляют собой умножители-аккумуляторы. Значения одной матрицы загружаются в массив (красные точки). Значения другой матрицы проходят через массив (серые точки). Вертикальные линии передают значения вверх. Горизонтальные линии передают частичные суммы. Пользователю предлагается проверить, что по мере прохождения данных через массив результат умножения матриц выходит с правой стороны.
Кроме того, пока в MXU вычисляются скалярные произведения, промежуточные суммы просто передаются между соседними вычислительными блоками. Их не нужно хранить и извлекать из памяти или даже из регистрового файла. В результате архитектура систолической матрицы TPU обладает значительным преимуществом в плотности и энергопотреблении, а также существенным преимуществом в скорости по сравнению с GPU при вычислении матричных умножений.
Облачный TPU
Когда вы запрашиваете « Cloud TPU v2» на платформе Google Cloud Platform, вы получаете виртуальную машину (ВМ) с платой TPU, подключенной через PCI. Плата TPU имеет четыре двухъядерных чипа TPU. Каждое ядро TPU включает в себя VPU (Vector Processing Unit) и 128x128 MXU (MatriX multiply Unit). Затем этот «Cloud TPU» обычно подключается по сети к виртуальной машине, которая его запросила. Таким образом, полная картина выглядит следующим образом:

Иллюстрация: ваша виртуальная машина с сетевым ускорителем "Cloud TPU". Сам "Cloud TPU" представляет собой виртуальную машину с платой TPU, подключенной через PCI, на которой размещены четыре двухъядерных чипа TPU.
TPU-капсулы
В центрах обработки данных Google процессоры TPU подключены к высокопроизводительному вычислительному соединению (HPC), благодаря чему они могут выглядеть как один очень большой ускоритель. Google называет их «подами», и они могут включать до 512 ядер TPU v2 или 2048 ядер TPU v3.

Иллюстрация: модуль TPU v3. Платы и стойки TPU соединены через высокопроизводительный межсоединительный интерфейс.
В процессе обучения градиенты обмениваются между ядрами TPU с использованием алгоритма all-reduce ( подробное объяснение all-reduce здесь ). Обучаемая модель может использовать преимущества аппаратного обеспечения, обучаясь на больших пакетах данных.

Иллюстрация: синхронизация градиентов во время обучения с использованием алгоритма all-reduce на высокопроизводительной вычислительной сети Google TPU с 2D-тороидальной сеткой.
Программное обеспечение
Обучение в больших группах
Идеальный размер пакета данных для TPU составляет 128 элементов данных на ядро TPU, но оборудование может демонстрировать хорошую загрузку уже при 8 элементах данных на ядро TPU. Следует помнить, что один облачный TPU имеет 8 ядер.
В этой практической работе мы будем использовать API Keras. В Keras указанный вами размер пакета данных является глобальным размером пакета для всего TPU. Ваши пакеты будут автоматически разделены на 8 частей и запущены на 8 ядрах TPU.

Дополнительные советы по повышению производительности см. в Руководстве по производительности TPU . При очень больших объемах партий в некоторых моделях может потребоваться особый подход; подробности см. в LARSOptimizer .
Под капотом: XLA
Программы TensorFlow определяют вычислительные графы. TPU не выполняет код Python напрямую, он выполняет вычислительный граф, определенный вашей программой TensorFlow. Под капотом компилятор XLA (ускоренный компилятор линейной алгебры) преобразует граф вычислительных узлов TensorFlow в машинный код TPU. Этот компилятор также выполняет множество сложных оптимизаций вашего кода и структуры памяти. Компиляция происходит автоматически по мере отправки задач на TPU. Вам не нужно явно включать XLA в цепочку сборки.

Иллюстрация: для работы на TPU вычислительный граф, определенный вашей программой Tensorflow, сначала преобразуется в представление XLA (ускоренный компилятор линейной алгебры), а затем компилируется XLA в машинный код TPU.
Использование TPU в Keras
Начиная с TensorFlow 2.1, поддержка TPU осуществляется через API Keras. Keras работает как с TPU, так и с TPU-подами. Вот пример, работающий на TPU, GPU(ах) и CPU:
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 Cloud (задания AI Platform, Colaboratory, Kubeflow, виртуальные машины глубокого обучения, созданные с помощью утилиты 'ctpu up'). Эти системы знают, где находится их TPU, благодаря переменной среды TPU_NAME. Если вы создаете TPU вручную, либо установите переменную среды TPU_NAME на виртуальной машине, с которой вы его используете, либо вызовитеTPUClusterResolverс явными параметрами:TPUClusterResolver(tp_uname, zone, project) -
TPUStrategy— это часть, реализующая распределение и алгоритм синхронизации градиентов "all-reduce". - Стратегия применяется через область видимости. Модель должна быть определена внутри области видимости стратегии (scope()).
- Функция
tpu_model.fitожидает в качестве входных данных для обучения на TPU объект tf.data.Dataset.
Типичные задачи портирования TPU
- Хотя существует множество способов загрузки данных в модель TensorFlow, для TPU требуется использование API
tf.data.Dataset. - TPU работают очень быстро, и при их использовании узким местом часто становится процесс приема данных. В руководстве по производительности TPU есть инструменты для выявления узких мест в передаче данных и другие советы по повышению производительности.
- Числа типа int8 или int16 обрабатываются как int32. В TPU отсутствует аппаратное обеспечение для работы с целочисленными значениями менее 32 бит.
- Некоторые операции TensorFlow не поддерживаются. Список можно найти здесь . Хорошая новость в том, что это ограничение распространяется только на код обучения, то есть на прямой и обратный проходы через вашу модель. Вы по-прежнему можете использовать все операции TensorFlow в своем конвейере ввода данных, поскольку они будут выполняться на ЦП.
-
tf.py_funcне поддерживается на TPU.
4. [ИНФО] Нейронная сеть-классификатор 101
В двух словах
Если все выделенные жирным шрифтом термины в следующем абзаце вам уже знакомы, можете перейти к следующему упражнению. Если же вы только начинаете изучать глубокое обучение, добро пожаловать, и читайте дальше.
Для моделей, построенных в виде последовательности слоев, Keras предлагает API Sequential. Например, классификатор изображений, использующий три полносвязных слоя, можно записать в 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 (Rectified Linear Unit — выпрямленный линейный блок). Это очень простая функция, как видно на графике выше.
Активация Softmax
Представленная выше нейронная сеть заканчивается слоем из 5 нейронов, поскольку мы классифицируем цветы по 5 категориям (роза, тюльпан, одуванчик, маргаритка, подсолнух). Нейроны в промежуточных слоях активируются с помощью классической функции активации RELU. Однако в последнем слое мы хотим вычислить числа от 0 до 1, представляющие вероятность того, что этот цветок является розой, тюльпаном и так далее. Для этого мы будем использовать функцию активации под названием "softmax".
Применение функции softmax к вектору осуществляется путем экспоненциального вычисления каждого элемента и последующей нормализации вектора, обычно с использованием L1-нормы (суммы абсолютных значений), так что сумма значений равна 1 и может быть интерпретирована как вероятность.


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

Градиентный спуск
«Обучение» нейронной сети на самом деле означает использование обучающих изображений и меток для корректировки весов и смещений с целью минимизации функции потерь кросс-энтропии. Вот как это работает.
Кросс-энтропия является функцией весов, смещений, пикселей обучающего изображения и его известного класса.
Если мы вычислим частные производные кросс-энтропии относительно всех весов и всех смещений, мы получим «градиент», вычисленный для заданного изображения, метки и текущего значения весов и смещений. Следует помнить, что у нас могут быть миллионы весов и смещений, поэтому вычисление градиента кажется очень трудоемким процессом. К счастью, TensorFlow делает это за нас. Математическое свойство градиента заключается в том, что он направлен «вверх». Поскольку мы хотим двигаться туда, где кросс-энтропия низка, мы движемся в противоположном направлении. Мы обновляем веса и смещения на долю градиента. Затем мы повторяем то же самое снова и снова, используя следующие пакеты обучающих изображений и меток, в цикле обучения. Надеемся, что это сойдется к точке, где кросс-энтропия минимальна, хотя ничто не гарантирует, что этот минимум является единственным.

Мини-пакетирование и импульс
Вы можете вычислить градиент на одном примере изображения и немедленно обновить веса и смещения, но если сделать это на пакете, например, из 128 изображений, градиент будет лучше отражать ограничения, накладываемые различными примерами изображений, и, следовательно, с большей вероятностью быстрее сойдется к решению. Размер мини-пакета является регулируемым параметром.
Этот метод, иногда называемый «стохастическим градиентным спуском», имеет еще одно, более прагматичное преимущество: работа с пакетами данных также означает работу с большими матрицами, которые обычно проще оптимизировать на графических и тензорных процессорах.
Однако сходимость может быть несколько хаотичной и даже остановиться, если вектор градиента состоит из одних нулей. Означает ли это, что мы нашли минимум? Не всегда. Компонент градиента может быть равен нулю как в точке минимума, так и в точке максимума. В векторе градиента, содержащем миллионы элементов, если все они равны нулю, вероятность того, что каждый ноль соответствует минимуму, а ни один из них — максимуму, довольно мала. В многомерном пространстве седловые точки встречаются довольно часто, и мы не хотим останавливаться на них.

Иллюстрация: седловая точка. Градиент равен 0, но точка не является минимумом во всех направлениях. (Источник изображения: Wikimedia: Nicoguaro - собственная работа, CC BY 3.0 )
Решение состоит в том, чтобы добавить алгоритму оптимизации некоторый импульс, чтобы он мог проходить седловые точки, не останавливаясь.
Глоссарий
Пакетная обработка или мини-пакетная обработка : обучение всегда выполняется на пакетах обучающих данных и меток. Это помогает алгоритму сойтись. Размерность «пакета» обычно представляет собой первую размерность тензоров данных. Например, тензор формы [100, 192, 192, 3] содержит 100 изображений размером 192x192 пикселя с тремя значениями на пиксель (RGB).
Функция потерь кросс-энтропии : специальная функция потерь, часто используемая в классификаторах.
Плотный слой : слой нейронов, в котором каждый нейрон соединен со всеми нейронами предыдущего слоя.
Признаки : входные данные нейронной сети иногда называют «признаками». Искусство определения того, какие части набора данных (или комбинации частей) следует подавать в нейронную сеть для получения хороших прогнозов, называется «инженерией признаков».
метки : другое название для «классов» или правильных ответов в задаче классификации с учителем.
Скорость обучения : доля градиента, на которую обновляются веса и смещения на каждой итерации цикла обучения.
Логиты : выходные сигналы слоя нейронов до применения функции активации называются «логитами». Термин происходит от «логистической функции», также известной как «сигмоидная функция», которая раньше была наиболее популярной функцией активации. Выражение «выходные сигналы нейронов до применения логистической функции» было сокращено до «логиты».
Функция потерь : функция ошибки, сравнивающая выходные данные нейронной сети с правильными ответами.
Нейрон : вычисляет взвешенную сумму своих входных сигналов, добавляет смещение и пропускает результат через функцию активации.
one-hot кодирование : класс 3 из 5 кодируется как вектор из 5 элементов, все из которых равны нулю, кроме третьего, который равен 1.
relu : выпрямленная линейная единица. Популярная функция активации для нейронов.
Сигмоидная функция : еще одна функция активации, которая когда-то была популярна и до сих пор полезна в особых случаях.
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'])

Сверточные нейронные сети: основы
В слое сверточной сети один «нейрон» выполняет взвешенное суммирование пикселей, расположенных непосредственно над ним, только в небольшом участке изображения. Он добавляет смещение и пропускает сумму через функцию активации, как это делал бы нейрон в обычном плотном слое. Затем эта операция повторяется по всему изображению с использованием тех же весов. Напомним, что в плотных слоях каждый нейрон имел свои собственные веса. Здесь же один «участок» весов скользит по изображению в обоих направлениях («свертка»). Выходные данные содержат столько значений, сколько пикселей в изображении (хотя по краям необходимо некоторое заполнение). Это операция фильтрации с использованием фильтра из 4x4x3=48 весов.
Однако 48 весов будет недостаточно. Чтобы добавить больше степеней свободы, мы повторяем ту же операцию с новым набором весов. Это дает новый набор выходных сигналов фильтра. Назовем его «каналом» выходных сигналов по аналогии с каналами R, G, B во входном изображении.

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

Иллюстрация: сверточная нейронная сеть преобразует «кубы» данных в другие «кубы» данных.
Свертки с шагом, максимальное пулинг
Выполняя свертки с шагом 2 или 3, мы также можем уменьшить размер результирующего куба данных по горизонтали. Для этого существует два распространенных способа:
- Свертка с шагом: скользящий фильтр, как описано выше, но с шагом >1.
- Максимальное объединение (Max Pooling): скользящее окно, применяющее операцию 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 слоев.
- Используйте небольшие фильтры. Как правило, фильтры размером 3x3 см подходят для всех условий.
- Фильтры 1x1 тоже можно использовать, и они недорогие. На самом деле они ничего не «фильтруют», а вычисляют линейные комбинации каналов. Чередуйте их с настоящими фильтрами. (Подробнее о «свертках 1x1» в следующем разделе.)
- Для подобных задач классификации следует часто уменьшать разрешение с помощью слоев максимального пулинга (или сверток с шагом >1). Местоположение цветка не имеет значения, важно лишь, роза это или одуванчик, поэтому потеря информации о координатах x и y не важна, а фильтрация меньших областей обходится дешевле.
- Количество фильтров обычно становится примерно таким же, как и количество классов в конце сети (почему? см. трюк с "глобальным усредняющим пулингом" ниже). Если вы классифицируете данные по сотням классов, постепенно увеличивайте количество фильтров в последовательных слоях. Для набора данных о цветах с 5 классами фильтрации всего с 5 фильтрами будет недостаточно. Вы можете использовать одинаковое количество фильтров в большинстве слоев, например, 32, и уменьшать его к концу.
- Последний полносвязный слой (или слои) является/являются дорогостоящими. Он/они могут содержать больше весов, чем все сверточные слои вместе взятые. Например, даже при вполне приемлемом результате обработки последнего куба данных размером 24x24x10¹⁰ точек, полносвязный слой со 100 нейронами будет стоить 24x24x10x10⁰ = 576 000 весов!!! Постарайтесь обдумать это или попробуйте глобальное усредняющее пулинг (см. ниже).
Глобальное усреднение
Вместо использования дорогостоящего полносвязного слоя в конце сверточной нейронной сети, можно разделить входящий «куб» данных на столько частей, сколько классов, усреднить их значения и пропустить их через функцию активации softmax. Такой способ построения классификационного слоя не требует весов. В Keras синтаксис выглядит так: tf.keras.layers.GlobalAveragePooling2D().

Решение
Вот блокнот с решениями. Вы можете использовать его, если у вас возникнут трудности.
Keras_Flowers_TPU (solution).ipynb
Что мы рассмотрели
- 🤔 Экспериментировали с сверточными слоями
- 🤓 Экспериментировал с максимальным пулингом, шагом, глобальным усредняющим пулингом и т.д.
- 😀 Быстро итеративно протестировано на реальной модели с использованием TPU.
Пожалуйста, уделите немного времени, чтобы мысленно пройтись по этому контрольному списку.
7. Поздравляем!
Вы создали свою первую современную сверточную нейронную сеть и обучили ее до точности более 80%, улучшив архитектуру всего за несколько минут благодаря TPU. Пожалуйста, перейдите к следующей лабораторной работе, чтобы узнать о современных сверточных архитектурах:
- Конвейеры обработки данных со скоростью TPU: tf.data.Dataset и TFRecords
- Your first Keras model, with transfer learning
- [THIS LAB] Convolutional neural networks, with Keras and TPUs
- Modern convnets, squeezenet, Xception, with Keras and TPUs
TPUs in practice
TPUs and GPUs are available on Cloud AI Platform :
- On Deep Learning VMs
- In AI Platform Notebooks
- In AI Platform Training jobs
Finally, we love feedback. Please tell us if you see something amiss in this lab or if you think it should be improved. Feedback can be provided through GitHub issues [ feedback link ].

|

