Глубокое обучения с fast.ai
Как обучить и внедрить модель глубокого обучения с fast.ai
Глубокое обучение вносит революционные изменения во многие дисциплины. Он также становится более доступным для экспертов в предметной области и энтузиастов ИИ с появлением таких библиотек, как TensorFlow, PyTorch и now fast.ai .
fast.ai миссия компании - демократизировать глубокое обучение. Это исследовательский институт, призванный помочь каждому – от программиста начального уровня до опытного специалиста по глубокому обучению – достичь результатов мирового уровня с помощью самых современных моделей и методов, основанных на новейших исследованиях в этой области.
Это сообщение в блоге проведет вас через процесс разработки классификатора собак с использованием fast.ai . Цель состоит в том, чтобы узнать, насколько легко начать работу с моделями глубокого обучения и быть способным достигать почти идеальных результатов с ограниченным объемом данных, используя предварительно обученные модели.
Обязательное условие
Единственное условие для начала работы - это то, что вы знаете, как программировать на Python, и что вы знакомы со школьной математикой.
Чему ты научишься
Импорт библиотек и настройка ноутбука
Сбор данных изображений с помощью Microsoft Azure
Преобразование загруженных данных в объекты DataLoader
Увеличение объема данных
Очистка данных с помощью обучения модели
Экспорт обученной модели
Создание приложения из вашего ноутбука Jupyter
Итак, давайте начнем.
Как импортировать библиотеки и настроить ноутбук
Прежде чем мы приступим к построению нашей модели, нам нужно импортировать необходимые библиотеки и служебные функции из набора ноутбуков под названием fastbook. Он был разработан, чтобы охватить введение в глубокое обучение с использованием fast.ai и ПаЙторч.
Давайте установим пакет fastbook для настройки ноутбука:
!pip install -Uqq fastbook
import fastbook
fastbook.setup_book()
Затем давайте импортируем все функции и классы из пакета fastbook и fast.ai API виджетов vision:
from fastbook import *
from fastai.vision.widgets import *
Как собирать данные изображений с помощью Microsoft Azure
Для большинства типов проектов вы можете найти данные в Интернете в различных хранилищах данных и на веб-сайтах. Чтобы разработать классификатор собак, нам нужны изображения собак. В Интернете есть много изображений собак.
Чтобы загрузить эти изображения, мы будем использовать API поиска изображений Bing, предоставляемый Microsoft Azure. Итак, зарегистрируйте бесплатную учетную запись в Microsoft Azure, и вы получите кредитов на сумму 200 долларов.
Перейдите на свой портал и создайте новый ресурс когнитивного сервиса с помощью этого быстрого запуска. Включите API поиска изображений Bing. Затем из Keys and Endpointопции на левой панели скопируйте ключи на свой ресурс.
С извлеченными ключами установите эти ключи для среды следующим образом:
key = os.environ.get('AZURE_SEARCH_KEY', '')
Теперь fastbook поставляется с такими полезными функциями, search_images_bingкоторые возвращают URL-адреса, соответствующие вашему поисковому запросу. Вы можете узнать о таких функциях с помощью справочной функции:
help(fastbook)
Вы можете проверить search_image_bingфункцию в этом справочном руководстве. Функция принимает ключ к вашему ресурсу, который вы определили выше, и поисковый запрос, и мы можем получить доступ к URL-адресам результатов поиска, используя attrgotметод:
results = search_images_bing(key, 'german shepherd dogs')
images = results.attrgot('content_url')
len(images)
У нас есть 150 URL-адресов изображений немецких овчарок:
Теперь мы можем загрузить эти изображения с помощью download_urlфункции. Но давайте сначала определим тип собак, которых мы хотим.
В этом уроке я буду работать с тремя типами собак: немецкими овчарками, черными собаками и лабрадорами.
Итак, давайте определим список типов собак:
dog_types = ['german shepherd', 'black', 'labrador']
path = Path('dogs')
Затем вам нужно будет определить путь, по которому будут загружаться ваши изображения, а также семантические имена папок для каждого класса dog.
if not path.exists():
path.mkdir()
for t in dog_types:
dest = (path/t)
print(dest)
dest.mkdir(exist_ok=True)
results = search_images_bing(key, '{} dog'.format(t))
download_images(dest, urls=results.attrgot('content_url'))
Это создаст каталог “собаки”, который дополнительно содержит 3 каталога для каждого типа изображения собаки.
После этого мы передаем поисковый запрос (который является dog_type ) и ключ к функции поиска, за которой следует функция загрузки, чтобы загрузить все URL-адреса из результатов поиска в соответствующие каталоги назначения (dest).
Мы можем проверить изображения, загруженные в путь, используя get_image_fileфункцию:
files = get_image_files(path)
files
Как проверить изображения
Вы также можете проверить количество поврежденных файлов / изображений в файлах:
corrupt = verify_images(files)
corrupt
##output: (#0) []
Вы можете удалить все поврежденные файлы (если таковые имеются), сопоставив метод unlink со списком поврежденных файлов: corrupt.map(Path.unlink);
Вот и все, у нас есть 379 готовых изображений собак для обучения и проверки нашей модели. Как преобразовать загруженные данные в объекты DataLoader
Теперь нам нужен механизм для предоставления данных в нашу модель. fast.ai имеет такую концепцию загрузчиков данных, которая хранит несколько объектов DataLoader, переданных ему, и делает их доступными как a trainingи validationset.
Теперь, чтобы преобразовать загруженные данные в объект DataLoader, мы должны предоставить четыре вещи:
С какими данными мы работаем
Как получить список элементов
Как маркировать эти предметы
Как создать набор проверки
Теперь, чтобы создать эти объекты DataLoaders вместе с информацией, упомянутой выше, fast.ai предлагает гибкую систему, называемую API блоков данных. Мы можем указать все детали создания загрузчика данных, используя аргументы и массив методов преобразования, которые предлагает API:
dogs = DataBlock(
blocks=(ImageBlock, CategoryBlock),
get_items=get_image_files,
splitter=RandomSplitter(valid_pct=0.2, seed=41),
get_y=parent_label,
item_tfms=Resize(128)
)
Здесь у нас есть куча аргументов, которые мы должны понять:
блоки — задает переменные объектов (изображения) и целевую переменную (категорию для каждого изображения).
get_items — извлекает базовые элементы (которые в нашем случае являются изображениями), и у нас есть get_image_filesфункция, которая возвращает список всех изображений в этом пути.
разделитель — разделяет данные в соответствии с предоставленным методом. Мы используем случайное разделение с 20% данных, зарезервированных для набора проверки, и указываем начальное значение, чтобы получить одинаковое разделение при каждом запуске.
get_y — целевая переменная называется y. Для создания меток мы используем parent_labelфункцию, которая получает имя папки, в которой находится файл, в качестве метки.
item_tfms — у нас есть изображения разных размеров, и это вызывает проблему, потому что мы всегда отправляем в модель пакет файлов вместо одного файла. Поэтому нам нужно предварительно обработать эти изображения, изменив их размер до стандартного, а затем сгруппировать их в тензор для прохождения через модель. Здесь мы используем Resizeпреобразование.
Теперь у нас есть объект DataBlock, который необходимо преобразовать в средство загрузки данных, указав путь к набору данных:
dls = dogs.dataloaders(path)
Затем мы можем проверить наличие изображений в объекте dataloader, используя show_batchметод:
dls.valid.show_batch()
Увеличение объема данных
Мы можем добавлять преобразования к этим изображениям, чтобы создавать случайные вариации входных изображений, чтобы они выглядели по-разному, но все же отображали одни и те же факты.
Мы можем поворачивать, деформировать, переворачивать или изменять яркость / контрастность изображений для создания этих вариаций. У нас также есть стандартный набор дополнений, инкапсулированных в aug_transformsфункцию, которая довольно хорошо работает для большинства наборов данных компьютерного зрения.
Теперь мы можем применить эти преобразования ко всему пакету изображений, поскольку все изображения имеют одинаковый размер (224 пикселя, стандартный для задач классификации изображений), используя следующее:
##adding item transformations
dogs = dogs.new(
item_tfms=RandomResizedCrop(224, min_scale=0.5),
batch_tfms=aug_transforms(mult=2)
)
dls = dogs.dataloaders(path)
dls.train.show_batch(max_n=8, nrows=2, unique=True)
Обучение модели и очистка данных
Пришло время обучить модель с этим ограниченным количеством изображений. fast.ai предлагает множество архитектур для использования, что делает его очень простым в использовании transfer learning.
Мы можем создать модель сверточной нейронной сети (CNN), используя предварительно обученные модели, которые работают для большинства приложений / наборов данных.
Мы собираемся использовать архитектуру ResNet, поскольку она быстра и точна для многих наборов данных и задач. 18 в resnet18представляет количество слоев в нейронной сети.
Мы также передаем метрику для измерения качества прогнозов модели, используя набор проверки из загрузчика данных. Мы используем error_rate, который сообщает нам, как часто модель делает неправильные прогнозы:
model = cnn_learner(dls, resnet18, metrics=error_rate)
model.fine_tune(4)
fine_tuneМетод аналогичен fit()методу в других библиотеках ML. Теперь, чтобы обучить модель, нам нужно указать, сколько раз (эпох) мы хотим обучить модель на каждом изображении.
Здесь мы тренируемся только для 4 эпох:
Мы также можем визуализировать прогнозы и сравнивать их с фактическими метками, используя матрицу путаницы:
interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix()
Как вы можете видеть, у нас есть только пять неверных прогнозов. Давайте проверим максимальные потери, то есть изображения с наибольшими потерями в наборе данных: interp.plot_top_losses (6, nrows = 3):
Вы можете видеть, что модель перепутала черного и лабрадора. Таким образом, мы можем указать, что эти изображения относятся к определенной категории, используя класс ImageClassifierCleaner .
Передайте модель классу, и он откроет виджет с интуитивно понятным графическим интерфейсом для очистки данных. Мы можем изменять метки образов обучающего и проверочного наборов и просматривать изображения с наибольшими потерями.
После добавления каждого изображения в соответствующий правильный класс, мы должны переместить их в нужный каталог, используя:
for idx,cat in cleaner.change():
shutil.move(str(cleaner.fns[idx]), str(path/cat).split('.')[0] +"_fixed.jpg")
Как экспортировать обученную модель
После нескольких раундов настройки гиперпараметров, когда вы будете довольны своей моделью, вам нужно сохранить ее, чтобы можно было развернуть на сервере для использования в рабочей среде.
При сохранении модели у нас есть архитектура модели и обученные параметры, которые представляют ценность для нас. fast.ai предлагает export()метод сохранения модели в файле pickle с расширением .pkl.
model.export()
path = Path()
path.ls(file_exts='.pkl')
Затем мы можем загрузить модель и сделать выводы, передав изображение загруженной модели:
model_inf = load_learner(path/'export.pkl')
Используйте эту загруженную модель, чтобы делать выводы:
model_inf.predict('dogs/labrador/00000000.jpg')
Мы можем проверить метки из словаря models dataloader:
model_inf.dls.vocab
Как создать приложение из вашего ноутбука Jupyter
Следующий шаг - создать приложение, которым мы сможем поделиться с нашими друзьями, коллегами, рекрутерами и другими.
Чтобы создать приложение, нам нужно добавить интерактивные элементы, чтобы мы могли попробовать и протестировать функции приложения. Нам также нужно сделать его доступным в Интернете в виде веб-страницы, что включает в себя его развертывание с помощью какой-либо платформы, такой как Flask, или просто с помощью Voila.
Вы можете использовать Voila для преобразования этого Jupyter Notebook в отдельное приложение. Я не описывал это здесь, но вы можете просмотреть мой блог / видео, в котором рассказывается обо всем процессе. Развертывание вашей модели
Я рассмотрел развертывание модели ML в своем посте здесь. Но если вам нужен другой простой и бесплатный способ развертывания приложения Voila, вы можете использовать Binder .
Выполните следующие действия, чтобы развернуть приложение в Binder:
Добавьте свой блокнот в репозиторий GitHub.
Вставьте URL-адрес этого репозитория в поле URL-адреса Binder.
Измените раскрывающийся список "Файл", чтобы вместо этого выбрать URL-адрес.
В поле “URL для открытия” введите /voila/render/
Нажмите кнопку буфера обмена в правом нижнем углу, чтобы скопировать URL-адрес и вставить его в безопасное место.
Нажмите кнопку Запустить.
И вот, пожалуйста, ваш классификатор собак запущен!
Если вы предпочитаете наблюдать, как я выполняю все эти шаги, вот видеоверсия этого блога: