В этом примере показано, как использовать предварительно обученную сверточную нейронную сеть (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');
Как упоминалось ранее, 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 есть только несколько слоев, которые подходят для редукции данных. Слои в начале сети захватывают основные функции изображений, такие как ребра и 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, которое следует за этим.
Затем используйте функции изображений 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: Как переобучить классификатор изображений для новых категорий.
countEachLabel
| activations
(Deep Learning Toolbox) | alexnet
(Deep Learning Toolbox) | classificationLayer
(Deep Learning Toolbox) | convolution2dLayer
(Deep Learning Toolbox) | deepDreamImage
(Deep Learning Toolbox) | fullyConnectedLayer
(Deep Learning Toolbox) | imageInputLayer
(Deep Learning Toolbox) | maxPooling2dLayer
(Deep Learning Toolbox) | predict
(Deep Learning Toolbox) | reluLayer
(Deep Learning Toolbox) | confusionmat
(Statistics and Machine Learning Toolbox) | fitcecoc
(Statistics and Machine Learning Toolbox)