Третья часть Nanodegree: CNN
"Вступление"
"Нейронные сети"
Сверточные нейронные сети
Генеративные состязательные сети
Общий
В этом уроке мы узнаем о сверточных нейронных сетях, попробуем передать обучение и передать стиль, поймем важность инициализации веса, обучим автоэнкодеры и многое другое. Также будем работать над вторым проектом - Классификатор пород собак.
Сверточные нейронные сети
В этом уроке мы узнаем больше о нейронных сетях: написании MLP и их сравнении с CNN, как работает CNN, увеличении изображений и многом другом. Я пропущу этот раздел. Почему? Потому что он доступен и бесплатен для всех. Есть бесплатный курс от Udacity: Введение в нейронные сети. Урок 5 этого курса содержит этот урок, так что вы можете пройти его, если вам интересно.
Трансферное обучение
Трансферное обучение широко используется во многих задачах компьютерного зрения, например, при классификации и сегментации изображений. По сути, это работает так: кто-то обучает глубокую CNN в ImageNet или другом большом наборе данных с изображениями и делает его доступным для публичного использования. Теперь мы можем использовать эту модель с предварительно обученными весами и применять ее для наших задач на меньшем наборе данных, и качество модели обычно будет выше, чем если бы мы пытались обучить новую модель с нуля.
Трансферное обучение - видеоролик с кратким описанием трансферного обучения.
Полезные слои - дополнительная информация о слоях с предварительно натренированными весами.
Тонкая настройка - как пользоваться предварительно обученными нейронными сетями.
В зависимости от нашего набора данных есть четыре основных случая:
- Новый набор данных невелик, новые данные аналогичны исходным обучающим данным.
- Новый набор данных невелик, новые данные отличаются от исходных данных обучения.
- Новый набор данных большой, новые данные аналогичны исходным обучающим данным.
- Новый набор данных большой, новые данные отличаются от исходных данных обучения.
Новый набор данных невелик, новые данные аналогичны исходным обучающим данным.
- отрезать конец нейронной сети
- добавить новый полностью связанный слой, который соответствует количеству классов в новом наборе данных
- рандомизируйте веса нового полностью связанного слоя; заморозить все веса из предварительно обученной сети
- обучить сеть обновлению весов нового полностью связанного слоя
Поскольку новые данные меньше и похожи на исходные данные, мы можем сохранить большую часть предварительно обученной сети и обучить только недавно добавленный последний плотный слой.
Небольшой набор данных, разные данные
- отрежьте все, кроме некоторых из предварительно обученных слоев в начале сети
- добавить к оставшимся предварительно обученным слоям новый полностью связанный слой, который соответствует количеству классов в новом наборе данных
- рандомизируйте веса нового полностью связанного слоя; заморозить все веса из предварительно обученной сети
- обучить сеть обновлению весов нового полностью связанного слоя
Поскольку у нас разные данные, мы не можем использовать всю предварительно обученную сеть - ее последние слои были обучены искать разные функции, поэтому она может плохо работать с нашими данными. И если мы сохраним только несколько верхних слоев (которые распознают более общие функции), наша модель сможет изучать функции, относящиеся к нашему набору данных.
Большой набор данных, похожие данные
- удалите последний полностью связанный слой и замените его слоем, соответствующим количеству классов в новом наборе данных
- произвольно инициализировать веса в новом полностью подключенном слое
- инициализировать остальные веса с помощью предварительно натренированных весов
- переобучить всю нейронную сеть
Идея состоит в том, что мы не переобучимся, если обучим всю сеть на большом наборе данных.
Большой набор данных, разные данные
- удалите последний полностью связанный слой и замените его слоем, соответствующим количеству классов в новом наборе данных
- переобучить сеть с нуля со случайно инициализированными весами
- в качестве альтернативы, вы можете просто использовать ту же стратегию, что и в случае с «большими и похожими» данными.
Идея состоит в том, что если у нас есть другой набор данных, нам нужно будет обучать нашу собственную сеть.
Модель и классификатор VGG - практическое видео.
Замораживание веса и последний слой
Инициализация веса
Инициализация веса действительно важна. Плохие начальные веса могут сделать нейронную сеть неспособной к обучению, поэтому следует использовать хороший метод инициализации.
Постоянные веса - что было бы, если бы мы установили постоянные веса?
"Главное правило"
Нормальное распределение - инициализация веса с нормальным распределением.
Решение и инициализация по умолчанию - решение для тетради по инициализации веса. Код доступен здесь.
Автоэнкодеры
В этом уроке мы узнаем об автоэнкодерах, которые могут сжимать данные в меньшее пространство функций, а затем возвращать их в исходные размеры. Код доступен здесь: https://github.com/udacity/deep-learning-v2-pytorch/tree/master/autoencoder
Автоэнкодеры - общая информация
Самая простая форма автоэнкодеров - это линейный автоэнкодер. Мы научимся использовать in для сжатия цифр в наборе данных MNIST.
Определение и обучение автоэнкодера
Learnable Upsampling - CNN, очевидно, лучше справляются с повышающей дискретизацией, чем линейные модели.
Сверточные автоэнкодеры используют сверточные слои и лучше, чем линейные.
Повышение частоты дискретизации и шумоподавление
Снижающие шум автоэнкодеры добавляют случайный шум к входным данным, чтобы сеть лучше обобщала.
Передача стиля
Как я писал в своем первом посте в блоге из этой серии, перенос стиля позволяет вам взять одно изображение и перенести его стиль на другое изображение.
Этот урок также доступен в бесплатном курсе от Udacity: Введение в нейронные сети. Урок 6 этого курса содержит этот урок, так что вы можете пройти его, если вам интересно. Вы можете найти код здесь: https://github.com/udacity/deep-learning-v2-pytorch/tree/master/style-transfer
Проект: Классификатор пород собак
Это второй проект этого курса. В этом проекте мы попытаемся создать алгоритм, который сначала определит, содержит ли изображение человека или собаку, а затем предскажет породу собаки. Шаблон кода для этого проекта можно найти здесь: https://github.com/udacity/deep-learning-v2-pytorch/tree/master/project-dog-classification
Пойдем по шагам проекта! У нас есть два набора данных: 13233 фотографии людей и 8351 изображение собак.
Обнаружение человеческих лиц
У нас есть код для распознавания лиц с использованием OpenCV - простого каскадного классификатора на основе функций Хаара. Он работает нормально, но не очень хорошо, как вы можете видеть ниже:
Поэтому я решил использовать другой подход и использовал код из этого репозитория: https://github.com/TropComplique/mtcnn-pytorch
Он использует многозадачные каскадные сверточные сети для обнаружения лиц, и результат лучше. Но на изображениях собак было много ложных срабатываний. Полагаю, причина в том, что модель скроена с учетом человеческих лиц и ищет их, даже когда их нет.
Обнаружение собак
Сначала мы используем базовый подход: мы просто используем предварительно обученную модель VGG16, чтобы делать прогнозы. Вот хороший трюк: вы можете увидеть все 1000 классов ImageNet здесь. Ключи 151–268 описывают породы собак, поэтому, если VGG16 вернет прогноз в этом диапазоне, мы можем сказать, что собака была обнаружена. И это прекрасно работает!
Мне было интересно попробовать другие подходы и я использовал предварительно обученный ResNet-18, результаты были даже лучше:
Обучение CNN о породах собак с нуля
Следующий шаг - обучение нашей собственной модели. Сначала тренируем его с нуля (как упражнение).
Я написал свой собственный класс набора данных:
class DogsDataset(Dataset): def __init__(self, datafolder, transform = transforms.Compose([transforms.CenterCrop(32),transforms.ToTensor()])): self.datafolder = datafolder self.image_files_list = [] self.transform = transform self.labels = [] for folder in glob(datafolder + '/*'): for img in glob(folder + '/*'): self.labels.append(int(folder.split('.')[0][-3:])) self.image_files_list.append(img) def __len__(self): return len(self.image_files_list) def __getitem__(self, idx): img_name = self.image_files_list[idx] image = Image.open(img_name).convert('RGB') image = self.transform(image) label = self.labels[idx] return image, label
И многослойная CNN:
class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 16, 3, stride=2, padding=1) self.conv2 = nn.Conv2d(16, 32, 3, stride=2, padding=1) self.conv3 = nn.Conv2d(32, 64, 3) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(2304, 512) self.fc3 = nn.Linear(512, 133) self.dropout = nn.Dropout(0.1) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = self.pool(F.relu(self.conv3(x))) x = x.view(-1, 2304) x = self.dropout(x) x = F.relu(self.fc1(x)) x = self.dropout(x) x = self.fc3(x) return x
Он достиг точности теста 12% (104 изображения из 836), чего было достаточно для выполнения этой задачи.
Обучение CNN с помощью трансферного обучения
В этом разделе я снова сделал базовый план, используя ResNet-18:
model_transfer = models.resnet18(pretrained=True) for param in model_transfer.parameters(): param.requires_grad = False model_transfer.fc = nn.Linear(512, 133)
Очевидно, это сработало намного лучше, достигнув точности 74% (623/836).
Написание окончательного алгоритма
А теперь мы написали алгоритм со следующей логикой:
- если на изображении обнаружена собака, верните предполагаемую породу.
- если на изображении обнаружен человек, верните похожую породу собаки.
- если ни один не обнаружен на изображении, предоставьте вывод, указывающий на ошибку.
Вот некоторые результаты:
Алгоритм работал не очень хорошо, я полагаю, основная причина - небольшой набор данных и простая основа для модели CNN. Если бы у нас была лучшая модель и больше данных, результаты были бы лучше. Полагаю, это актуально для любого проекта глубокого обучения :)
Глубокое обучение для обнаружения рака
В этом уроке Себастьян Трун расскажет о своей новаторской работе по обнаружению рака кожи с помощью сверточных нейронных сетей.
"Вступление"
"Рак кожи"
Вероятность выживания при раке кожи
"Данные"
Обнаружить рак кожи действительно сложно:
Случайный и предварительно инициализированный вес
Чувствительность и специфичность
Сравнение наших результатов с врачами
"Визуализация"
"Заключение"
Работа в области глубокого обучения
В этом небольшом разделе мы получаем много практических идей по работе с глубоким обучением.
Как проникнуть в индустрию глубокого обучения?
Важно искать возможности и демонстрировать собственные навыки!
- будьте в курсе: читайте твиттер / СМИ и другие ресурсы;
- проведите исследование вакансий и посмотрите, какие еще навыки необходимы для достижения успеха;
- разработать собственное приложение / продукт: это докажет ваши навыки;
- прочтите последние статьи и напишите свои собственные реализации;
Развитие дополнительных навыков
Вам нужно будет овладеть многими навыками, которых нет в этой Nanodegree, вот несколько примеров:
- Изучение таких областей, как компьютерное зрение, обработка естественного языка и / или глубокое обучение с подкреплением, с помощью других программ Школы искусственного интеллекта Nanodegree или других ресурсов.
- Повышение уровня ваших навыков программирования на C ++ (полезный язык для работы с оборудованием)
- Изучение того, как создавать сети как в PyTorch, так и в TensorFlow
- Работа с SQL и применение навыков анализа данных, в частности, как вы можете очищать данные или работать с очень маленькими или большими наборами данных
Чем обычно занимаются типичные инженеры по глубокому обучению
Задачи, связанные с конкретной работой, различаются от компании к компании, но вот несколько примеров:
- Проектируйте и создавайте функции машинного интеллекта
- Разработка алгоритмов машинного обучения, связанных с глубоким обучением, таких как обнаружение объектов, языковой перевод и поиск изображений в алгоритмах поиска.
- Разверните аналитические модели в производственной среде и оцените их масштабируемость
- Код на C ++ и Python
- Используйте фреймворки машинного обучения, такие как PyTorch и Tensorflow, для реализации и прототипирования моделей глубокого обучения.
- Мониторинг и обновление модели после ее развертывания в производстве
- Используйте расширение данных для работы с небольшими наборами данных
- Сотрудничать с другими командами по обработке данных и инженерам по аппаратному обеспечению, аппаратной архитектуре программного обеспечения и обеспечению качества.
Это была вторая часть Deep Learning Nanodegree. Мы научились писать CNN и использовать их для множества задач. Следующая часть будет о рекуррентных нейронных сетях: RNN, LSTM, встраиваниях слов и многом другом!