Классификация категорий изображений с использованием глубокого обучения

В этом примере показано, как использовать предварительно обученную сверточную нейронную сеть (CNN) в качестве экстрактора функций для настройки классификатора категорий изображений.

Обзор

Сверточная нейронная сеть (CNN) - мощный метод машинного обучения из области глубокого обучения. CNN обучаются с использованием больших наборов разнообразных изображений. Из этих больших наборов CNN могут узнать богатые представления функций для широкой области значений изображений. Эти представления признаков часто превосходят ручные функции, такие как HOG, LBP или SURF. Легкий способ использовать степени CNN, не вкладывая время и усилия в обучение, - использовать предварительно обученный CNN в качестве экстрактора функций.

В этом примере изображения из набора данных Flowers [5] классифицируются по категориям с помощью многоклассового линейного SVM, обученного функциям CNN, извлеченным из изображений. Этот подход к классификации категорий изображений следует стандартной практике обучения готового классификатора с использованием функций, извлеченных из изображений. Например, пример «Классификация категорий изображений с использованием сумки признаков» использует функции SURF в среде набора признаков для обучения многоклассового SVM. Здесь различие, что вместо использования таких функций изображений, как HOG или SURF, функции извлекаются с помощью CNN .

Примечание. Этот пример требует Toolbox™ глубокого обучения, Statistics and Machine Learning Toolbox™ и модели Deep Learning Toolbox™ для ResNet-50 сети.

Для выполнения этого примера настоятельно рекомендуется использовать NVIDIA™ графический процессор с поддержкой CUDA. Для использования графический процессор требуется Toolbox™ Parallel Computing. Для получения информации о поддерживаемых вычислительных возможностях смотрите Поддержку GPU by Release (Parallel Computing Toolbox).

Загрузка данных

Классификатор категорий будет обучен на изображениях из набора данных Flowers [5].

% Location of the compressed data set
url = 'http://download.tensorflow.org/example_images/flower_photos.tgz';

% Store the output in a temporary folder
downloadFolder = tempdir;
filename = fullfile(downloadFolder,'flower_dataset.tgz');

Примечание: Время загрузки данных зависит от вашего подключения к Интернету. Следующий набор команд использует MATLAB для загрузки данных и будет блокировать MATLAB. Также можно использовать веб-браузер для первой загрузки набора данных на локальный диск. Чтобы использовать файл, загруженный из Интернета, измените переменную 'outputFolder' выше на местоположение загруженного файла.

% Uncompressed data set
imageFolder = fullfile(downloadFolder,'flower_photos');

if ~exist(imageFolder,'dir') % download only once
    disp('Downloading Flower Dataset (218 MB)...');
    websave(filename,url);
    untar(filename,downloadFolder)
end

Загрузка изображений

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

imds = imageDatastore(imageFolder, 'LabelSource', 'foldernames', 'IncludeSubfolders',true);

Ниже можно увидеть пример изображения из одной из категорий, включенных в набор данных. Отображаемое изображение - от Mario.

% Find the first instance of an image for each category
daisy = find(imds.Labels == 'daisy', 1);

figure
imshow(readimage(imds,daisy))

The imds теперь переменная содержит изображения и метки категорий, сопоставленные с каждым изображением. Метки автоматически присваиваются из имен папок файлов изображений. Использование countEachLabel для суммирования количества изображений по категориям.

tbl = countEachLabel(imds)
tbl=5×2 table
      Label       Count
    __________    _____

    daisy          633 
    dandelion      898 
    roses          641 
    sunflowers     699 
    tulips         799 

Потому что imds выше содержится неравное количество изображений в категории, сначала отрегулируем, так что количество изображений в набор обучающих данных сбалансировано.

% Determine the smallest amount of images in a category
minSetCount = min(tbl{:,2}); 

% Limit the number of images to reduce the time it takes
% run this example.
maxNumImages = 100;
minSetCount = min(maxNumImages,minSetCount);

% Use splitEachLabel method to trim the set.
imds = splitEachLabel(imds, minSetCount, 'randomize');

% Notice that each set now has exactly the same number of images.
countEachLabel(imds)
ans=5×2 table
      Label       Count
    __________    _____

    daisy          100 
    dandelion      100 
    roses          100 
    sunflowers     100 
    tulips         100 

Загрузка предварительно обученной сети

Существует несколько предварительно обученных сетей, которые завоевали популярность. Большинство из них были обучены на наборе данных ImageNet, который имеет 1000 категорий объектов и 1,2 миллиона обучающих изображений [1]. «ResNet-50» является одной из таких моделей и может быть загружена с помощью resnet50 функция от Neural Network Toolbox™. Использование resnet50 требует, чтобы вы сначала установили resnet50 (Deep Learning Toolbox).

% Load pretrained network
net = resnet50();

Другие популярные сети, обученные на ImageNet, включают AlexNet, GoogLeNet, VGG-16 и VGG-19 [3], которые можно загрузить с помощью alexnet, googlenet, vgg16, и vgg19 из Deep Learning Toolbox™.

Использование plot для визуализации сети. Поскольку это большая сеть, настройте окно отображения, чтобы показать только первый раздел.

% Visualize the first section of the network. 
figure
plot(net)
title('First section of ResNet-50')
set(gca,'YLim',[150 170]);

Первый слой определяет входные размерности. Каждый CNN имеет различные требования к размеру входа. Используемый в этом примере требует входа изображения, которое 224 224 3.

% Inspect the first layer
net.Layers(1)
ans = 
  ImageInputLayer with properties:

                      Name: 'input_1'
                 InputSize: [224 224 3]

   Hyperparameters
          DataAugmentation: 'none'
             Normalization: 'zerocenter'
    NormalizationDimension: 'auto'
                      Mean: [224×224×3 single]

Промежуточные слои составляют основную часть CNN. Это серия сверточных слоев, перемежающихся с выпрямленными линейными модулями (ReLU) и слоями максимального объединения [2]. Следом за этими слоями идут 3 полносвязные слои.

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

% Inspect the last layer
net.Layers(end)
ans = 
  ClassificationOutputLayer with properties:

            Name: 'ClassificationLayer_fc1000'
         Classes: [1000×1 categorical]
      OutputSize: 1000

   Hyperparameters
    LossFunction: 'crossentropyex'

% Number of class names for ImageNet classification task
numel(net.Layers(end).ClassNames)
ans = 1000

Обратите внимание, что модель CNN не будет использоваться для исходной задачи классификации. Он будет повторно предназначен для решения другой задачи классификации на наборе данных Flowers.

Подготовка наборов обучающих и тестовых изображений

Разделите наборы на обучающие и валидационные данные. Выберите 30% изображений из каждого набора для обучающих данных и оставшиеся 70% для данных валидации. Рандомизируйте разделение, чтобы избежать смещения результатов. Обучающие и тестовые наборы будут обработаны моделью CNN.

[trainingSet, testSet] = splitEachLabel(imds, 0.3, 'randomize');

Предпроцессные изображения для CNN

Как упоминалось ранее, net можно обработать только изображения RGB 224 на 224. Чтобы избежать повторного сохранения всех изображений в этот формат, используйте augmentedImageDatastore для изменения размера и преобразования любых полутоновых изображений в RGB на лету. The augmentedImageDatastore может использоваться для дополнительного увеличения количества данных, а также при использовании для сетевого обучения.

% Create augmentedImageDatastore from training and test sets to resize
% images in imds to the size required by the network.
imageSize = net.Layers(1).InputSize;
augmentedTrainingSet = augmentedImageDatastore(imageSize, trainingSet, 'ColorPreprocessing', 'gray2rgb');
augmentedTestSet = augmentedImageDatastore(imageSize, testSet, 'ColorPreprocessing', 'gray2rgb');

Извлечение обучающих функций с помощью CNN

Каждый слой CNN создает ответ или активацию на вход изображение. Однако в CNN есть только несколько слоев, которые подходят для редукции данных. Слои в начале сети захватывают основные функции изображений, такие как ребра и blobs. Чтобы увидеть это, визуализируйте веса сетевого фильтра с первого сверточного слоя. Это может помочь создать интуицию относительно того, почему извлеченные из CNN функции так хорошо работают для задач распознавания изображений. Обратите внимание, что визуализация функций из более глубоких весов слоев может быть выполнена с помощью deepDreamImage из Deep Learning Toolbox™.

% Get the network weights for the second convolutional layer
w1 = net.Layers(2).Weights;

% Scale and resize the weights for visualization
w1 = mat2gray(w1);
w1 = imresize(w1,5); 

% Display a montage of network weights. There are 96 individual sets of
% weights in the first layer.
figure
montage(w1)
title('First convolutional layer weights')

Заметьте, что первый слой сети изучил фильтры для захвата функций больших двоичных объектов и ребер. Эти «примитивные» признаки затем обрабатываются более глубокими слоями сети, которые комбинируют ранние функции, чтобы сформировать более высокие характеристики изображения. Эти функции более высокого уровня лучше подходят для задач распознавания, потому что они объединяют все примитивные функции в более богатое представление изображений [4].

Можно легко извлечь функции из одного из более глубоких слоев, используя activations способ. Выбор глубоких слоев для выбора является выбором для проекта, но обычно, начиная со слоя непосредственно перед классификационным слоем, это хорошее место для начала. В net, этот слой имеет имя 'fc1000'. Давайте извлекем обучающие функции с помощью этого слоя.

featureLayer = 'fc1000';
trainingFeatures = activations(net, augmentedTrainingSet, featureLayer, ...
    'MiniBatchSize', 32, 'OutputAs', 'columns');

Обратите внимание, что функция активации автоматически использует графический процессор для обработки, если он доступен, в противном случае используется центральный процессор.

В коде выше, 'MiniBatchSize' установлен 32, чтобы убедиться, что данные CNN и изображения помещаются в память графический процессор. Вы, возможно, должны будете опустить 'MiniBatchSize', если у вашего графического процессора закончится память. Кроме того, выход активаций выполнен в виде столбцов. Это помогает ускорить многоклассовое линейное обучение SVM, которое следует за этим.

Обучите многоклассовый классификатор SVM с использованием функций CNN

Затем используйте функции изображений CNN для обучения многоклассового классификатора SVM. Быстрый решатель градиентного спуска Стохастика используется для обучения путем установки fitcecoc параметр функции 'Learners' к 'Linear'. Это помогает ускорить обучение при работе с высокомерными векторами функций CNN.

% Get training labels from the trainingSet
trainingLabels = trainingSet.Labels;

% Train multiclass SVM classifier using a fast linear solver, and set
% 'ObservationsIn' to 'columns' to match the arrangement used for training
% features.
classifier = fitcecoc(trainingFeatures, trainingLabels, ...
    'Learners', 'Linear', 'Coding', 'onevsall', 'ObservationsIn', 'columns');

Оценка классификатора

Повторите процедуру, используемую ранее для извлечения функций изображения из testSet. Затем тестовые функции могут быть переданы классификатору для измерения точности обученного классификатора.

% Extract test features using the CNN
testFeatures = activations(net, augmentedTestSet, featureLayer, ...
    'MiniBatchSize', 32, 'OutputAs', 'columns');

% Pass CNN image features to trained classifier
predictedLabels = predict(classifier, testFeatures, 'ObservationsIn', 'columns');

% Get the known labels
testLabels = testSet.Labels;

% Tabulate the results using a confusion matrix.
confMat = confusionmat(testLabels, predictedLabels);

% Convert confusion matrix into percentage form
confMat = bsxfun(@rdivide,confMat,sum(confMat,2))
confMat = 5×5

    0.8571    0.0286    0.0286    0.0714    0.0143
    0.0571    0.8286         0    0.0571    0.0571
    0.0143         0    0.7714    0.0714    0.1429
    0.0286    0.0571    0.0571    0.8000    0.0571
         0         0    0.2000    0.0286    0.7714

% Display the mean accuracy
mean(diag(confMat))
ans = 0.8057

Примените обученный классификатор к одному тестовому изображению

Примените обученный классификатор для классификации новых изображений. Прочтите одно из «ромашечных» тестовых изображений.

testImage = readimage(testSet,1);
testLabel = testSet.Labels(1)
testLabel = categorical
     daisy 

Извлечение функций помощью CNN.

% Create augmentedImageDatastore to automatically resize the image when
% image features are extracted using activations.
ds = augmentedImageDatastore(imageSize, testImage, 'ColorPreprocessing', 'gray2rgb');

% Extract image features using the CNN
imageFeatures = activations(net, ds, featureLayer, 'OutputAs', 'columns');

Сделайте предсказание с помощью классификатора.

% Make a prediction using the classifier
predictedLabel = predict(classifier, imageFeatures, 'ObservationsIn', 'columns')
predictedLabel = categorical
     daisy 

Ссылки

[1] Deng, Jia, et al. Imagenet: крупномасштабная иерархическая база данных изображений. Компьютерное зрение and Pattern Recognition, 2009. CVPR 2009. Конференция IEEE по. IEEE, 2009.

[2] Крижевский, Алекс, Илья Суцкевер, и Джеффри Э. Хинтон. «Классификация Imagenet с глубокими сверточными нейронными сетями». Усовершенствования в системах нейронной обработки информации. 2012.

[3] Симоньян, Карен и Эндрю Зиссерман. «Очень глубокие сверточные сети для крупномасштабного распознавания изображений». arXiv preprint arXiv:1409.1556 (2014).

[4] Donahue, Jeff, et al. Decaf: Глубокая сверточная функция активации для общего визуального распознавания. arXiv preprint arXiv:1310.1531 (2013).

[5] Tensorflow: Как переобучить классификатор изображений для новых категорий.

См. также

| (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Statistics and Machine Learning Toolbox) | (Statistics and Machine Learning Toolbox)

Похожие темы