Третья часть Nanodegree: CNN

"Вступление"

"Нейронные сети"

Сверточные нейронные сети

Рекуррентные нейронные сети

Генеративные состязательные сети

Развертывание модели

Конец путешествия

Общий

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

Сверточные нейронные сети

В этом уроке мы узнаем больше о нейронных сетях: написании MLP и их сравнении с CNN, как работает CNN, увеличении изображений и многом другом. Я пропущу этот раздел. Почему? Потому что он доступен и бесплатен для всех. Есть бесплатный курс от Udacity: Введение в нейронные сети. Урок 5 этого курса содержит этот урок, так что вы можете пройти его, если вам интересно.

Трансферное обучение

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

Трансферное обучение - видеоролик с кратким описанием трансферного обучения.

Полезные слои - дополнительная информация о слоях с предварительно натренированными весами.

Тонкая настройка - как пользоваться предварительно обученными нейронными сетями.

В зависимости от нашего набора данных есть четыре основных случая:

  1. Новый набор данных невелик, новые данные аналогичны исходным обучающим данным.
  2. Новый набор данных невелик, новые данные отличаются от исходных данных обучения.
  3. Новый набор данных большой, новые данные аналогичны исходным обучающим данным.
  4. Новый набор данных большой, новые данные отличаются от исходных данных обучения.

Новый набор данных невелик, новые данные аналогичны исходным обучающим данным.

  • отрезать конец нейронной сети
  • добавить новый полностью связанный слой, который соответствует количеству классов в новом наборе данных
  • рандомизируйте веса нового полностью связанного слоя; заморозить все веса из предварительно обученной сети
  • обучить сеть обновлению весов нового полностью связанного слоя

Поскольку новые данные меньше и похожи на исходные данные, мы можем сохранить большую часть предварительно обученной сети и обучить только недавно добавленный последний плотный слой.

Небольшой набор данных, разные данные

  • отрежьте все, кроме некоторых из предварительно обученных слоев в начале сети
  • добавить к оставшимся предварительно обученным слоям новый полностью связанный слой, который соответствует количеству классов в новом наборе данных
  • рандомизируйте веса нового полностью связанного слоя; заморозить все веса из предварительно обученной сети
  • обучить сеть обновлению весов нового полностью связанного слоя

Поскольку у нас разные данные, мы не можем использовать всю предварительно обученную сеть - ее последние слои были обучены искать разные функции, поэтому она может плохо работать с нашими данными. И если мы сохраним только несколько верхних слоев (которые распознают более общие функции), наша модель сможет изучать функции, относящиеся к нашему набору данных.

Большой набор данных, похожие данные

  • удалите последний полностью связанный слой и замените его слоем, соответствующим количеству классов в новом наборе данных
  • произвольно инициализировать веса в новом полностью подключенном слое
  • инициализировать остальные веса с помощью предварительно натренированных весов
  • переобучить всю нейронную сеть

Идея состоит в том, что мы не переобучимся, если обучим всю сеть на большом наборе данных.

Большой набор данных, разные данные

  • удалите последний полностью связанный слой и замените его слоем, соответствующим количеству классов в новом наборе данных
  • переобучить сеть с нуля со случайно инициализированными весами
  • в качестве альтернативы, вы можете просто использовать ту же стратегию, что и в случае с «большими и похожими» данными.

Идея состоит в том, что если у нас есть другой набор данных, нам нужно будет обучать нашу собственную сеть.

Модель и классификатор 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. Если бы у нас была лучшая модель и больше данных, результаты были бы лучше. Полагаю, это актуально для любого проекта глубокого обучения :)

Глубокое обучение для обнаружения рака

В этом уроке Себастьян Трун расскажет о своей новаторской работе по обнаружению рака кожи с помощью сверточных нейронных сетей.

"Вступление"

"Рак кожи"

Вероятность выживания при раке кожи

Медицинская классификация

"Данные"

Проблемы с имиджем

Обнаружить рак кожи действительно сложно:

Обучение нейронной сети

Случайный и предварительно инициализированный вес

Проверка обучения

Чувствительность и специфичность

Диагностика рака

Обновить кривые ROC

Кривая ROC

Сравнение наших результатов с врачами

"Визуализация"

На что смотрит сеть?

Обновите матрицу неточностей

Матрица путаницы

"Заключение"

Работа в области глубокого обучения

В этом небольшом разделе мы получаем много практических идей по работе с глубоким обучением.

Как проникнуть в индустрию глубокого обучения?

Важно искать возможности и демонстрировать собственные навыки!

  • будьте в курсе: читайте твиттер / СМИ и другие ресурсы;
  • проведите исследование вакансий и посмотрите, какие еще навыки необходимы для достижения успеха;
  • разработать собственное приложение / продукт: это докажет ваши навыки;
  • прочтите последние статьи и напишите свои собственные реализации;

Развитие дополнительных навыков

Вам нужно будет овладеть многими навыками, которых нет в этой Nanodegree, вот несколько примеров:

  • Изучение таких областей, как компьютерное зрение, обработка естественного языка и / или глубокое обучение с подкреплением, с помощью других программ Школы искусственного интеллекта Nanodegree или других ресурсов.
  • Повышение уровня ваших навыков программирования на C ++ (полезный язык для работы с оборудованием)
  • Изучение того, как создавать сети как в PyTorch, так и в TensorFlow
  • Работа с SQL и применение навыков анализа данных, в частности, как вы можете очищать данные или работать с очень маленькими или большими наборами данных

Чем обычно занимаются типичные инженеры по глубокому обучению

Задачи, связанные с конкретной работой, различаются от компании к компании, но вот несколько примеров:

  • Проектируйте и создавайте функции машинного интеллекта
  • Разработка алгоритмов машинного обучения, связанных с глубоким обучением, таких как обнаружение объектов, языковой перевод и поиск изображений в алгоритмах поиска.
  • Разверните аналитические модели в производственной среде и оцените их масштабируемость
  • Код на C ++ и Python
  • Используйте фреймворки машинного обучения, такие как PyTorch и Tensorflow, для реализации и прототипирования моделей глубокого обучения.
  • Мониторинг и обновление модели после ее развертывания в производстве
  • Используйте расширение данных для работы с небольшими наборами данных
  • Сотрудничать с другими командами по обработке данных и инженерам по аппаратному обеспечению, аппаратной архитектуре программного обеспечения и обеспечению качества.

Это была вторая часть Deep Learning Nanodegree. Мы научились писать CNN и использовать их для множества задач. Следующая часть будет о рекуррентных нейронных сетях: RNN, LSTM, встраиваниях слов и многом другом!