IBM Senior DevOps Engineer & Integration Architect   Глубокое обучение — это набор методов, которые особенно хорошо работают с задачами компьютерного зрения и обработки естественного языка. DL является частью более широкой области, называемой машинным обучением (ML).В данной практике мы хотим распознавать разные предметы одежды, обученные на наборе данных, содержащем 10 различных типов — по сути, проблема классификации изображений, а не данные, напоминающие что-то вроде набора данных Iris, который мы далее рассмотрим. Прежде чем мы перейдем к работе с изображениями, давайте сначала научимся использовать Keras и строить нейронные сети для решения простых задач. Мы начнем с решения задачи регрессии, а затем проблемы классификации. Сначала создайте новый файл, в котором будет находиться наш код:touch step1.py Открываем только что созданный файл step1.py. Начнем с импорта. Здесь мы будем импортировать: tensorflow и назовем его TF для простоты использования. numpy, который помогает нам легко и быстро представлять наши данные в виде массивов. Фреймворк keras для определения нейронной сети как набора последовательных слоев. TensorFlow — это бесплатная библиотека с открытым исходным кодом для потоков данных и дифференцированного программирования для целого ряда задач. Мы используем Keras, высокоуровневый API поверх TensorFlow. Хотя мы можем использовать TensorFlow для построения нейронных сетей, в большинстве случаев достаточно использовать Keras, не понимая, что происходит под капотом. Настроив нашу среду, мы попытаемся построить нейронную сеть, которая предсказывает цену дома по простой формуле. Вот как выглядит нейронная сеть: Представьте, что у нас есть очень простая модель ценообразования дома 50 000 + 50 000 за спальню, так что дом с 1 спальней стоит 100 000 долларов, дом с 2 спальнями стоит 150 000 долларов и так далее. Мы можем записать это, используя общую нотацию a + bx, где a равно 50k, b равно 50k, а x — количество спален. Теперь у нас могло бы быть гораздо больше функций, таких как квадратные метры, которые просто расширили бы наше общее обозначение до a + bx + cy, где c — постоянное значение, а y — квадратные метры. Но давайте придерживаться нашей простой модели ценообразования для простоты понимания. Эти неизвестные a и b называются весами модели. Наша цель — создать модель, которая изучает эту функцию ценообразования на основе доступных данных и прогнозирует цены на жилье на основе количества спален. По сути, нейронная сеть пытается найти значения с помощью итеративной процедуры. Как только он найдет эти значения, нам просто нужно указать значение x или количество спален, и он выведет цену. Давайте создадим некоторые фиктивные данные по формуле: Обратите внимание, что данные соответствуют нашей выдуманной формуле. Мы надеемся, что с помощью Keras мы сможем создать нейронную сеть, которая будет обучаться, просто предоставляя данные. Теперь мы создадим простейшую из возможных нейронную сеть только с 1 слоем (выходным слоем), и этот слой имеет один нейрон/узел, а входная форма для него — всего одно значение (один признак). Откройте тот же файл: step1.py. Sequential() определяет модель с ПОСЛЕДОВАТЕЛЬНОСТЬЮ (стеком) слоев в нейронной сети.Dense() добавляет слой нейронов/узлов.По умолчанию, поскольку мы не указываем функцию активации, выход будет линейной комбинацией входных данных — именно то, что мы хотим. Если мы посмотрим на изображение плотной сети из шага 1, модель в основном представляет собой один единственный нейрон/узел во входном слое (который соответствует количеству спален) и один единственный узел в выходном слое, который является ценой дома. На данный момент в нашей модели нет скрытых слоев. Теперь пришло время скомпилировать нашу нейронную сеть. Когда мы это делаем, мы должны указать 2 аргумента, потерю и оптимизатор. Проигрыш измеряет предполагаемые ответы по сравнению с известными правильными ответами и измеряет, насколько хорошо или плохо они справились.Оптимизатор угадывает вывод. Основываясь на выводе функции потерь, он попытается минимизировать потери. Мы собираемся использовать стохастический градиентный спуск sgd в качестве mean_squared_error в качестве нашей функции потерь для модели. mean_squared_error — очень распространенная метрика, используемая в задачах линейной регрессии с непрерывными целевыми переменными.model.compile(optimizer='sgd', loss='mean_squared_error') После компиляции идет примерка. Процесс обучения нейронной сети, где она изучает взаимосвязь между спальнями и ценами, находится в вызове model.fit. Он итеративно пытается выяснить лучшие “веса”.model.fit(bedrooms, prices, epochs=500) Давайте теперь попробуем предсказать цену дома с восемью спальнями и получить “веса” модели. Весь код выглядит так: Наконец, давайте запустим скрипт:python step1.py Обратите внимание на значения весов (ядро — это вес, связанный с количеством спален, а смещение — постоянная величина) и на то, что они очень близки к 50! Это был небольшой синтетический набор данных, в котором мы использовали наименьшую возможную нейронную сеть. На следующем шаге давайте воспользуемся реальным набором данных для решения задачи классификации. Здесь мы повторим то, что сделали, но с несколькими существенными изменениями: Большая нейронная сеть: теперь мы добавим один скрытый слой с несколькими узлами. Проблема классификации. На предыдущем шаге мы реализовали задачу регрессии, включающую непрерывное целевое значение. В задаче классификации целевые значения представляют собой дискретные конечные значения, такие как 0, 1 и 2, или значения в формате горячего кодирования, где 0, 1 и 2 могут быть представлены как [1, 0, 0], [0, 1, 0] и [0, 0, 1] соответственно. Реальный набор данных: мы будем работать со знаменитым набором данных Iris вместо создания собственного набора данных. Набор данных содержит три класса по 50 экземпляров в каждом, где каждый класс относится к типу ириса. На этот раз у каждого экземпляра также есть 4 характеристики: длина чашелистика, ширина чашелистика, длина лепестка и ширина лепестка. На предыдущем шаге мы использовали только одну функцию: количество спален. Разделение нашего набора данных на две части: набор тренировочных данных и набор тестовых данных. Мы зарезервируем 80% данных для обучения методу model.fit(), а 20% будем использовать для проверки точности модели. Причина, по которой мы это делаем, заключается в том, что мы хотим протестировать модель на данных, на которых она не обучалась (или не видела), чтобы избежать этой предвзятости на данных обучения. Создайте новый файл, в котором будет находиться наш код:Touch step3.py Открываем только что созданный файл step3.py. Начнем с импорта. Давайте загрузим набор данных и просмотрим первый экземпляр. Запустим:python step3.py Данные уже предварительно обработаны, поэтому нам не нужно ничего делать для их подготовки, и мы можем использовать их напрямую. Кроме того, нам на самом деле не нужно заботиться о том, какой столбец представляет какую функцию — мы позволим модели выяснить закономерности, поскольку нам важен только окончательный целевой прогноз. Давайте разделим наш набор данных на наборы данных для обучения и тестирования. Запустим: Вы можете заметить, что разделение 80-20 (20% для тестового набора) действительно имеет место! Когда наши данные готовы, давайте поработаем над нашей моделью.Пришло время построить и скомпилировать нашу модель. Как упоминалось ранее, теперь мы собираемся использовать один скрытый слой, состоящий из десяти узлов.Мы будем использовать функцию активации relu для скрытого слоя, популярный выбор в недавней литературе по машинному обучению.Мы будем использовать функцию активации softmax для вывода позже, потому что нам нужны значения вероятности для каждого класса.Мы будем использовать три выходных узла, каждый из которых будет иметь значение от 0 до 1, что в сумме даст 1 (из-за softmax). Каждый узел будет указывать вероятность определенного класса в целевых метках. Выполним кодPython step3.py Обратите внимание на количество параметров для каждого слоя. Это веса или неизвестные, которые модель пытается найти с помощью обратного распространения — алгоритма, который используется для вычисления градиентов нейронной сети для достижения точки минимизации функции стоимости (или функции потерь), такой как среднеквадратическая ошибка. (MSE), которую мы использовали на шаге 2, или функцию потерь, которую мы собираемся использовать в следующем блоке кода. Мы собираемся использовать оптимизатор RMSProp. Категориальная перекрестная энтропия — это функция потерь для задачи классификации. Он разреженный, потому что наши целевые значения находятся в {0,1,2}, а не в горячем кодировании. Мы добавляем точность в качестве метрики, которую необходимо отслеживать. Мы предоставляем тестовые данные в качестве аргумента validation_data. В результате мы сможем увидеть val_loss и val_accuracy (потери и точность тестового набора) после каждой эпохи. Давайте также добавим блок кода, чтобы отобразить значения точности и потерь по эпохам. Щелкните по accuracy_plot.png, чтобы визуализировать график точности. Нажмите loss_plot.png, чтобы визуализировать график потерь. Мы ясно видим улучшение точности и уменьшение потерь — именно то, что мы ожидали. Количество единиц Dense и функция активации в скрытом слое — это то, что можно изменить для получения лучших результатов. Мы также могли бы добавить больше скрытых слоев и изменить оптимизатор (или изменить скорость обучения оптимизатора). При обучении нейронной сети происходит много проб и ошибок.  Полный код:  В предыдущей практике минуту назад мы создали нейронную сеть и то, как изученное поведение решило проблему. Мы работали как с проблемой регрессии, так и с проблемой классификации, используя как синтетические данные, так и реальные данные. В каком-то смысле мы поняли, как выходные данные соотносятся с входными, но как насчет задачи, где написать такие правила гораздо сложнее, например, задачи компьютерного зрения? Вот наша следующая проблема, когда мы хотим распознавать разные предметы одежды, обученные на наборе данных, содержащем 10 различных типов — по сути, проблема классификации изображений, а не данных, напоминающих что-то вроде набора данных Iris. В задаче классификации изображений каждый вход соответствует изображению. Каждое изображение будет состоять из ряда функций, равного количеству пикселей, из которых оно состоит. Например, изображение RGB 32x32 будет иметь функции 32x32x3. Создайте новый файл:touch step1.pyОткрываем только что созданный файл step1.py. Начнем с импорта библиотек: Мы будем обучать нейронную сеть распознавать предметы одежды из общего набора данных под названием Fashion MNIST. Вы можете узнать больше об этом наборе данных здесь: https://www.kaggle.com/datasets/zalando-research/fashionmnist Он содержит 70 000 предметов одежды в 10 различных категориях. Каждый предмет одежды представлен в виде изображения в оттенках серого 28x28. Вы можете увидеть некоторые примеры здесь: https://github.com/zalandoresearch/fashion-mnistЭтот набор данных также доступен в API наборов данных Keras, давайте загрузим его:mnist = tf.keras.datasets.fashion_mnist Точно так же keras (и tensorflow) имеют множество встроенных наборов данных. Далее мы извлечем данные из mnist. Вызов метода load_data для объекта mnist даст вам два набора из двух списков, это будут обучающие и проверочные значения для графики, содержащей предметы одежды и их метки.(train_images, train_labels), (test_images, test_labels) = mnist.load_data() Все пиксели в основном имеют значения в диапазоне от 0 до 255. Если мы обучаем нейронную сеть, по разным причинам будет проще, если мы будем рассматривать все значения как от 0 до 1. Следовательно, нам придется нормализовать изображения, разделив каждое из обучающих и тестовых изображений по 255: Давайте запустим скрипт, чтобы просмотреть некоторые значения пикселей:python step1.py Обратите внимание, что значения пикселей изменились с диапазона 0–255 до 0–1. Это простое масштабирование функций — не единственный способ нормализации, но этот простой способ деления на 255 очень распространен для пикселей изображения. Нормализация — ключевой шаг в любой проблеме машинного обучения. Мы хотели бы, чтобы все значения находились в одном и том же небольшом диапазоне, чтобы оптимизатор работал более эффективно. Когда наши наборы данных для обучения и тестирования нормализованы, мы готовы разработать нашу модель. Откройте тот же файл .py: step1.py Для этой модели мы будем использовать несколько слоев. Давайте также выведем саммари модели. Запустим скрипт Модель изучает более 200 тысяч параметров! Вы можете попробовать изменить количество единиц в скрытом слое (первый плотный слой), чтобы увидеть, как изменится количество параметров. Чем сложнее модель, тем больше времени требуется для ее обучения. Давайте разберемся с каждым из этих ключевых слов здесь: Sequential: это определяет модель с ПОСЛЕДОВАТЕЛЬНОСТЬЮ (стеком) слоев в нейронной сети, где каждый слой имеет один входной тензор и один выходной тензор. Flatten: этот слой просто берет квадрат и превращает его в одномерный набор. Например, если сглаживание применяется к слою с входной формой (batch_size, 2,2), то выходная форма слоя будет (batch_size, 4). Dense: добавляет слой нейронов. Каждому слою нейронов нужна функция активации, которая сообщает им, что делать. Вариантов много, но мы пока воспользуемся ими. Relu фактически означает «Если X>0 вернуть X, иначе вернуть 0», поэтому он позволяет нам передавать значения 0 или выше на следующий уровень в сети. Softmax дает нам вероятность для каждого класса, в который должен быть классифицирован экземпляр, и в сумме они составляют 1. Например, если выходные данные последнего слоя равны [0,0, -1,0, 2,0, 3,0], softmax преобразует их в [ 0,03467109 0,01275478 0,25618663 0,69638747]. Теперь, когда модель определена, нужно ее построить. Мы делаем это, компилируя его с оптимизатором и функцией потерь. Мы используем один из самых популярных оптимизаторов, оптимизатор Adam. Поскольку это проблема классификации с метками не в формате горячего кодирования, мы используем sparse разреженную категориальную потерю энтропии.Обучим модель, вызвав метод fit(). Давайте построим значения точности и потерь. Чтобы оценить модель, мы должны знать, как она работает с данными типа unseen. Вот почему у нас есть тестовые изображения. Мы будем использовать model.evaluate() и передавать ей тестовые изображения и метки:model.evaluate(test_images, test_labels) Выполним код, чтобы просмотреть выходные данные и графики.Python step1.py После завершения обучения вы должны увидеть значение точности в конце последней эпохи. Вы можете ожидать чего-то подобного (точное значение будет отличаться для разных прогонов). Причина, по которой он различается для разных прогонов, заключается в том, что веса плотных слоев инициализируются случайным образом. Один из способов инициализировать его все время одними и теми же значениями (если вам интересно) — использовать начальный аргумент для любого значения int при использовании аргумента инициализатора в слое. Например, tf.keras.layers.Dense(256, активация=tf.nn.relu, kernel_initializer=tf.keras.initializers.GlorotUniform(seed=5)). GlorotUniform — это инициализатор ядра по умолчанию для плотного слоя. Нам не нужно указывать начальное значение для offset_initializer, потому что по умолчанию он устанавливает все значения смещения равными нулю. Вы должны попытаться увидеть, можете ли вы улучшить производительность, изменив количество эпох или любые другие гиперпараметры, такие как оптимизатор, скорость обучения оптимизатора и т. д. Щелкните по accuracy_plot.png, чтобы визуализировать график точности. Как и ожидалось, точность тренировки и теста увеличивается.Нажмите loss_plot.png, чтобы визуализировать график потерь. Как и ожидалось, потери как в тренировке, так и в тесте уменьшаются.И, как и ожидалось, он, вероятно, не будет так хорошо работать с невидимыми данными, как с данными, на которых он обучался!Полный код: В заключение приглашаю всех на бесплатный урок курса "Компьютерное зрение", где вы узнаете в чем заключается задача Face Recognition и из каких подзадач она состоит: детекция и выравнивание лиц, распознавание и матчинг лиц. Какие существуют основные подходы по решению задачи детекции лиц (нейросетевые подходы и алгоритмы классического компьютерного зрения). С помощью каких алгоритмов решается задача распознавания лиц (EigenFaces, нейросетевые методы). Как на практике решить задачу распознавания лиц с помощью метода EigenFaces, а также какие существуют датасеты, библиотеки и инструменты, необходимые для решения задачи распознавания лиц. Зарегистрироваться на бесплатный урок  Редактор