В этом примере показано, как использовать предварительно обученную Сверточную нейронную сеть (CNN) в качестве экстрактора функции для обучения классификатор категории изображений.
Сверточная нейронная сеть (CNN) является мощным методом машинного обучения от поля глубокого обучения. CNNs обучены с помощью большого количества разнообразных изображений. От этого большого количества CNNs может изучить богатые представления функции для широкого спектра изображений. Эти представления функции часто превосходят по характеристикам изготовленные вручную функции, такие как ПОЖИРАТЕЛЬ РЕСУРСОВ, LBP или SURF. Простой способ усилить степень CNNs, не инвестируя время и усилие в обучение, состоит в том, чтобы использовать предварительно обученный CNN в качестве экстрактора функции.
В этом примере изображения от Цветочного Набора данных [5] классифицируются в категории с помощью мультикласса линейный SVM, обученный с функциями CNN, извлеченными из изображений. Этот подход, чтобы отобразить классификацию категорий следует общепринятой практике обучения стандартный использующий классификатора функции, извлеченные из изображений. Например, Классификация Категорий Изображений Используя пример Набора признаков использует функции SURF в среде набора признаков, чтобы обучить мультикласс SVM. Различие здесь - то, что вместо того, чтобы использовать функции изображений, такие как ПОЖИРАТЕЛЬ РЕСУРСОВ или SURF, функции извлечены с помощью CNN.
Примечание: Этот пример требует Deep Learning Toolbox™, Statistics and Machine Learning Toolbox™ и Модели Deep Learning Toolbox™ для Сети ResNet-50.
Используя CUDA-способный графический процессор NVIDIA™ настоятельно рекомендован для выполнения этого примера. Использование графического процессора требует Parallel Computing Toolbox™. Для получения информации о поддерживаемом вычислите возможности, смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).
Классификатор категории будет обучен на изображениях от Цветочного Набора данных [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);
Ниже, вы видите изображение в качестве примера от одной из категорий, включенных в набор данных. Отображенное изображение Марио.
% Find the first instance of an image for each category daisy = find(imds.Labels == 'daisy', 1); figure imshow(readimage(imds,daisy))
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, который имеет 1 000 категорий объектов и 1,2 миллиона учебных изображений [1]. "ResNet-50" является одной такой моделью и может загрузиться с помощью resnet50
функция от Нейронной сети 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 путями. Таким образом слой классификации имеет 1 000 классов от набора данных 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 не будет используемой для исходной задачи классификации. Это будет повторно ставившим целью, чтобы решить различную задачу классификации на Цветочном Наборе данных.
Разделите наборы в данные об обучении и валидации. Выберите 30% изображений от каждого набора для обучающих данных и остатка, 70%, для данных о валидации. Рандомизируйте разделение, чтобы не смещать результаты. Наборы обучающих данных и наборы тестов будут обработаны моделью CNN.
[trainingSet, testSet] = splitEachLabel(imds, 0.3, 'randomize');
Как отмечалось ранее, net
может только обработать изображения RGB, которые являются 224 224. Чтобы постараться не повторно сохранять все изображения в этот формат, используйте augmentedImageDatastore
изменить размер и преобразовать любые полутоновые изображения в RGB на лету. 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, которые подходят для извлечения признаков изображений. Слои в начале сетевого получения основные функции изображений, такие как ребра и блобы. Чтобы видеть это, визуализируйте сетевые веса фильтра из первого сверточного слоя. Это может помочь создать интуицию относительно того, почему функции, извлеченные из CNNs, работают так хорошо на задачи распознавания изображений. Обратите внимание на то, что визуализация функций от более глубоких весов слоя может быть сделана с помощью 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
параметр 'Учеников' функции к 'Линейному'. Это помогает ускорению обучение при работе с высоко-размерными характеристическими векторами 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] Дэн, Цзя, и др. "Imagenet: крупномасштабная иерархическая база данных изображений". Компьютерное зрение и Распознавание образов, 2009. CVPR 2009. Конференция по IEEE по. IEEE, 2009.
[2] Krizhevsky, Алекс, Илья Сутскевер и Джеффри Э. Хинтон. "Классификация Imagenet с глубокими сверточными нейронными сетями". Усовершенствования в нейронных системах обработки информации. 2012.
[3] Симонян, Карен и Эндрю Зиссермен. "Очень глубоко сверточные сети для крупномасштабного распознавания изображений". arXiv предварительно распечатывают arXiv:1409.1556 (2014).
[4] Donahue, Джефф, и др. "Кофе без кофеина: глубокая сверточная активация показывает для типового визуального распознавания". arXiv предварительно распечатывают arXiv:1310.1531 (2013).
[5] Tensorflow: как переобучить классификатор изображений для новых категорий.
alexnet
(Deep Learning Toolbox) | countEachLabel
| imageInputLayer
(Deep Learning Toolbox) | convolution2dLayer
(Deep Learning Toolbox) | reluLayer
(Deep Learning Toolbox) | maxPooling2dLayer
(Deep Learning Toolbox) | classificationLayer
(Deep Learning Toolbox) | fullyConnectedLayer
(Deep Learning Toolbox) | activations
(Deep Learning Toolbox) | predict
(Deep Learning Toolbox) | deepDreamImage
(Deep Learning Toolbox) | fitcecoc
(Statistics and Machine Learning Toolbox) | confusionmat
(Statistics and Machine Learning Toolbox)